Compare commits

...
381 Commits
Author SHA1 Message Date
pixelmaxQM 85681af8b8 feat: 默认注册表增加 info表和图库分类表 2025-03-16 12:09:14 +08:00
Qing Liang 4b12ecdf4b bugfix:mongodb没有密码无法连接 (#1999) 2025-03-16 12:00:22 +08:00
pixelmaxQM e8eacb02d6 feat: 未登录情况下防止进入路由死循环 2025-03-16 11:53:44 +08:00
pixelmaxQM e9dd55f4f9 feat: 修复未登录情况下死循环的bug 2025-03-15 16:42:36 +08:00
pixelmaxQM a79df727c9 feat: 给扫码上传添加客户端标记 2025-03-15 14:06:17 +08:00
pixelmaxQM ca47b1c4f5 feat: 在登录状态下进入白名单页面强制拉取到当前角色的默认页面 2025-03-15 14:05:58 +08:00
ab75bc7f59 public: 发布2.8.0版本 (#1998)
* feat:修改token获取优先级,优先从header获取

* feat: 增加业务ctx的传递

* fix文件选择问题,
有公共函数onDownloadFile,去掉downloadFile

* 没问题

* feat: 增加context引入

* fix: 修复图片多选的情况下点击确定抽屉无法收起的bug

* feat: 提高header的token优先级,优化导出表格逻辑,不再依赖于cookie鉴权

---------

Co-authored-by: piexlMax(奇淼 <qimiaojiangjizhao@gmail.com>
Co-authored-by: task <121913992@qq.com>
2025-03-15 13:31:33 +08:00
PiexlMax(奇淼 f776a061ce Update README.md 2025-03-13 11:05:33 +08:00
krank 1456f95b2c Update README.md 2025-03-08 13:34:23 +08:00
krank c5767f6ad5 Update README.md 2025-03-08 13:32:41 +08:00
haimait 3f8dedba80 fix: 修改导入excel模板数据注释 (#1995) 2025-03-05 10:15:49 +08:00
pixelmaxQM 121d62f20f fix: 修复图片多选的情况下点击确定抽屉无法收起的bug 2025-03-03 20:05:48 +08:00
pixelmaxQM 2c08265210 fix: 修复个人样式配置情况下false无法生效的问题 2025-02-25 20:43:58 +08:00
PiexlMax(奇淼 82e397f136 fix:修复mssql中getDB失败的bug 2025-02-20 15:29:46 +08:00
taskandtask 730ee0205e 媒体库增加裁剪上传,扫码上传 (#1994)
Co-authored-by: task <121913992@qq.com>
2025-02-19 18:08:31 +08:00
pixelmaxQM a4716d5db0 fix: 修复iframe url传入不识别的bug 2025-02-16 12:28:34 +08:00
pixelmaxQM 06f166b70a feat: 发布2.7.9版本 2025-02-16 11:52:41 +08:00
pixelmaxQM f2ea36ac0d feat: 调整初始化数据 2025-02-15 16:58:33 +08:00
piexlMax(奇淼 a8e706a395 feat: 调整自动化代码富文本模式下的可选查询条件 2025-02-13 16:20:52 +08:00
bypanghu f608bfa191 fix:设置添加页面切换动画 2025-02-13 15:39:09 +08:00
piexlMax(奇淼 e494e22c07 feat: 调整版本为v2.7.9-beta 2025-02-13 15:33:01 +08:00
d40c815760 2.7.9beta (#1993)
* 媒体库增加分类,图库多选择时优化。

* 重构 JWT token 生成,使用 `New()` 函数代替直接创建实例

* 上传组件支持查看大图 (#1982)

* 将参数缓存,媒体库增加分类,图库多选择时优化。 (#1978)

* 媒体库增加分类,图库多选择时优化。

*修复文件上传进度显示bug&按钮样式优化 (#1986)

* fix:添加内部 iframe 展示网页,优化 permission 代码

* 俩个uuid库合并一个,更新库到当前版本。

* 优化关于我们界面

* feat: 个人中心头像调整,媒体库兼容性调整。

* feat: 自动化代码前端页面美化,多余按钮收入专家模式

* feat: 增加单独生成server功能

* feat: 限制单独生成前后端的情况下的细节配置

* feat: 修复全选失败报错的问题

---------

Co-authored-by: task <121913992@qq.com>
Co-authored-by: Feng.YJ <32027253+huiyifyj@users.noreply.github.com>
Co-authored-by: will0523 <dygsunshine@163.com>
Co-authored-by: task <ms.yangdan@gmail.com>
Co-authored-by: sslee <57312216+GIS142857@users.noreply.github.com>
Co-authored-by: bypanghu <bypanghu@163.com>
Co-authored-by: Azir <2075125282@qq.com>
Co-authored-by: piexlMax(奇淼 <qimiaojiangjizhao@gmail.com>
Co-authored-by: krank <emosick@qq.com>
2025-02-13 15:25:10 +08:00
PiexlMax(奇淼 ea39d83907 Update README.md 2025-02-10 16:44:35 +08:00
pixelmaxQM dae38d9b18 fix:菜单复合模式下,点击一级菜单会自动选择首位子菜单,不含子菜单则定位为顶栏本体。 2025-02-09 19:56:51 +08:00
药要吃 831bd61e02 更新个人信息页样式 这个头 得开 (#1977)
* 更新个人信息页样式
2025-01-09 17:14:39 +08:00
pixelmaxQM fe2b846dbc feat: 提交发布2.7.8版本 2025-01-01 14:49:27 +08:00
pixelmaxQM 8c47d2b179 feat: 提交发布2.7.8版本 2025-01-01 14:49:27 +08:00
Leslie afe6b234cf fixed: 修复递归获取角色列表数据缺失问题 (#1974) 2024-12-31 11:38:04 +08:00
piexlMax(奇淼 1743c763d2 feat: gorm的debug日志无论是否开启了zap都需要输出到控制台 2024-12-31 10:51:33 +08:00
Feng.YJ 21237f8be1 模板文件文档注释修改 (#1973)
* 模板文件文档注释修改

* 补充模板相关修改
2024-12-30 17:08:17 +08:00
piexlMax(奇淼 d19e446416 fixed: 修复无法创建新内容的bug 2024-12-26 15:16:58 +08:00
piexlMax(奇淼 8b93ede959 fixed: 修复sql日志无法加入统一zap输出的bug 2024-12-25 13:51:02 +08:00
PiexlMax(奇淼 cb23254152 给自动化代码增加视觉功能 (#1970)
* update:增加视觉能力。

* feat: 自动化代码增加视觉识别功能
2024-12-22 00:14:03 +08:00
Feng.YJ 601aa6e245 代码优化及错误返回改进 (#1969)
* Makefile: 使用 '?=' 替代 if-else 的判断

* 移除多余的类型转换

* 移除多余的nil判断

* map 使用简化以及错误处理优化
2024-12-22 00:13:22 +08:00
Feng.YJ 532d282509 修复生成的结构体 tag 字段错误以及其它注释和尾部空格问题 (#1968)
* 修复生成的结构体 tag 字段错误

* 移除字段注释多余尾部空格

* 文件模板注释 `@accept` 保持规范
2024-12-20 16:50:45 +08:00
Feng.YJ 93c0525ea5 生成模板中注释文档 query 修改 (#1967)
* 生成模板中注释文档 query 修改
2024-12-19 17:21:22 +08:00
Feng.YJ 2bf423b42f 修复可能的 context 泄露以及遗漏的错误处理 (#1965)
* 修复结构体 tag 字段的错误使用
2024-12-17 16:59:06 +08:00
Brandon-lz f6c2ce45c1 修复限流不返回报错信息的bug (#1966) 2024-12-17 16:57:28 +08:00
Feng.YJ d24eeefc86 添加 swagger 文档接口排序的 @Tag 设置说明 (#1964)
* fix: 修复欢迎信息中的 tab 缩进格式

* 添加 swagger 文档生成

* 添加 swagger 文档接口排序的 `@Tag` 设置说明
2024-12-16 14:25:38 +08:00
pixelmaxQM 876d4187d9 fixed: 过滤条件添加富文本 2024-12-15 13:34:14 +08:00
pixelmaxQM 2412e7151f fixed: 修复富文本组件 查看详情没有正确展示的bug 2024-12-15 13:31:33 +08:00
Isaacedvr1003andzsc 07c21caf8d fixed:修复表名是大写字母开头时,自动化代码异常问题。 (#1961)
Co-authored-by: zsc <zhangshuncheng@dhcc.com.cn>
2024-12-13 17:51:00 +08:00
青菜白玉汤 69ddb2ddff fix: 修复自动化代码管理侧边栏自动展开的问题 (#1959) 2024-12-11 17:51:10 +08:00
283143e1bf 发布v2.7.8Beta1 (#1957)
* beta:2.7.8-a 增加自动化创建树形结构 (#1941)

* feat: 支持创建树形结构

---------

Co-authored-by: piexlMax(奇淼 <qimiaojiangjizhao@gmail.com>

* 优化user store部分写法

* Update user.js

* feat: 升级版本号

* Dev 278 beta2 (#1954)

* 在关闭详情弹窗后 detailFrom为空对象,arr为undefined 使用slice控制台会报错

* 查询不重置pageSize

* 优化主题模式相关内容

* 优化弹窗手机端显示

* bugfix:PostgreSQL initdb (#1953)

* bugfix:postgresql增加显示指定template

---------

Co-authored-by: PiexlMax(奇淼 <165128580+pixelmaxQm@users.noreply.github.com>

---------

Co-authored-by: zayn <972858472@qq.com>
Co-authored-by: Azir <2075125282@qq.com>
Co-authored-by: Qing Liang <106448173+xue-ding-e@users.noreply.github.com>

* docs:调整部分代码注释以及代码格式

* feat: 自动化代码字典支持多选

* fix:调整值接收器和指针接收器

* feat: 支持导出表格复制,优化增加方法页面。

* chore:初始化代码规范化。

---------

Co-authored-by: piexlMax(奇淼 <qimiaojiangjizhao@gmail.com>
Co-authored-by: Azir <2075125282@qq.com>
Co-authored-by: zayn <972858472@qq.com>
Co-authored-by: Qing Liang <106448173+xue-ding-e@users.noreply.github.com>
Co-authored-by: cjb <75364055@qq.com>
2024-12-08 21:17:21 +08:00
PiexlMax(奇淼 80c54ad890 Merge pull request #1946 from neo-6/neo-6-patch-1
解决Invalid vnode type when creating vnode的警告问题
2024-12-04 20:29:35 +08:00
天梦 3272f3c8cc 修复长度验证中数字验证 2024-12-02 18:47:28 +08:00
天梦 6bfbfc4762 解决传参时提示错误警告 2024-12-02 18:29:44 +08:00
天梦 8d2735f6e9 解决Invalid vnode type when creating vnode的警告问题 2024-12-02 15:59:25 +08:00
ipanghu d72984be7e 修复 dockerfile 添加缓存层 (#1943) 2024-11-25 15:41:08 +08:00
pixelmaxQM 39212666c5 feat: 修复导出在baseApi配置为/时候的路径拼接错误 2024-11-21 20:00:27 +08:00
PiexlMax(奇淼 c909d32c56 fix: 无法自动化新增字段的bug 2024-11-19 16:31:43 +08:00
zayn 8073e989f5 查询不重置pageSize (#1940)
* 查询不重置pageSize
2024-11-18 18:07:38 +08:00
pixelmaxQM 4671013ea6 fix: 自动化代码回滚后不可复用的bug 2024-11-17 11:59:09 +08:00
task b954457ae4 Update date.js (#1937)
替换被弃用的RegExp.$1、substr
2024-11-16 13:24:19 +08:00
zayn f7889b9709 Update format.js (#1935)
在关闭详情弹窗后 detailFrom为空对象,arr为undefined 使用slice控制台会报错
2024-11-15 10:38:53 +08:00
pixelmaxQM a9894acd51 feat: 允许清除关联关系 2024-11-14 23:16:10 +08:00
Mr·Zhaoandadmin 51e1c62ee6 web/src/view/superAdmin/menu/icon.vue: 后台菜单管理中选择图标时增加可选自定义图标 (#1933)
Co-authored-by: admin <admin@example.com>
2024-11-12 22:52:30 +08:00
pixelmaxQM fbd0f4b9c6 fix: 自动化代码需检测简称,简称不可以重复。 2024-11-11 22:40:41 +08:00
PiexlMax(奇淼 58204373aa Update README.md 2024-11-10 23:35:30 +08:00
pixelmaxQM 710257da65 delete: 删除开发模式docker-compose环境 2024-11-10 22:37:18 +08:00
青菜白玉汤 f63803529a perf(projects): 增强文件校验的兼容性 (#1931) 2024-11-10 17:02:31 +08:00
piexlMax(奇淼 7d9af64f6d feat: 使用prettierrc对代码进行格式化 2024-11-09 10:32:26 +08:00
piexlMax(奇淼 87a4ce17e1 feat: 根据eslint 对项目进行规范化处理 2024-11-09 10:17:57 +08:00
Raindrop-YL fae6f413a5 fix: 适配 eslint v9 更新, 兼容低版本 node (#1930)
* fix: eslint v9 版本配置文件更新
2024-11-09 09:48:21 +08:00
piexlMax(奇淼 d8e36ab0f8 feat: 新增方法默认窗口关闭 2024-11-09 09:45:56 +08:00
piexlMax(奇淼 35fd5c8d65 feat: 更新dockerfile的node版本 2024-11-08 16:17:52 +08:00
PiexlMax(奇淼 5604424e6f Merge pull request #1924 from zayn-code/main
表单提交按钮增添loading,防连点
2024-11-08 13:54:23 +08:00
pixelmaxQM c4c5f01ee5 feat: 增加包ace-builds 2024-11-07 21:47:24 +08:00
pixelmaxQM e6d203d567 fix: AI生成代码强制处理首字母大写,提高容错 2024-11-07 20:15:09 +08:00
piexlMax(奇淼 e75fa0bd84 feat: 更换代码编辑器,增加不同node的兼容性。 2024-11-07 18:33:33 +08:00
piexlMax(奇淼 b2cfbb95b6 fix: 在导出表格之前取消掉用户自行添加的""和`` 2024-11-06 11:19:17 +08:00
zayn 0d84ea9523 Update form.vue.tpl
表单提交的时候按钮添加loading状态,防止手滑连点后重复创建
2024-11-04 19:39:52 -08:00
zayn e99fe70164 Update table.vue.tpl
表单提交的时候按钮添加loading状态,防止手滑连点后重复创建
2024-11-04 19:28:24 -08:00
pixelmaxQM 8bd337e08f fix: 字符串情况下搜索条件为空不再参与搜索筛选 2024-11-03 22:09:02 +08:00
pixelmaxQM 12124eb1aa feat: 完善自动化代码填充方法逻辑,增加成功率 2024-11-03 13:15:52 +08:00
pixelmaxQM e036395d18 fix: #1918 在包含delete_at的情况下,数据源自动过滤软删除数据 2024-10-31 20:24:18 +08:00
pixelmaxQM 41ba7ad6a5 fix: #1918 在包含delete_at的情况下,数据源自动过滤软删除数据 2024-10-31 20:10:06 +08:00
pixelmaxQM 3452eafe4f feat: 模板配置将自动同步本地有的模板和插件 2024-10-30 20:41:10 +08:00
pixelmaxQM e515ad3074 feat: UI细节优化 2024-10-30 20:32:39 +08:00
pixelmaxQM 255f138bdb feat: 模板配置可以读取系统原生携带的文件模板 2024-10-30 20:32:04 +08:00
PiexlMax(奇淼 08496c2c61 Merge pull request #1922 from cangqiaoyuzhuo/main
chore: fix function name in comment
2024-10-30 10:07:40 +08:00
piexlMax(奇淼 25a996fe51 fix: 新增字段在没有选择gvaModel的情况下,防止出现空指针 2024-10-30 09:48:40 +08:00
piexlMax(奇淼 9ba39f2eda fix: 新增字段在没有选择gvaModel的情况下,防止出现空指针 2024-10-30 09:46:38 +08:00
piexlMax(奇淼 4a70b38a99 fix: 修复关联模式下的sql语句bug 2024-10-30 09:42:37 +08:00
pixelmaxQM 0dc66adc0d feat: 参数管理功能示例代码动态化 2024-10-29 22:18:13 +08:00
bypanghu c2c11b29a7 fix:修复运行时 saas 报错 2024-10-29 22:08:17 +08:00
pixelmaxQM 071f48c3ca feat: 表格模板更名为导出模板 2024-10-29 22:05:03 +08:00
pixelmaxQM 65cef0b40f feat: 导入导出功能将可以直接看到代码模板。 2024-10-29 21:56:30 +08:00
pixelmaxQM f30912e02f fix: 不再自动对导出key进行处理,如遇到关键字需要使用对应数据库的字符串表达式包裹 2024-10-29 20:46:31 +08:00
cangqiaoyuzhuo 1b74dc8afd chore: fix function name in comment 2024-10-28 22:24:45 +08:00
pixelmaxQM 1840b343b2 feat: 自动化代码不允许创建与模板同名的的字段JSON。 2024-10-28 22:05:24 +08:00
pixelmaxQM 4f8030ecae fix: 修复LIKE查询下的模板bug
fix: 在模板模式下对AI进行disabled
2024-10-28 21:39:40 +08:00
PiexlMax(奇淼 bb6c0be9de Merge pull request #1921 from flipped-aurora/dev2.7.7
beta:2.7.7 AI版本发布
2024-10-27 10:36:40 +08:00
pixel(奇淼 a2d4c43047 feat: 插件模板搜索功能按照数组提供索引条件 2024-10-27 10:35:43 +08:00
pixel(奇淼 60184f12bd feat: 菜单主菜单css样式调整 2024-10-27 10:26:35 +08:00
pixel(奇淼 4ffa30e31a feat: 增加AI生成之前的确认行为 2024-10-27 10:21:48 +08:00
pixel(奇淼 7fff2833c3 feat: ai生成页面功能屏蔽 2024-10-26 12:37:27 +08:00
pixel(奇淼 d1da92d040 Merge branch 'main' into dev2.7.7
# Conflicts:
#	web/src/pathInfo.json
#	web/vitePlugin/componentName/index.js
2024-10-26 12:30:41 +08:00
pixel(奇淼 6bb8f8a030 fix: 修复空菜单无法切换为手动输入的bug,修复没有vueName无法读取到pathinfo.json中的bug 2024-10-26 12:17:54 +08:00
pixelmaxQM dcd0eb20e1 feat: 调整自动引入组件,新增html展示页面。 2024-10-25 22:19:13 +08:00
pixelMax(奇淼 7d6270079a feat: 增加ai绘制页面功能 2024-10-25 18:22:11 +08:00
pixelMax(奇淼 05242c0ad7 feat: 完善AI帮写内容 2024-10-25 10:35:14 +08:00
pixelMax(奇淼 30fb3a97d7 feat: 增加方法可以根据方法介绍自动补全 2024-10-25 10:22:09 +08:00
pixelMax(奇淼 4dec8cfb17 Merge branch 'dev2.7.7' of github.com:flipped-aurora/gin-vue-admin into dev2.7.7 2024-10-25 09:47:36 +08:00
pixelmaxQM bb8210b88e feat: autoFunc可以ai添加代码。 2024-10-24 22:55:15 +08:00
pixelMax(奇淼 b69858b6f7 feat: AddFunc在ai生成后支持页面编辑 2024-10-24 18:44:07 +08:00
pixelMax(奇淼 f191601ab4 feat: 增加AddFunc自动填充方法逻辑功能 2024-10-24 18:01:40 +08:00
PiexlMax(奇淼 7d62a55a92 Merge pull request #1917 from Brandon-lz/dev2.7.7
Dev2.7.7 新增支持minio分片上传大文件
2024-10-23 11:22:17 +08:00
Brandon lz eadcda4e30 modified: server/go.mod
modified:   server/go.sum
2024-10-22 07:05:18 +00:00
Brandon lz 45382d1446 支持大文件分片上传minio 2024-10-22 07:00:51 +00:00
PiexlMax(奇淼 0fd4f0bd7c Merge pull request #1911 from zyw0605688/dev2.7.7
修改模板文件table.vue.tpl
2024-10-22 13:29:18 +08:00
pixelmaxQM c3fd7b9077 fixed: 修复一对一一对多编辑时候,kv丢失的bug。 2024-10-21 20:16:59 +08:00
zyw0605688 0f6aa3df83 feat:'1.查询条件字段,如果关联业务表下拉查询,则参考form使用下拉框。2.新增和添加统一,变更好修改统一,查看详情弹框增加标题' 2024-10-19 11:32:14 +08:00
pixelmaxQM 48333c2ad2 Merge remote-tracking branch 'origin/main' into dev2.7.7 2024-10-18 21:25:27 +08:00
pixelmaxQM 9786886c3f feat: 在存在enum的情况下自动化代码时候会校验其赋值并且在错误时候自动包裹 2024-10-18 21:23:43 +08:00
pixelMax(奇淼 b0eedfd6f1 fix: AI导出需要必须选择表 2024-10-18 18:07:23 +08:00
pixelMax(奇淼 1753bf96a8 fix: AI导出表格模板获取表格信息错误的bug 2024-10-18 17:41:58 +08:00
pixelMax(奇淼 67315bf88e feat: 自动化代码string调整为指针类型 2024-10-18 13:53:48 +08:00
PiexlMax(奇淼 4a3dcf24e1 Merge pull request #1906 from Brandon-lz/main
新增支持minio oss
2024-10-18 10:35:44 +08:00
PiexlMax(奇淼 c1b18fe478 Merge branch 'dev2.7.7' into main 2024-10-18 10:35:35 +08:00
chenlianghong e918af0a0c adjust sys_user.go message when del logined self (#1909) 2024-10-18 10:34:24 +08:00
pixelmaxQM a847ad292f feat: 自动化代码可自行配置mod 2024-10-17 23:15:59 +08:00
pixelmaxQM efac72ecbb feat: 增加添加字段功能,方便用户粘贴赋值字段到对应代码位置 2024-10-17 22:29:52 +08:00
pixelMax(奇淼 ed5611810f feat: 自动化代码部分输入框样式调节 2024-10-17 10:03:44 +08:00
pixelMax(奇淼 b8d5e79c03 fixed: 修复无法直接设置router-view的bug 2024-10-16 15:26:09 +08:00
pixelMax(奇淼 3e72ea0650 delete: 去除无用的引用包 2024-10-16 13:17:03 +08:00
pixelMax(奇淼 8b8a0b61af delete: 剔除ws插件 2024-10-16 13:13:15 +08:00
pixelmaxQM f237ac981e feat: 增加自动化代码增加字段的可控参数 2024-10-15 23:28:47 +08:00
PiexlMax(奇淼andAzir 0ce5a63c1d update: 发布dev2.7.6Beta版本 (#1908)
* feat: 优化菜单管理的路径选择框

* fixed: 修复错误的文件命名

* feat: 增加参数管理功能,调整菜单选择组件。

* feat: 恢复config.yaml

* feat: 更新AI功能

* feat: 增加API自动填充功能

* feat: 增加AI自动填充表格导出模板

* feat: 增加AI自动填充表格导出模板和AI自动模板填充

* feat: 新增方法支持选择是否鉴权

---------

Co-authored-by: Azir <2075125282@qq.com>
2024-10-15 21:58:17 +08:00
Brandon-lz a483ac9174 minio 完善 2024-10-14 11:46:39 +00:00
Brandon-lz 91e4c89962 新增minio oss 功能 2024-10-14 10:03:28 +00:00
PiexlMax(奇淼 c34e3b4282 Update README.md 2024-10-11 17:36:25 +08:00
chenlianghong 6e38eb1d70 fix: support pluginPath svg file as component show list when dev mode (#1902) 2024-10-09 10:30:27 +08:00
piexlMax(奇淼 5d227d8d72 feat: 配置保存按钮移动到顶部 2024-10-08 13:14:43 +08:00
piexlMax(奇淼 ccdf725957 fixed: 修复暗夜模式失效的bug 2024-10-08 13:06:18 +08:00
86cffba4aa Beta:发布v2.7.5测试版本 (#1896)
* 生产环境时移除console

* 更新第三方库道最新版本,修正导致的兼容问题

* feat: 版本号变更,修复自动化历史的结构体描述

* feat: 放弃element的按需引用,增加自定义表单组件,替换原始的iframe引入模式。

* feat: 放开表单生成器的key输入

* feat: 自动化代码关联属性支持跨数据库关联

* fixed: 修复跨库关联模板

* feat: 允许清空跨数据关联的业务库选项

* feat: 增加用户搜索功能

* feat: 允许单条API同步
---------

Co-authored-by: task <121913992@qq.com>
Co-authored-by: task <ms.yangdan@gmail.com>
2024-09-30 21:27:16 +08:00
pixelMax(奇淼 2086a73557 feat: 兼容不同版本数据库的json操作 2024-09-30 16:05:45 +08:00
piexlMax(奇淼 a5e8980b23 fix: 消除swag init的不兼容bug 2024-09-29 10:17:59 +08:00
piexlMax(奇淼 360af93d8d fix: 增加图片选择器兼容性 2024-09-29 10:14:26 +08:00
3vilive 4c46bdaa7f feat: 上传文件到 oss 遇到错误时,应该返回错误,避免 panic (#1890) 2024-09-27 20:54:44 +08:00
pixelmaxQM b98094ceee feat: 修复文件选择组件的bug 2024-09-25 21:08:06 +08:00
pixelmaxQM 03330537fc feat: 优化图片选择器 2024-09-22 23:18:33 +08:00
task 2c7809b134 生产环境时移除console 2024-09-21 13:21:30 +08:00
task af287dcdce 生产环境时移除console 2024-09-21 13:21:30 +08:00
chenlianghong ed840a96e6 clean: Update global.js clean console.log svg component name 2024-09-21 13:21:30 +08:00
chenlianghong 04cfd0eb38 feat: edit global.js support plugin svg 2024-09-21 13:21:30 +08:00
pixelmaxQM 6386034c65 feat: 调整icon功能的绑定形式 升级vue和svg插件 2024-09-21 12:54:58 +08:00
chenlianghong 9b26d6c504 server: same Author "yourname" for gen Code (#1887) 2024-09-21 12:28:05 +08:00
chenlianghong 3529297fa4 clean: clean header index.vue repeat flex class (#1888) 2024-09-21 12:27:20 +08:00
pixelmaxQM ad699fa23c fixed: 方法名 ==> 方法介绍 2024-09-18 22:51:27 +08:00
pixelmaxQM 0fd9e951b9 fixed: 对JSONMap进行多数据库不同断言兼容 2024-09-18 22:48:41 +08:00
PiexlMax(奇淼 66bcd32ae7 Merge pull request #1886 from flipped-aurora/revert-1884-main
Revert "Update basetypes.go, fixed origin_setting column read error"
2024-09-18 22:41:24 +08:00
PiexlMax(奇淼 f0d91b0058 Revert "Update basetypes.go, fixed origin_setting column read error" 2024-09-18 22:41:06 +08:00
PiexlMax(奇淼 3d58213f0b Merge pull request #1884 from juneyx/main
Update basetypes.go, fixed origin_setting column read error
2024-09-18 22:37:12 +08:00
Juneyx 528d7411e1 Update basetypes.go, fixed origin_setting column read error 2024-09-18 14:53:13 +08:00
pixelmaxQM a6651ffe48 fixed: 字典页面默认值调整为拉回字典列表的第一个 2024-09-17 21:13:42 +08:00
pixelmaxQM a8e6dc3a3a fixed: 修复复用代码高级模式不展示可选项的bug 2024-09-17 09:43:19 +08:00
pixelmaxQM 8733b2463c fixed: 清理自动化方法的swagger入参 2024-09-16 20:01:45 +08:00
pixelmaxQM 37b0ef4599 fixed: 修复文件监听错误的bug 2024-09-14 18:16:17 +08:00
pixelmaxQM c72ed970fb feature: 增加basetype 兼容低版本数据库的json不兼容问题 2024-09-13 21:02:15 +08:00
pixelMax(奇淼 e9e42be139 fixed: 修复RedisList不受控制创建的bug 2024-09-13 16:39:43 +08:00
piexlMax(奇淼 b55ecd2808 fixed: api.js模板调整 2024-09-13 16:13:48 +08:00
pixelmaxQM f2a8829d1d feature: 版本号v2.7.3升级为v2.7.4 2024-09-12 21:03:35 +08:00
c20ea7e030 publish: 发布2.7.4版本Beta (#1880)
* 媒体库增加批量导入URL

* fix 描述错误

* feature: 自动化代码方法支持增加方法描述

* update: 更新依赖,升级为最新版本

* feature: 自动化代码预览部分支持黑夜模式

* fixed: 修复keepalive上线后失效的bug

* feature: 增加自动化基础模板功能

* feature: 增加自动化基础模板功能

* 将用户配置保存到数据库,刷新或者异地登录配置不丢失

* update: 清除无用的userinfo配置信息

* fixed: 清理开发阶段页面无端进入404的bug

* feature: 前端主题配置跟随用户,不再单独设置json编译生效。

* feature: 增加个人中心配置兼容性

* fix(package): 包名设置为中文会导致无法自动生成代码,禁止包名设置为中文

* feature: 格式化代码

* feature: 对严格模式新建根角色进行调整。

* feature: 版本变更为2.7.4

---------

Co-authored-by: sliboy <34034053+sliboy@users.noreply.github.com>
Co-authored-by: ba0ch3ng <ba0ch3ng@foxmail.com>
Co-authored-by: task <121913992@qq.com>
Co-authored-by: task <ms.yangdan@gmail.com>
Co-authored-by: 爱丽-黑子 <62006632+ailiheizi@users.noreply.github.com>
Co-authored-by: sliboy <sliboy@hotmail.com>
2024-09-12 20:48:03 +08:00
pixelmaxQM df3fc0a9ef fixed: 修复文件上传失败但是依然加入了文件列表的bug 2024-09-04 22:37:41 +08:00
pixel(奇淼 3c7a05b572 feature: 增加上传文件组件的成功失败回调事件 2024-08-31 22:06:36 +08:00
pixelmaxQM a155bcd11a fixed: 修复登陆页面小屏幕下背景色bug 2024-08-30 22:17:46 +08:00
pixelmaxQM 57f13f59b1 fixed: 修复loading无法消失的bug 2024-08-30 22:15:15 +08:00
pixelmaxQM 894cf8e6c3 feature: api默认忽略数据增加 /info/getInfoDataSource 和 /info/getInfoPublic 2024-08-27 21:44:15 +08:00
zayn fa3b952af3 column参数类型是number (#1865)
避免浏览器console的warn提示
Vue warn]: Invalid prop: type check failed for prop "column". Expected Number with value 1, got String with value "1".
2024-08-27 13:17:07 +08:00
chenlianghong b26db1910b Update model.go.template (#1866) 2024-08-27 13:16:39 +08:00
chenlianghong aab865be96 Update service.go.template (#1867)
清除生成代码多于空格
2024-08-27 13:16:18 +08:00
PiexlMax(奇淼andtask 866fa5643e Dev273 (#1868)
* fixed: 修复addFunction下前端api.js无法创建的bug。

* feature: 增加严格角色模式

* Update system.vue

* fixed: 多点登录拦截模式下,jwt换票期间不需要拉黑token。

* fixed: 修复使用ast时候产生无意义的换行的问题

* fixed: 修复跨级操作角色权限的越权问题

* feature: 优化严格模式角色鉴权操作。

* fixed: 增加菜单和api设置越权问题的限制

* feature: 增加插件打包前的自动化同步所需菜单和api的功能

* feature: 自动化代码可以默认生成导入导出

* feature: 自动化导入导出对模板进行回滚

* feature: 剔除无用的packfile代码包

* feature: 发布V2.7.3版本公测。

---------

Co-authored-by: task <ms.yangdan@gmail.com>
2024-08-27 13:15:56 +08:00
PiexlMax(奇淼 87ced16d63 Merge pull request #1862 from Eric54920/Eric-dev
feature: swagger接口请求优化
2024-08-24 23:20:23 +08:00
Eric54920 ed5463360e feature: swagger接口请求优化 2024-08-24 22:34:09 +08:00
chenlianghong 27edfac161 fix: add funcName is sure UpperChar (#1860)
* fix: add funcName is sure UpperChar
2024-08-23 18:14:40 +08:00
pixelMax(奇淼 7f70e69c8e fixed: 修复自动化代码产生的详情功能图片不可用的bug 2024-08-20 10:55:41 +08:00
pixelMax(奇淼 c70fedfb43 fixed: 修复addFunction下前端api.js无法创建的bug。 2024-08-15 18:05:43 +08:00
pixelMax(奇淼 85d7b5fd5d fixed: 修复addFunction下前端api.js无法创建的bug。 2024-08-15 18:04:33 +08:00
pixelMax(奇淼 cbace6f97e feature: 调整全量引入功能对格式化后的代码依然生效 2024-08-15 15:52:35 +08:00
pixelMax(奇淼 bec5dc4476 fixed: 模板中el-image默认添加preview-teleported,用户在预览时候方式弹出层被遮罩。 2024-08-15 15:38:29 +08:00
sliboy f7ddd8bbbb chore(user.vue): Update user.vue, alter userInfo username to userName. (#1855) 2024-08-15 10:49:31 +08:00
马国栋 43d0c291ed feature:swagger 接口请求方式优化 (#1854) 2024-08-15 10:46:41 +08:00
pixelmaxQM 0956edd0d0 feat: 初始化完成后主动获取GVA_ACTIVE_DBNAME。 2024-08-14 20:48:47 +08:00
c9477d37fa V2.7.2版本发布 (#1853)
* feat: 自动化代码增加json导出和导入功能

* feat: 自动化代码前端可见分为Table和Form分别选中

* feature: 调整代码预览为左边栏模式的tabs。

* feat: 增加方法自动添加前端api

* feat: 自动化生成前端支持详情功能

* feat: 增加自动创建可控权限按钮功能

* fixed: 顶栏样式菜单样式细节bug修复

* fixed: 修改视频地址

* fixed: 自动获取表结构和数据库表列结构保持一致

* fixed: casbin 设置空权限无需调用 AddPolicies 方法 (#1850)

* feat:对象存储支持配置Cloudflare R2 (#1849)

* fixed:设为首页和菜单勾选互为必选

---------

Co-authored-by: SliverHorn <503551462@qq.com>
Co-authored-by: 千石 <CN_QianShi@hotmail.com>

* feat: 复杂数据类型的查询将不会生成查询语句,会以string形式接收参数,用户自行实现复杂查询逻辑。

* feat: 创建新角色默认携带字典和长传权限。
禁止删除有首页占用的菜单。
不允许切换至无首页的角色。
自动化代码创建失败将返回错误信息。

* feat: 当package或plugin结构异常时候,阻止创建自动化代码。

---------

Co-authored-by: krank <emosick@qq.com>
Co-authored-by: SliverHorn <503551462@qq.com>
Co-authored-by: 千石 <CN_QianShi@hotmail.com>
2024-08-13 21:55:27 +08:00
千石 3b5c96d7cb feat:对象存储支持配置Cloudflare R2 (#1849) 2024-08-12 22:30:14 +08:00
SliverHorn c3c049b225 fixed: casbin 设置空权限无需调用 AddPolicies 方法 (#1850) 2024-08-12 22:29:50 +08:00
lbbniu 6fedb9773b fix: 代码自动生成选择业务库自动迁移代码生成异常 (#1848) 2024-08-12 15:08:17 +08:00
pixelmaxQM 332a8de2e9 fixed: 修复其他数据库类型下无法获取表列表的bug 2024-08-05 20:05:23 +08:00
PiexlMax(奇淼andkrank 7121968081 2.7.1版本提交 (#1844)
* feature:表格模板自动化生成 (#1841)

* feature:  为导出模板增加自动化功能

* feature:  视频按钮修改

* feature: 发布2.7.1Beta版本,视频集中处理。

---------

Co-authored-by: krank <emosick@qq.com>
2024-08-04 16:06:00 +08:00
pixelmaxQM a44133d0c9 fixed: 修复在同时开启多个窗口的情况下刷新页面导致的死循环情况 2024-08-04 11:12:43 +08:00
pixelmaxQM 3c3d9487d0 fixed:修复复用代码无法改变主键的bug 2024-08-03 15:08:25 +08:00
PiexlMax(奇淼 15b5083d17 Update README.md 2024-08-03 14:55:11 +08:00
pixelMax(奇淼 e25cafe2b4 fixed: 调整重复创建代码的提示 2024-08-02 14:35:16 +08:00
pixelMax(奇淼 b5c44e47ff feature: 调整baseUrl方法 2024-08-01 18:24:11 +08:00
pixelMax(奇淼 5d04b8deea fixed: 调整autoCode标签 2024-08-01 14:20:18 +08:00
pixelMax(奇淼 1207291249 fixed: 修复自动化模板多了}的问题 2024-08-01 14:08:05 +08:00
pixelMax(奇淼 06bf641e7a fixed: 修复自动化代码路径不匹配的bug 2024-07-31 18:09:12 +08:00
pixelMax(奇淼 ce764082b8 feature: 修改vite.config.js注释 2024-07-31 16:23:09 +08:00
pixelMax(奇淼 aebc301b05 feature: swagger自动化模板优化 2024-07-31 15:55:31 +08:00
pixelMax(奇淼 3b93a073c3 feature: swagger 优化 2024-07-31 15:52:23 +08:00
pixelMax(奇淼 a4a7b44da9 feature: Local优化文件删除逻辑 2024-07-31 11:22:56 +08:00
maxwell e65be6ee36 feat: tab支持使用鼠标中键关闭 (#1840)
* fix: 修复注释错误

* feat: tab支持使用鼠标中键进行关闭
2024-07-31 11:20:14 +08:00
LixvYang 2d0b9ecac0 add cloudflare r2 storage (#1835) 2024-07-30 15:31:23 +08:00
pixelmaxQM 5a5b86aeec fixed:新增方法清空已经输入的内容 2024-07-27 22:25:13 +08:00
pixelmaxQM ff41fe0577 fixed:对导出关键字进行处理 2024-07-27 17:59:00 +08:00
pixelmaxQM c97b60b2da fixed:插件api增加空方法模板调整。 2024-07-27 14:29:02 +08:00
pixelmaxQM 2645dcdddf fixed:插件api增加空方法模板调整。 2024-07-27 14:25:22 +08:00
pixelmaxQM 6debb09b0f Merge remote-tracking branch 'origin/main' 2024-07-27 00:17:02 +08:00
pixelmaxQM 62b84d454a feature:提取创建claims和token的方法,方便后续插件扩展。 2024-07-27 00:16:48 +08:00
pixelMax(奇淼 26dc3f32d9 feature: 优化自动化api模板 2024-07-26 14:52:24 +08:00
SliverHorn 84f8b6e1da fixed: package template api.go.tpl Update 2024-07-26 14:47:47 +08:00
SliverHorn 70e3d40c3e Merge remote-tracking branch 'origin/main' 2024-07-26 14:45:28 +08:00
SliverHorn 432b2f04d7 fixed: plugin template api.go.template and package template api.go.tpl 2024-07-26 14:45:10 +08:00
pixelMax(奇淼 63c82cf705 feature: 优化pathInfo.json生成功能 2024-07-26 14:00:08 +08:00
pixelMax(奇淼 5c7d121e67 feature: 放弃自己研发的代码定位功能,集成vite官方的devtool工具 2024-07-26 13:38:21 +08:00
SliverHorn 055198ccd5 fixed: plugin template api.go.template {{.Abbreviation}}.UpdatedBy rename info.UpdatedBy 2024-07-26 13:01:06 +08:00
SliverHorn 0993e81e00 fixed: package template api.go.tpl 作用域问题 2024-07-26 11:58:39 +08:00
pixelMax(奇淼 15d22b7726 feature: 增加空方法后续业务逻辑处理 2024-07-26 11:30:41 +08:00
pixelMax(奇淼 bb3a54a312 feature: 优化添加空方法的apiPath 2024-07-26 11:22:30 +08:00
pixelMax(奇淼 7ad6b9c32a feature: 自动关联可能的apiGroup 2024-07-26 11:15:02 +08:00
pixelMax(奇淼 4814f21017 feature: 增加新初始化api 2024-07-26 10:28:21 +08:00
pixelMax(奇淼 1f962f21b3 fixed: 修复自动化代码字段名称key编辑时候失去焦点的bug 2024-07-26 10:24:48 +08:00
pixelMax(奇淼 397e1e2bf1 opt: 优化模板逻辑 2024-07-26 10:04:56 +08:00
pixelmaxQM b10c7297fd feature:方法结束关闭file 2024-07-25 21:55:40 +08:00
PiexlMax(奇淼 7f9194f475 feater: 可对自动化代码增加空方法 (#1834)
* feature:自动化代码可从自动化代码管理中增加空方法,用户不用自行组织其中的关系。
2024-07-25 21:29:20 +08:00
lonevle 0fc1edf895 Dockerfile修复工作路径的问题 (#1833) 2024-07-25 21:27:20 +08:00
pixelMax(奇淼 c973c0cce5 feature: 调整自动化代码菜单和api注册逻辑 2024-07-25 16:43:11 +08:00
pixelMax(奇淼 48f3bdc80c fixed:前端文件创建路径错误 2024-07-25 16:11:33 +08:00
pixelMax(奇淼 0fc43fcf42 opt: 调整Viper配置文件路径展示代码 2024-07-25 10:05:48 +08:00
pixelMax(奇淼 e593ec604e opt: 调整import注入和回滚带别名无法识别的bug 2024-07-24 16:48:49 +08:00
PiexlMax(奇淼 1494bc9db3 2.7.0Beta2 (#1829)
* opt: 优化自动化package注册gorm_biz代码,替换为Inspect

* opt: 自动化代码插件gorm改造完成

* opt: 自动化代码插件路由注册改造完成
2024-07-24 15:24:50 +08:00
pixelMax(奇淼 4512aa7ff8 feature: 修复下标越界的bug,调整enter ast 代码 2024-07-23 18:36:35 +08:00
pixelMax(奇淼 de782e629f feature: 修复package下gorm数据添加和回滚的异常 2024-07-23 18:26:19 +08:00
pixelMax(奇淼 b7c6a7ffd9 feature: 修复package下gorm数据添加和回滚的异常 2024-07-23 17:35:17 +08:00
pixelMax(奇淼 ca4118cc8e feature: 插件enter回滚当数据为空时候删除import 2024-07-23 16:27:41 +08:00
pixelMax(奇淼 a561e7dc2b feature: 修复自动化插件会创建两个var的bug 2024-07-23 15:56:17 +08:00
PiexlMax(奇淼 b3a0f187d7 2.7.0Beta Bug修复 (#1826)
* feature:调整package注入路由方法

* feature:调整package回滚路由方法

* feature:调整创建自动化代码enter重复import的问题

* feature:调整package创建时enter的问题

* feature:调整package回滚问题
2024-07-23 00:19:21 +08:00
PiexlMax(奇淼 39be2d0351 BetaBug修复 (#1825)
* feature:调整package注入路由方法

* feature:调整package回滚路由方法

* feature:调整创建自动化代码enter重复import的问题
2024-07-22 23:53:48 +08:00
pixelMax(奇淼 5492e0db50 feature: 修复插件无法安装的bug 2024-07-22 11:33:47 +08:00
pixelMax(奇淼 db038c29e8 feature: 修复插件无法安装的bug 2024-07-22 11:30:46 +08:00
pixelmaxQM 4fe1f5c225 feature:菜单选择文件时自动同步path 2024-07-21 22:00:52 +08:00
pixelmaxQM ac374bab22 feature: 调整自动化代码web模板 2024-07-21 21:58:23 +08:00
pixelmaxQM 01f6814a25 feature: 调整插件自动注册逻辑。 2024-07-21 21:36:25 +08:00
6e4dc10c49 文件结构调整,支持插件自动化 (#1824)
* Update index.vue

多个详情页之间切换tab,页面没有重新渲染

* feature:新增同步API功能

* feature: 同步表数据

* feature:新增同步API功能

* feature: 增加V2插件注册

* feature:给Enter的依赖结构增加单独的New 方便引用

* feature: 调整关联属性的选择模式

* feature: 增加component组件和name的映射插件,防止keepalive的懒加载失效。

* update: PluginInitializeRouter  && 修复TypePluginInitializeMenu ast 类型错误

* update: 测试文件的astType 类型错误

* feature: 文件变更自动同步componentName.json。

* feature: 文件变更自动同步componentName.json。

* feat: UI美化

* feat: 自动化页面顺序调整

* feature:修改404页面

* update: PluginInitializeMenu

* update: Plugin template

* fixed systemApi 重复声明

* api.vue:update:修改API分组为下拉列表

* update: import添加注释

* update: plugin_enter_test.go 增加测试用例

* update: ast 预览文件路径

* update: config Autocode 新增Module字段以及如果为空的情况下自动获取运行目录下的go.mod文件

* update: auto_code_package.go 完善调用ast工具类的封装使用

* update: auto_code_template.go Create方法和修正SysAutoCodeHistory

* feat:调整自动化package为模板,增加初始化配置信息,调整页面信息。

* update: ast PreviewPath MkdirAll

* update: ast type错误, PluginEnter and PackageModuleEnter add TemplatePath模版路径

* update: autoCodePackage and autoCodeTemplate bug修正

* update: PackageInitializeRouter 传入两个路由组

* update: PackageModuleEnter 处理空变量时与type冲突注入

* update: Package 模版更新

* update: utils/ast 优化统一

* update: 注入内容修复错误

* fix: 修复注释错误

* update: plugin 模版 完成

* feature: 文件watch功能只在development下开启

* update: viper.go.template 因为viper不区分配置的key的大小写所以用package

* update: ast 测试代码规范化

* update: package 删除api和router多余导包

* update: plugin template

* update: auto_code_package 问题修复

* update: ast 测试插件的预览功能

* update: gorm_biz 更新注册方式

* update: go.mod tidy

* remove: plugin template gen main.go.template

* update: ast 重构, 分离读取和写入步骤支持

* update: AutoCodePackageApi 传入参数错误修复

* rename: sys_autocode_history.go => sys_auto_code_history.go

* update: 预览无需落盘, 创建落盘,抽离公共参数

* update: api.go.tpl 导包位置fmt 和package js位置存放错误

* update: 测试用例修复 and PackageInitializeGorm 重构

* update: ast 新增相对路径, 代码生成器历史回滚功能

* update: ast 工具类回滚失败修复以及测试文件

* update: 代码生成器历史 回滚问题修复

* update: 代码生成器模版忽略.DS_Store

* featute: 自动化GORM结构的注入和剔除

* feature: 插件模板调整

* feature: 增加公告插件示例,调整代码模板。

* feature: 自动注册插件V2。

---------

Co-authored-by: zayn <972858472@qq.com>
Co-authored-by: SliverHorn <sliver_horn@qq.com>
Co-authored-by: krank <emosick@qq.com>
Co-authored-by: cjk <wlicjk@126.com>
Co-authored-by: piexlMax(奇淼 <qimiaojiangjizhao@gmail.com>
Co-authored-by: maxwell <zhong.maxwell@gmail.com>
2024-07-21 11:33:25 +08:00
jameschcc 6b3a9024d3 README.md: correct typo (#1823) 2024-07-21 11:30:36 +08:00
PiexlMax(奇淼 b4841843f7 Update ci.yaml 2024-07-17 13:24:52 +08:00
pixelMax(奇淼 35efc07b2e fixed: 增加导出模板特殊字段说明,添加默认darkMode 2024-07-10 17:53:57 +08:00
pixelMax(奇淼 954160ebd9 feature: 调整导出的时间格式处理 2024-07-10 17:52:53 +08:00
pixelMax(奇淼 ea1633ad52 fixed: 修复darkMode失效的bug 2024-07-10 17:34:56 +08:00
pixelmaxQM fb5d5ea1be feature:版本变更v2.6.7 2024-07-06 12:17:17 +08:00
PiexlMax(奇淼 02f5d6fea2 增加同步API功能 (#1811)
* feature:新增同步API功能
2024-07-04 21:19:20 +08:00
zayn 227755b892 Update index.vue (#1810)
多个详情页之间切换tab,页面没有重新渲染
2024-07-04 21:14:12 +08:00
SliverHorn eebd8771bd Merge pull request #1809 from SliverHorn/ai
Update: mv system ai-path to autocode
2024-07-03 09:31:34 +08:00
SliverHorn 36fed0cc6f Update: mv system ai-path to autocode 2024-07-03 09:27:30 +08:00
pixelmaxQM 08f3b64243 feature:增加AI提问的长度限制 2024-07-02 23:40:14 +08:00
PiexlMax(奇淼 59cfe96fe3 增加AI辅助功能 (#1808)
* feature: 增加两个辅助AI,小奇和小淼

* feature:调整AI自动反写部分
2024-07-02 22:53:59 +08:00
PiexlMax(奇淼 128e810f77 调整镜像和依赖 2024-07-02 11:07:33 +08:00
PiexlMax(奇淼 bbe9322f75 Update Makefile 2024-07-02 11:03:38 +08:00
pixelMax(奇淼 35186b41ff feature:调整多图下不换行的问题 2024-07-02 10:46:38 +08:00
pixelMax(奇淼 0c846f0fea feature:url调整兼容各类情况下的图片展示 2024-07-02 10:46:30 +08:00
Wallandwall-js d497e96407 feat: 调整逻辑无论是否创建菜单或API都注册自动化代码历史 (#1804)
* feat: 调整逻辑无论是否创建菜单或API都注册自动化代码历史

---------

Co-authored-by: wall-js <wall_js@foxmail.com>
2024-07-01 10:43:32 +08:00
Qing Liang a4f139f855 后端dockerfile正确设置时区 && 忽略后端server/uploads文件夹 (#1803)
* dockerfile后端设置时区

* gitignore忽略后端uploads文件夹
2024-07-01 10:14:24 +08:00
pixelmaxQM e386b28ba4 feature:插件注册功能多给一个engine 准备后续扩展 2024-06-29 00:22:53 +08:00
pixelmaxQM aa8ef48246 fixed:侧边宽度调整防止出现横向滚动条 2024-06-28 21:59:07 +08:00
pixelmaxQM 6bac462359 fixed:图片展示功能调整 2024-06-28 21:46:37 +08:00
pixelMax(奇淼 24e4d05157 feature:url调整让上传文件支持/模式 2024-06-28 11:37:59 +08:00
SliverHornandSliverHorn 737c051466 Update: .gitignore (#1800)
* Update: .gitignore server

---------

Co-authored-by: SliverHorn <caiwei.lai@jutze.com.cn>
2024-06-27 17:33:52 +08:00
SliverHorn 4ab50882a4 Merge pull request #1801 from jedyang/patch-1
业务路由的代码错误
2024-06-27 16:40:20 +08:00
yunsheng 06a07865f3 Update router_biz.go
privateGroup应该是切片的第一个。publicGroup应该是切片的第一个。
2024-06-27 15:02:11 +08:00
pixelMax(奇淼 5607702be9 fixed: 导出模板调整limit为指针 2024-06-27 14:57:57 +08:00
pixelMax(奇淼 e9be009f49 fixed: 导出模板调整limit为指针 2024-06-27 14:57:01 +08:00
pixelMax(奇淼 bb4e938bd2 fixed: 业务库导出问题调整 2024-06-27 10:20:44 +08:00
Wallandwall-js 45f723c07f feat: 调整自动化代码逻辑,重复创建的菜单和api需要用户手动取消自动创建 (#1798)
* feat: 调整自动化代码逻辑,重复创建的菜单和api需要用户手动取消自动创建

---------

Co-authored-by: wall-js <wall_js@foxmail.com>
2024-06-27 09:41:35 +08:00
pixelmaxQM 640f44fd10 fixed:修复左侧无法滚动的bug 2024-06-26 19:58:57 +08:00
Jupiterandhxl 821dd02aa4 feat: 优化布局结构 统一使用 drawer (#1796)
* sysDictionary.vue: perf 系统统一使用 drawer 抽屉 新增或编辑时form 取消校验

---------

Co-authored-by: hxl <52553624@qq.com>
2024-06-25 10:54:35 +08:00
pixelmaxQM 6e2140258e feature:后端路由注册和数据库注册方法与原始框架分离,自定业务不再干扰原始框架内容。 2024-06-23 17:01:39 +08:00
b628bd7769 调整配置文件默认灰度不生效问题 (#1795)
修复:在默认配置config.json文件修改灰色模式后,启动项目后不生效问题。

---------

Co-authored-by: zsc1003 <11476303+zsc1003@user.noreply.gitee.com>
Co-authored-by: Isaacedvr1003 <152384462+Isaacedvr1003@users.noreply.github.com>
2024-06-22 21:46:42 +08:00
pixelmaxQM f23cd22110 feature:增加静态目录public,调整在线logo地址到public。 2024-06-22 21:16:50 +08:00
PiexlMax(奇淼andSliverHorn 8ef4f408bf feat: 优化自动化代码结构,增加顶栏侧边栏组合式结构 (#1793)
* feature:增加顶栏组合模式。

* Update:
1. request.go.tpl and model.go.tpl indent problem
2. api.go.tpl, request.go.tpl, service.go.tpl struct {}

* Update:
1. model.go.tpl import blank line

* feature:增加顶栏组合模式。

* feature:增加左侧检测逻辑保证存在左侧菜单。

---------

Co-authored-by: SliverHorn <caiwei.lai@jutze.com.cn>
2024-06-21 21:03:47 +08:00
PiexlMax(奇淼 01139a2e6b Merge pull request #1792 from sliboy/main
chore(spell check): rename /server/utils/clamis.go to /server/utils/claims.go
2024-06-21 20:15:15 +08:00
pixelMax(奇淼 08606f740d feature: swagdoc调整 2024-06-21 14:59:30 +08:00
LiDahan 42c6bc11cc chore(spell check): rename clamis.go to claims.go 2024-06-21 09:50:49 +08:00
Wallandwall-js d6703e82e2 fixed: 修复自动化代码form模板,find接口调整未调整完全 (#1790)
Co-authored-by: wall-js <wall_js@foxmail.com>
2024-06-20 17:45:56 +08:00
Wallandwall-js 8f1692e394 fixed: 修复生成代码element-ui接口启用警告问题 (#1787)
* fixed: 修复生成代码element-ui接口启用警告问题

---------

Co-authored-by: wall-js <wall_js@foxmail.com>
2024-06-18 13:17:09 +08:00
pixelMax(奇淼 3e55234a24 feature: 可以选择不自动迁移表结构 2024-06-17 17:17:25 +08:00
pixelMax(奇淼 7df246c25a feature: 可以选择不自动迁移表结构 2024-06-17 17:15:15 +08:00
pixelMax(奇淼 fbffbce090 fixed:调整顶栏模式自动缩进bug 2024-06-17 15:15:28 +08:00
Juneyx 18e9b6d84c Fixed system.vue: 日志留存时间json key错误 (#1785)
后端对应的json key是retention-day
2024-06-16 23:33:59 +08:00
03e5bc515f v2.6.6版本发布 (#1784)
* 前端支持顶部菜单栏模式

* 自动化代码单条获取方法不再需要取data.xxx直接取用data

* 自动化代码支持选择索引

* 自动化代码回滚支持自行选择是否删除菜单、API、表

* 日志增加定期清理功能

* 权限配置API部分,支持根据API真实path进行筛选

* 修复了一些已知bug

* 修复了一个sql注入漏洞

---------

Co-authored-by: xuedinge <781408517@qq.com>
Co-authored-by: Qing Liang <106448173+xue-ding-e@users.noreply.github.com>
Co-authored-by: wall-js <wall_js@foxmail.com>
Co-authored-by: Wall <307606056@qq.com>
Co-authored-by: leooza <leooza@163.com>
Co-authored-by: piexlMax(奇淼 <qimiaojiangjizhao@gmail.com>
Co-authored-by: hxl <52553624@qq.com>
Co-authored-by: zsc1003 <11476303+zsc1003@user.noreply.gitee.com>
2024-06-16 00:27:40 +08:00
Juneyx b336529d42 添加通过点击展开/收起控制显示更多的查询条件的功能 (#1771)
* 给table.vue模板添加控制显示/隐藏更多查询条件的语句块和按钮

* sys_auto_code.go: 添加隐藏查询条件控制字段

* table.vue.tpl: 按照FieldSearchHide字段自动将隐藏的查询条件写到对应的代码块里

* fieldDialog.vue: 添加隐藏查询条件的控制开关

* 只有已经选择了查询条件的情况下才能选择
2024-06-12 23:33:19 +08:00
青菜白玉汤 bbf716b28e style(login): 优化登陆部分代码,提升可读性 (#1772) 2024-06-12 23:32:18 +08:00
pixelMax(奇淼 725f6fe3ec fixed: 自动化请求结构中不应该携带JSON 2024-06-11 14:33:44 +08:00
Dale f773a02ce0 [fixed] 优化错误判断 (#1762) 2024-06-07 11:17:25 +08:00
Deng 21266be1ed perf: 优化 api 和 service 中方法注释不正确的问题 (#1765) 2024-06-05 20:30:08 +08:00
pixelmaxQM 53d0338218 feature:修复已知安全问题。 2024-06-02 21:13:51 +08:00
pixelmaxQM 2f67c23c5c feature:在选择图片时候增加删除按钮,可以在媒体库中直接删除图片。 2024-06-02 20:50:55 +08:00
poppingkaka e64be755f9 优化如果join表时出现重复的字段或者需要有函数时可以导出别名的值 (#1761) 2024-05-31 10:45:39 +08:00
SliverHornandSliverHorn 23952c5f5f Update: (#1758)
1.config gorm相关移除DBBASE实现改为GeneralDB实现LogLevel函数
2.移除initializel/internal/logger实现,改为gorm_logger_writer实现gorm的logger通过zap输出到文件或者控制台
3.优化initializel/internal/gorm代码

Co-authored-by: SliverHorn <caiwei.lai@jutze.com.cn>
2024-05-27 10:24:19 +08:00
02fc5036d7 v2.6.5版本更新 (#1757)
* feature:增加资源加载loading

* feature:修正sql无法落盘的问题

* fixed: 修复切换角色出现404的问题。

* 删除selectImage.vue中chooseImg下多余的console.log(url)

---------

Co-authored-by: krank <emosick@qq.com>
Co-authored-by: Qing Liang <106448173+xue-ding-e@users.noreply.github.com>
2024-05-26 21:49:34 +08:00
a6a65ed9f4 fixed:修复自动化生成表格缺少的prop (#1755)
* fixed:修复自动化生成表格缺少的prop

---------

Co-authored-by: wall-js <liujun@grectronics.cn>
Co-authored-by: wall-js <wall_js@foxmail.com>
2024-05-26 21:24:33 +08:00
Wallandwall-js 369f657aa6 fixed:修复自动化代码无法识别json类型,去掉插件路由冗余代码 (#1751)
* fix(bug): [api.go.tpl]自动化代码swag路径冲突

---------

Co-authored-by: wall-js <liujun@grectronics.cn>
2024-05-22 16:56:55 +08:00
pixelmaxQM 1801e5b30f fixed:selectImage组件图片偏移的bug 2024-05-21 21:26:16 +08:00
pixelmaxQM b10d5103f3 fixed:selectImage组件重构 2024-05-20 22:07:45 +08:00
pixelmaxQM 9964bfef8b fixed:修复特殊符号下无法预览图片的bug 2024-05-20 21:08:32 +08:00
Juneyx 9945a19f2c state.vue: 修复展示多硬盘信息时无法上下滚动的bug (#1749) 2024-05-20 10:27:32 +08:00
pixelmaxQM a5d43e6f14 fixed:修复右上角focus-visible状态下会出现outline的bug 2024-05-18 23:11:28 +08:00
pixelmaxQM b61b9a06dd feature:增加首页插件推荐 2024-05-18 21:58:50 +08:00
pixelmaxQM f28570fa98 feature:新版树组件适配暗夜模式 2024-05-18 21:48:42 +08:00
Juneyx fb53d639be 添加展示多硬盘用量信息的功能 (#1747)
* featurel: 添加多磁盘用量信息展示
2024-05-18 11:52:44 +08:00
nonstop 42de9257c3 fixed: 修复文件分片上传在已选择文件的情况下,再次选择并取消出现控制台飘红且原文件清空的bug (#1746) 2024-05-18 11:48:28 +08:00
Wallandwall-js 0fba597a61 fixed:调整自动化代码swagger文档返回值类型 (#1742)
* fix(bug): [api.go.tpl]自动化代码swag路径冲突

* fixed:调整自动化代码swagger文档返回值类型

* fixed:修复RouterPrefix修改后不影响插件路由问题

---------

Co-authored-by: wall-js <liujun@grectronics.cn>
2024-05-17 16:22:16 +08:00
pixelMax(奇淼 d0393c4e9f fixed:调整前端打包的base路径,适配history模式路由。 2024-05-17 13:25:31 +08:00
pixelMax(奇淼 a21d2a591e feature:优化数据源字段和数组字段展示 2024-05-17 11:26:51 +08:00
pixelMax(奇淼 de54688c56 fixed:自动导入功能将根据表内字段自动创建created_at和updated_at的时间 2024-05-17 10:26:47 +08:00
pixelmaxQM 3c486d9117 feature:暗夜模式兼容调整,初始化需要手动写入初始密码。 2024-05-16 21:55:32 +08:00
pixelmaxQM e8128250f4 feature:暗夜模式兼容调整,初始化需要手动写入初始密码。 2024-05-16 21:49:56 +08:00
pixelmaxQM 58a1b72910 fixed:登录页面暗夜模式适配 2024-05-16 21:02:16 +08:00
SliverHornandSliverHorn ee00d29afd Update: (#1743)
1. 移除zap配置文件MaxAge字段
2. 重构自定义Cutter切分日志
3. 自定义ZapCore, 可实现根据fields自定义功能文件输出

Co-authored-by: SliverHorn <caiwei.lai@jutze.com.cn>
2024-05-16 18:21:30 +08:00
pixelMax(奇淼 5cfcc538a8 fixed:左侧菜单栏超长支持滚动 2024-05-16 15:22:21 +08:00
pixelmaxQM e7c8a9d420 feature:增加自动化代码页面暂时存储功能 2024-05-15 21:40:36 +08:00
pixelmaxQM 6b07ffe8f7 feature:增加数据源一对多关系。 2024-05-15 21:26:32 +08:00
pixelmaxQM 0d17340445 feature:增加数据源一对多关系。 2024-05-15 21:15:41 +08:00
pixelMax(奇淼 2a0b92713b fixed:兼容旧自动化数据 2024-05-15 10:50:22 +08:00
pixelMax(奇淼 fb22eb4178 fixed:修复生成json类文件关闭弹窗后再开启的错误 2024-05-14 15:29:34 +08:00
pixelMax(奇淼 136fb2f394 fixed:修复更新api失败的bug 2024-05-14 12:45:33 +08:00
pixelMax(奇淼 c515805f0a fixed:表格增加左右-1px的边距,防止表格边框线导致宽度超出页面从而无限延伸的bug。 2024-05-14 10:44:36 +08:00
PiexlMax(奇淼 613ba9ba20 Update README-en.md 2024-05-11 11:30:12 +08:00
PiexlMax(奇淼 f6314d3581 Update README.md 2024-05-11 11:29:51 +08:00
pixelmaxQM 043f5c78c2 feature:调整autoPackage弹窗 2024-05-10 21:28:53 +08:00
pixelMax(奇淼 0f9e519b0e feature:调整侧边栏暗夜模式的hover错误 2024-05-10 15:17:04 +08:00
PiexlMax(奇淼 0d17a2351f Update ci.yaml 2024-05-10 14:34:21 +08:00
pixelMax(奇淼 1b388664cb feature:水印密集度调整 2024-05-10 13:16:06 +08:00
pixelMax(奇淼 1edb0c529f feature:调整bottomInfo组件位置 2024-05-10 13:05:36 +08:00
pixelMax(奇淼 f07a58bff4 feature:readme版权相关文案调整 2024-05-10 11:18:48 +08:00
pixelMax(奇淼 c054840aec feature:上线前细节数据调整 2024-05-10 11:15:38 +08:00
PiexlMax(奇淼 e259418398 Update README.md 2024-05-09 21:42:11 +08:00
PiexlMax(奇淼andbypanghu df1d68a724 新版前端UI,预发布2.6.4版本。 (#1735)
* fix: 修改 layout 中相关 emit 和 重复声明的 theme ,采用最新的vue api

* fix:修改 eslintrc 的配置文件,删除大多数无用配置

* fix: 修复 layout 切换手机样式模糊层的 bug

* feature: 重构 layout , 添加暗黑模式 , 删除侧边栏颜色

* fix:细节调整,activeColor摘除。

* feature:右侧滚动模式调整

* feature:无用代码剔除

* fix: 修复暗黑模式相关细节

* fix: custome config layout

* feature:样式细节调整

* fix: 增加前端样式配置文件

* feature:调整基础配置,增加表格边框

* feature:buttomInfo取消底色,a标签更改为活跃色

* feature:调整阴影颜色和配置同步

* feature:版本调整2.6.3==>2.6.4

---------

Co-authored-by: bypanghu <bypanghu@163.com>
2024-05-09 21:35:39 +08:00
Wallandwall-js 9d58390e11 fix(bug): [api.go.tpl]自动化代码swag路径冲突 (#1732)
Co-authored-by: wall-js <liujun@grectronics.cn>
2024-05-09 11:48:15 +08:00
pixelMax(奇淼 db4c7a8bda fixed:修复富文本无法编辑的bug 2024-05-09 10:12:20 +08:00
PiexlMax(奇淼 ab163fc0ef Update ci.yaml 2024-05-06 21:20:20 +08:00
pixelmaxQM 0265801830 fixed:表格模板删除查看详情功能。 2024-05-06 21:15:37 +08:00
pixelmaxQM 5fa7bbbc0f fixed:导出模板顺序一致性调整 2024-05-06 21:10:01 +08:00
PiexlMax(奇淼 e15351e1c5 Update README.md 2024-04-29 17:10:22 +08:00
pixelmaxQM 5eb0133b5c feature:升级后端依赖,前端代码调优 2024-04-28 22:05:50 +08:00
pixelmaxQM ff8344d671 feature:自动化代码增加数据源配置功能 2024-04-27 21:48:24 +08:00
pixelmaxQM d9a43ea1d6 feature:自动化代码增加数据源配置功能 2024-04-27 21:35:29 +08:00
pixelmaxQM 6c62d73afb feature:v2.6.3发布 2024-04-27 17:16:42 +08:00
pixelmaxQM d23d6c342a feature:自动化增加前端可控显隐。 2024-04-25 21:13:55 +08:00
pixelmaxQM 90549a09e1 feature:自动化增加前端可控显隐和自定义class。 2024-04-25 21:02:43 +08:00
pixelmaxQM 17d3639443 feature:优化api代码逻辑,调整pgsql下 more than once的bug。 2024-04-23 21:13:09 +08:00
pixelmaxQM e8a096b8fe feature:调整Update方法,不再使用save全量更新。 2024-04-23 20:56:30 +08:00
pixelmaxQM fea136e513 fixed:修改agent的数据库存储方式,防止日志过长存储失败。 2024-04-23 20:43:50 +08:00
pixelMax(奇淼 f3a4095462 增加丢失的vue-router 2024-04-23 14:45:56 +08:00
pixelmaxQM d7d25cf69b feature:调整抽屉的title属性,消除warning 2024-04-22 22:14:25 +08:00
pixelmaxQM 3b33fe83e6 feature:代码生成器可拖拽行,修复pgsql从库创建代码的bug,增加默认值属性。 2024-04-22 22:04:29 +08:00
pixelmaxQM 56f4d223ab fixed:适配pgsql编辑菜单触发 more than once的bug 2024-04-22 20:59:15 +08:00
pixelMax(奇淼 c07317a619 调整openDocument 2024-04-17 10:39:55 +08:00
Qing Liang 4798f7688b 点击跳转代码插件修复websotrm bug (#1715) 2024-04-17 10:35:32 +08:00
pixelmaxQM 24db0eb5aa fixed:切换角色功能适配新版gorm 2024-04-14 23:43:21 +08:00
Haoran Wu 1ece13c43d sys_export_template.go: 修复导入Excel时前几条为空数据的问题 (#1713) 2024-04-14 21:03:44 +08:00
pixelmaxQM 48268309b9 fixed:回滚时候自动清理掉router下空的作用域 2024-04-14 21:02:35 +08:00
4074a52b1b 修复pgsql和数据库导入bug,增加默认mod中的datatypes (#1712)
* 多文件: fix error specified more than once in PG

* Update sys_authority.go

* Update sys_authority.go

* sys_export_template.go: 导入Excel时使用批量插入提高性能

* 添加gorm.io/datatypes

---------

Co-authored-by: crazyrunsnail <fjyuan1991@163.com>
Co-authored-by: XiMo-210 <2831802697@qq.com>
2024-04-13 18:46:58 +08:00
pixelMax(奇淼 61dd524c26 fixed:修复根目录为O的错误 2024-04-12 14:54:28 +08:00
pixelMax(奇淼 61a678a318 调整无法创建根菜单的bug 2024-04-12 14:47:16 +08:00
pixelmaxQM 8ecec6a14f Merge branch 'fixed_menu'
# Conflicts:
#	server/service/system/sys_base_menu.go
#	web/src/view/superAdmin/menu/menu.vue
2024-04-11 21:27:44 +08:00
PiexlMax(奇淼andcrazyrunsnail e3f8b8a394 fixed:菜单删除功能细节调优 (#1705)
* 多文件: 菜单parentId由string改成uint

* sys_base_menu.go: fix table name "sys_base_menus" specified more than once (SQLSTATE 42712) (#1704)

---------

Co-authored-by: crazyrunsnail <fjyuan1991@163.com>
2024-04-11 21:17:49 +08:00
pixelmaxQM eebddbafcc feature:调整菜单删除逻辑 2024-04-11 21:15:35 +08:00
PiexlMax(奇淼 50cbce0f7a Merge pull request #1702 from crazyrunsnail/fix-model-idtype
多文件: 菜单parentId由string改成uint
2024-04-11 20:56:07 +08:00
fakedavid f9974a8971 sys_base_menu.go: fix table name "sys_base_menus" specified more than once (SQLSTATE 42712) (#1704) 2024-04-11 20:55:46 +08:00
crazyrunsnail baa48a1679 多文件: 菜单parentId由string改成uint 2024-04-11 16:38:09 +08:00
pixelmaxQM 032910f87a feature:插件自动化添加自动注册菜单和api的模板供给修改 2024-04-10 21:48:20 +08:00
pixelmaxQM 773ef95b70 feature:增加插件自动化的前端功能页面 后端api生成自动添加一个开放的接口示例 2024-04-10 21:24:46 +08:00
pixelmaxQM 18c2f84771 feature:表格导出功能增加join支持多表关联导出 2024-04-09 22:05:12 +08:00
pixelmaxQM ea721a71b5 feature:防止自动化代码中的路径穿越 2024-04-09 21:09:01 +08:00
pixelMax(奇淼 b1b7427c6e fixed:修复GHSA-gv3w-m57p-3wc4 2024-04-09 18:09:09 +08:00
pixelmaxQM 7bc7c30510 fixed:#1695 对资源属性进行检测 2024-04-07 21:35:40 +08:00
pixelmaxQM d1e055430d feature:前端自动化增加分包 2024-04-07 21:20:27 +08:00
pixelmaxQM 736534379a fixed:字典限制仅字符串模式可选择 2024-04-07 20:40:02 +08:00
pixelMax(奇淼 f6b71e157c fixed:升级postgres的驱动到1.5.7 2024-04-07 10:16:51 +08:00
ShuBo6 53e9f931f2 fix: 应该调用filepath.Ext的地方调用了path.Ext (#1696)
* fix: 应该调用filepath.Ext的地方调用了path.Ext

* fix: typo
2024-04-03 16:25:09 +08:00
481 changed files with 41462 additions and 19446 deletions
+6 -6
View File
@@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.8.0]
node-version: [18.16.0]
steps:
- name: Check out branch
uses: actions/checkout@v2
@@ -48,7 +48,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [1.21]
go-version: [1.22]
steps:
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
@@ -83,8 +83,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.8.0]
go-version: [1.21]
node-version: [18.16.0]
go-version: [1.22]
steps:
- name: Check out branch
uses: actions/checkout@v2
@@ -194,8 +194,8 @@ jobs:
name: devops-prod
strategy:
matrix:
node-version: ['16.x']
go-version: ['1.21']
node-version: ['18.x']
go-version: ['1.22']
steps:
- uses: actions/checkout@v2
- name: tag major and minor versions
+11 -1
View File
@@ -1,4 +1,3 @@
.idea/
/web/node_modules
/web/dist
@@ -22,11 +21,22 @@ yarn-error.log*
*.sln
*.sw?
rm_file/
/server/log/
/server/gva
/server/server
/server/latest_log
/server/__debug_bin*
server/uploads/
*.iml
web/.pnpm-debug.log
web/pnpm-lock.yaml
# binary files
*.exe
# SQLite database files
*.db
*.sqlite
*.sqlite3
+12 -15
View File
@@ -2,9 +2,9 @@ SHELL = /bin/bash
#SCRIPT_DIR = $(shell pwd)/etc/script
#请选择golang版本
BUILD_IMAGE_SERVER = golang:1.18
BUILD_IMAGE_SERVER = golang:1.22
#请选择node版本
BUILD_IMAGE_WEB = node:16
BUILD_IMAGE_WEB = node:20
#项目名称
PROJECT_NAME = github.com/flipped-aurora/gin-vue-admin/server
#配置文件目录
@@ -13,16 +13,9 @@ CONFIG_FILE = config.yaml
IMAGE_NAME = gva
#镜像地址
REPOSITORY = registry.cn-hangzhou.aliyuncs.com/${IMAGE_NAME}
ifeq ($(TAGS_OPT),)
TAGS_OPT = latest
else
endif
ifeq ($(PLUGIN),)
PLUGIN = email
else
endif
#镜像版本
TAGS_OPT ?= latest
PLUGIN ?= email
#容器环境前后端共同打包
build: build-web build-server
@@ -48,7 +41,7 @@ build-image-server:
build-local:
if [ -d "build" ];then rm -rf build; else echo "OK!"; fi \
&& if [ -f "/.dockerenv" ];then echo "OK!"; else make build-web-local && make build-server-local; fi \
&& mkdir build && cp -r web/dist build/ && cp server/server build/ && cp -r server/resource build/resource
&& mkdir build && cp -r web/dist build/ && cp server/server build/ && cp -r server/resource build/resource
#本地环境打包前端
build-web-local:
@@ -63,13 +56,17 @@ build-server-local:
&& go build -ldflags "-B 0x$(shell head -c20 /dev/urandom|od -An -tx1|tr -d ' \n') -X main.Version=${TAGS_OPT}" -v
#打包前后端二合一镜像
image: build
image: build
docker build -t ${REPOSITORY}/gin-vue-admin:${TAGS_OPT} -f deploy/docker/Dockerfile .
#尝鲜版
images: build build-image-web build-image-server
docker build -t ${REPOSITORY}/all:${TAGS_OPT} -f deploy/docker/Dockerfile .
#swagger 文档生成
doc:
@cd server && swag init
#插件快捷打包: make plugin PLUGIN="这里是插件文件夹名称,默认为email"
plugin:
if [ -d ".plugin" ];then rm -rf .plugin ; else echo "OK!"; fi && mkdir -p .plugin/${PLUGIN}/{server/plugin,web/plugin} \
+1 -5
View File
@@ -1,6 +1,6 @@
<div align=center>
<img src="http://qmplusimg.henrongyi.top/gvalogo.jpg" width=300" height="300" />
<img src="http://qmplusimg.henrongyi.top/gvalogo.jpg" width="300" height="300" />
</div>
<div align=center>
<img src="https://img.shields.io/badge/golang-1.18-blue"/>
@@ -16,10 +16,6 @@ English | [简体中文](./README.md)
[github](https://github.com/flipped-aurora/gin-vue-admin): https://github.com/flipped-aurora/gin-vue-admin
[Vue3 version branch address](https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop): https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop
[Approval flow branch](https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow): https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow
# Project Guidelines
[Online Documentation](https://www.gin-vue-admin.com/) : https://www.gin-vue-admin.com/
+34 -16
View File
@@ -1,7 +1,8 @@
<div align=center>
<img src="http://qmplusimg.henrongyi.top/gvalogo.jpg" width=300" height="300" />
<img src="http://qmplusimg.henrongyi.top/gvalogo.jpg" width="300" height="300" />
</div>
<div align=center>
<img src="https://img.shields.io/badge/golang-1.20-blue"/>
<img src="https://img.shields.io/badge/gin-1.9.1-lightBlue"/>
@@ -10,16 +11,30 @@
<img src="https://img.shields.io/badge/gorm-1.25.2-red"/>
</div>
<div align=center>
<a href="https://trendshift.io/repositories/3250" target="_blank"><img src="https://trendshift.io/api/badge/repositories/3250" alt="Calcium-Ion%2Fnew-api | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</div>
[English](./README-en.md) | 简体中文
## 不同版本
## ✨一分钟生成前后端基础代码
我们会对以下四个版本持续维护,请选择适合自己的版本使用。最新技术栈为组合式api版本,已支持多语言(I18N)
<table>
<tr>
<td width="200">
<p>📄 创建基础模板</p>
<p>🤖 AI生成结构</p>
<p>⏰ 生成代码</p>
<p>🏷️ 分配权限</p>
<p>🎉 基础CURD生成完成</p>
</td>
<td>
<video src="https://private-user-images.githubusercontent.com/165128580/384700666-4d039215-af29-4f86-bb4f-60dbab38f58e.mp4?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzEyNTIxNDYsIm5iZiI6MTczMTI1MTg0NiwicGF0aCI6Ii8xNjUxMjg1ODAvMzg0NzAwNjY2LTRkMDM5MjE1LWFmMjktNGY4Ni1iYjRmLTYwZGJhYjM4ZjU4ZS5tcDQ_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMTEwJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTExMFQxNTE3MjZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00NjJkMDcwZjJkMjAyMmU1N2I2MzQxY2RhODFlNzgzNGRiMDFhMmY2NTYyM2ZmODdhNDVmMWE1NzlhMDdlOTI5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.ZJbswpLzF2RHjemcGirKOP0L1fvpl3FUqIiQ_-yjeUo" data-canonical-src="https://private-user-images.githubusercontent.com/165128580/384700666-4d039215-af29-4f86-bb4f-60dbab38f58e.mp4?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzEyNTIxNDYsIm5iZiI6MTczMTI1MTg0NiwicGF0aCI6Ii8xNjUxMjg1ODAvMzg0NzAwNjY2LTRkMDM5MjE1LWFmMjktNGY4Ni1iYjRmLTYwZGJhYjM4ZjU4ZS5tcDQ_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMTEwJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTExMFQxNTE3MjZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00NjJkMDcwZjJkMjAyMmU1N2I2MzQxY2RhODFlNzgzNGRiMDFhMmY2NTYyM2ZmODdhNDVmMWE1NzlhMDdlOTI5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.ZJbswpLzF2RHjemcGirKOP0L1fvpl3FUqIiQ_-yjeUo" controls="controls" muted="muted" class="d-block rounded-bottom-2 border-top width-fit" style="max-height:640px; min-height: 200px">
</video>
</td>
</tr>
</table>
[组合式API版(主)](https://github.com/flipped-aurora/gin-vue-admin) |
[组合式API多语言(i18n)版](https://github.com/flipped-aurora/gin-vue-admin/tree/i18n-dev-new) |
[声明式API版](https://github.com/flipped-aurora/gin-vue-admin/tree/v2.4.x) |
[声明式API多语言(i18n)版](https://github.com/flipped-aurora/gin-vue-admin/tree/i18n-dev)
# 项目文档
[在线文档](https://www.gin-vue-admin.com) : https://www.gin-vue-admin.com
@@ -34,6 +49,8 @@
[插件市场](https://plugin.gin-vue-admin.com/)
[软件著作权证书](https://www.gin-vue-admin.com/copyright.pdf)
# 重要提示
1.本项目从起步到开发到部署均有文档和详细视频教程
@@ -42,9 +59,11 @@
3.您完全可以通过我们的教程和文档完成一切操作,因此我们不再提供免费的技术服务,如需服务请进行[付费支持](https://www.gin-vue-admin.com/coffee/payment.html)
4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,其余信息功能不做任何限制。如需剔除请[购买授权](https://www.gin-vue-admin.com/empower/index.html)
4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,以及日志和代码中所包含的版权声明信息。所需保留信息均为文案性质,不会影响任何业务内容,如决定商用【产生收益的商业行为均在商用行列】或者必须剔除请[购买授权](https://www.gin-vue-admin.com/empower/index.html)
\
<img src="https://qmplusimg.henrongyi.top/openSource/login.jpg" width="1000">
<img src="https://qmplusimg.henrongyi.top/%E6%8E%88%E6%9D%83.png" width="1000">
<img src="https://qmplusimg.henrongyi.top/openSource/dashboard.jpg" width="1000">
## 1. 基本介绍
@@ -83,7 +102,7 @@ Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-adm
```
- node版本 > v16.8.3
- golang版本 >= v1.16
- golang版本 >= v1.22
- IDE推荐:Goland
```
@@ -101,11 +120,9 @@ cd server
# 使用 go mod 并安装go依赖包
go generate
# 编译
go build -o server main.go (windows编译命令为go build -o server.exe main.go )
# 运行
go run .
# 运行二进制
./server (windows运行命令为 server.exe)
```
### 2.2 web项目
@@ -331,7 +348,7 @@ swag init
### 7.1 技术群
### QQ交流群:470239250
### QQ交流群:971857775
### 微信交流群
| 微信 |
@@ -362,4 +379,5 @@ fmt.Println(decodeBytes, err)
## 10. 商用注意事项
如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。
请严格遵守Apache 2.0协议并保留作品声明,商业用途请务必[获取授权](https://www.gin-vue-admin.com/empower/)
未授权商用将依法追究法律责任
@@ -1,99 +0,0 @@
version: "3"
# 声明一个名为network的networks,subnet为network的子网地址,默认网关是177.7.0.1
networks:
network:
ipam:
driver: default
config:
- subnet: '177.7.0.0/16'
# 设置mysql,redis持久化保存
volumes:
mysql:
redis:
services:
web:
image: node:16
container_name: gva-web
hostname: gva-web #可以通过容器名访问
restart: always
ports:
- '8080:8080'
depends_on:
- server
working_dir: /web # 如果docker 设置了workdir 则此处不需要设置
#若网络不太好,请自行换源,如下
#command: bash -c "yarn config set registry https://registry.npm.taobao.org --global && yarn install && yarn serve"
command: bash -c "yarn install && yarn serve"
volumes:
- ../../web:/web
networks:
network:
ipv4_address: 177.7.0.11
server:
image: golang:1.18
container_name: gva-server
hostname: gva-server
restart: always
ports:
- '8888:8888'
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
volumes:
- ../../server:/server
working_dir: /server # 如果docker 设置了workdir 则此处不需要设置
command: bash -c "go env -w GOPROXY=https://goproxy.cn,direct && go mod tidy && go run main.go"
links:
- mysql
- redis
networks:
network:
ipv4_address: 177.7.0.12
mysql:
image: mysql:8.0.21 # 如果您是 arm64 架构:如 MacOS 的 M1,请修改镜像为 image: mysql/mysql-server:8.0.21
container_name: gva-mysql
hostname: gva-mysql
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci #设置utf8字符集
restart: always
ports:
- "13306:3306" # host物理直接映射端口为13306
environment:
#MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
MYSQL_USER: 'gva'
MYSQL_PASSWORD: 'Aa@6447985'
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "gva", "-pAa@6447985"]
interval: 10s
timeout: 5s
retries: 3
volumes:
- mysql:/var/lib/mysql
networks:
network:
ipv4_address: 177.7.0.13
redis:
image: redis:6.0.6
container_name: gva-redis # 容器名
hostname: gva-redis
restart: always
ports:
- '16379:6379'
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG || exit 1"]
interval: 10s
timeout: 5s
retries: 3
volumes:
- redis:/data
networks:
network:
ipv4_address: 177.7.0.14
+7
View File
@@ -13,6 +13,10 @@ RUN go env -w GO111MODULE=on \
FROM alpine:latest
LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com"
# 设置时区
ENV TZ=Asia/Shanghai
RUN apk update && apk add --no-cache tzdata openntpd \
&& ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /go/src/github.com/flipped-aurora/gin-vue-admin/server
@@ -20,5 +24,8 @@ COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/server ./
COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/resource ./resource/
COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.docker.yaml ./
# 挂载目录:如果使用了sqlite数据库,容器命令示例:docker run -d -v /宿主机路径/gva.db:/go/src/github.com/flipped-aurora/gin-vue-admin/server/gva.db -p 8888:8888 --name gva-server-v1 gva-server:1.0
# VOLUME ["/go/src/github.com/flipped-aurora/gin-vue-admin/server"]
EXPOSE 8888
ENTRYPOINT ./server -c config.docker.yaml
+2 -2
View File
@@ -5,9 +5,9 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/api/v1/system"
)
var ApiGroupApp = new(ApiGroup)
type ApiGroup struct {
SystemApiGroup system.ApiGroup
ExampleApiGroup example.ApiGroup
}
var ApiGroupApp = new(ApiGroup)
+2
View File
@@ -5,9 +5,11 @@ import "github.com/flipped-aurora/gin-vue-admin/server/service"
type ApiGroup struct {
CustomerApi
FileUploadAndDownloadApi
AttachmentCategoryApi
}
var (
customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService
fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService
attachmentCategoryService = service.ServiceGroupApp.ExampleServiceGroup.AttachmentCategoryService
)
@@ -0,0 +1,82 @@
package example
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/example"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AttachmentCategoryApi struct{}
// GetCategoryList
// @Tags GetCategoryList
// @Summary 媒体库分类列表
// @Security AttachmentCategory
// @Produce application/json
// @Success 200 {object} response.Response{data=example.ExaAttachmentCategory,msg=string} "媒体库分类列表"
// @Router /attachmentCategory/getCategoryList [get]
func (a *AttachmentCategoryApi) GetCategoryList(c *gin.Context) {
res, err := attachmentCategoryService.GetCategoryList()
if err != nil {
global.GVA_LOG.Error("获取分类列表失败!", zap.Error(err))
response.FailWithMessage("获取分类列表失败", c)
return
}
response.OkWithData(res, c)
}
// AddCategory
// @Tags AddCategory
// @Summary 添加媒体库分类
// @Security AttachmentCategory
// @accept application/json
// @Produce application/json
// @Param data body example.ExaAttachmentCategory true "媒体库分类数据"// @Success 200 {object} response.Response{msg=string} "添加媒体库分类"
// @Router /attachmentCategory/addCategory [post]
func (a *AttachmentCategoryApi) AddCategory(c *gin.Context) {
var req example.ExaAttachmentCategory
if err := c.ShouldBindJSON(&req); err != nil {
global.GVA_LOG.Error("参数错误!", zap.Error(err))
response.FailWithMessage("参数错误", c)
return
}
if err := attachmentCategoryService.AddCategory(&req); err != nil {
global.GVA_LOG.Error("创建/更新失败!", zap.Error(err))
response.FailWithMessage("创建/更新失败:"+err.Error(), c)
return
}
response.OkWithMessage("创建/更新成功", c)
}
// DeleteCategory
// @Tags DeleteCategory
// @Summary 删除分类
// @Security AttachmentCategory
// @accept application/json
// @Produce application/json
// @Param data body common.GetById true "分类id"
// @Success 200 {object} response.Response{msg=string} "删除分类"
// @Router /attachmentCategory/deleteCategory [post]
func (a *AttachmentCategoryApi) DeleteCategory(c *gin.Context) {
var req common.GetById
if err := c.ShouldBindJSON(&req); err != nil {
response.FailWithMessage("参数错误", c)
return
}
if req.ID == 0 {
response.FailWithMessage("参数错误", c)
return
}
if err := attachmentCategoryService.DeleteCategory(&req.ID); err != nil {
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
@@ -84,7 +84,7 @@ func (b *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) {
// @Produce application/json
// @Param file formData file true "Find the file, 查找文件"
// @Success 200 {object} response.Response{data=exampleRes.FileResponse,msg=string} "查找文件,返回包括文件详情"
// @Router /fileUploadAndDownload/findFile [post]
// @Router /fileUploadAndDownload/findFile [get]
func (b *FileUploadAndDownloadApi) FindFile(c *gin.Context) {
fileMd5 := c.Query("fileMd5")
fileName := c.Query("fileName")
@@ -2,12 +2,13 @@ package example
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/example"
"github.com/flipped-aurora/gin-vue-admin/server/model/example/request"
exampleRes "github.com/flipped-aurora/gin-vue-admin/server/model/example/response"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"strconv"
)
type FileUploadAndDownloadApi struct{}
@@ -25,15 +26,16 @@ func (b *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
var file example.ExaFileUploadAndDownload
noSave := c.DefaultQuery("noSave", "0")
_, header, err := c.Request.FormFile("file")
classId, _ := strconv.Atoi(c.DefaultPostForm("classId", "0"))
if err != nil {
global.GVA_LOG.Error("接收文件失败!", zap.Error(err))
response.FailWithMessage("接收文件失败", c)
return
}
file, err = fileUploadAndDownloadService.UploadFile(header, noSave) // 文件上传后拿到文件路径
file, err = fileUploadAndDownloadService.UploadFile(header, noSave, classId) // 文件上传后拿到文件路径
if err != nil {
global.GVA_LOG.Error("修改数据库链接失败!", zap.Error(err))
response.FailWithMessage("修改数据库链接失败", c)
global.GVA_LOG.Error("上传文件失败!", zap.Error(err))
response.FailWithMessage("上传文件失败", c)
return
}
response.OkWithDetailed(exampleRes.ExaFileResponse{File: file}, "上传成功", c)
@@ -85,11 +87,11 @@ func (b *FileUploadAndDownloadApi) DeleteFile(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @Param data body request.ExaAttachmentCategorySearch true "页码, 每页大小, 分类id"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页文件列表,返回包括列表,总数,页码,每页数量"
// @Router /fileUploadAndDownload/getFileList [post]
func (b *FileUploadAndDownloadApi) GetFileList(c *gin.Context) {
var pageInfo request.PageInfo
var pageInfo request.ExaAttachmentCategorySearch
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
@@ -108,3 +110,26 @@ func (b *FileUploadAndDownloadApi) GetFileList(c *gin.Context) {
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
// ImportURL
// @Tags ExaFileUploadAndDownload
// @Summary 导入URL
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body example.ExaFileUploadAndDownload true "对象"
// @Success 200 {object} response.Response{msg=string} "导入URL"
// @Router /fileUploadAndDownload/importURL [post]
func (b *FileUploadAndDownloadApi) ImportURL(c *gin.Context) {
var file []example.ExaFileUploadAndDownload
err := c.ShouldBindJSON(&file)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := fileUploadAndDownloadService.ImportURL(&file); err != nil {
global.GVA_LOG.Error("导入URL失败!", zap.Error(err))
response.FailWithMessage("导入URL失败", c)
return
}
response.OkWithMessage("导入URL成功", c)
}
@@ -2,9 +2,9 @@ package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
request "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
@@ -21,13 +21,13 @@ type AutoCodeHistoryApi struct{}
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取meta信息"
// @Router /autoCode/getMeta [post]
func (a *AutoCodeHistoryApi) First(c *gin.Context) {
var info request.GetById
var info common.GetById
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
data, err := autoCodeHistoryService.First(&info)
data, err := autoCodeHistoryService.First(c.Request.Context(), info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
@@ -45,13 +45,13 @@ func (a *AutoCodeHistoryApi) First(c *gin.Context) {
// @Success 200 {object} response.Response{msg=string} "删除回滚记录"
// @Router /autoCode/delSysHistory [post]
func (a *AutoCodeHistoryApi) Delete(c *gin.Context) {
var info request.GetById
var info common.GetById
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = autoCodeHistoryService.Delete(&info)
err = autoCodeHistoryService.Delete(c.Request.Context(), info)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
@@ -66,17 +66,17 @@ func (a *AutoCodeHistoryApi) Delete(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.RollBack true "请求参数"
// @Param data body request.SysAutoHistoryRollBack true "请求参数"
// @Success 200 {object} response.Response{msg=string} "回滚自动生成代码"
// @Router /autoCode/rollback [post]
func (a *AutoCodeHistoryApi) RollBack(c *gin.Context) {
var info systemReq.RollBack
var info request.SysAutoHistoryRollBack
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = autoCodeHistoryService.RollBack(&info)
err = autoCodeHistoryService.RollBack(c.Request.Context(), info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
@@ -90,17 +90,17 @@ func (a *AutoCodeHistoryApi) RollBack(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SysAutoHistory true "请求参数"
// @Param data body common.PageInfo true "请求参数"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "查询回滚记录,返回包括列表,总数,页码,每页数量"
// @Router /autoCode/getSysHistory [post]
func (a *AutoCodeHistoryApi) GetList(c *gin.Context) {
var search systemReq.SysAutoHistory
err := c.ShouldBindJSON(&search)
var info common.PageInfo
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := autoCodeHistoryService.GetList(search.PageInfo)
list, total, err := autoCodeHistoryService.GetList(c.Request.Context(), info)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
@@ -109,7 +109,7 @@ func (a *AutoCodeHistoryApi) GetList(c *gin.Context) {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: search.Page,
PageSize: search.PageSize,
Page: info.Page,
PageSize: info.PageSize,
}, "获取成功", c)
}
+100
View File
@@ -0,0 +1,100 @@
package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"strings"
)
type AutoCodePackageApi struct{}
// Create
// @Tags AutoCodePackage
// @Summary 创建package
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SysAutoCodePackageCreate true "创建package"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功"
// @Router /autoCode/createPackage [post]
func (a *AutoCodePackageApi) Create(c *gin.Context) {
var info request.SysAutoCodePackageCreate
_ = c.ShouldBindJSON(&info)
if err := utils.Verify(info, utils.AutoPackageVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if strings.Contains(info.PackageName, "\\") || strings.Contains(info.PackageName, "/") || strings.Contains(info.PackageName, "..") {
response.FailWithMessage("包名不合法", c)
return
} // PackageName可能导致路径穿越的问题 / 和 \ 都要防止
err := autoCodePackageService.Create(c.Request.Context(), &info)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
return
}
response.OkWithMessage("创建成功", c)
}
// Delete
// @Tags AutoCode
// @Summary 删除package
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body common.GetById true "创建package"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "删除package成功"
// @Router /autoCode/delPackage [post]
func (a *AutoCodePackageApi) Delete(c *gin.Context) {
var info common.GetById
_ = c.ShouldBindJSON(&info)
err := autoCodePackageService.Delete(c.Request.Context(), info)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
// All
// @Tags AutoCodePackage
// @Summary 获取package
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功"
// @Router /autoCode/getPackage [post]
func (a *AutoCodePackageApi) All(c *gin.Context) {
data, err := autoCodePackageService.All(c.Request.Context())
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
response.OkWithDetailed(gin.H{"pkgs": data}, "获取成功", c)
}
// Templates
// @Tags AutoCodePackage
// @Summary 获取package
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功"
// @Router /autoCode/getTemplates [get]
func (a *AutoCodePackageApi) Templates(c *gin.Context) {
data, err := autoCodePackageService.Templates(c.Request.Context())
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
response.OkWithDetailed(data, "获取成功", c)
}
+119
View File
@@ -0,0 +1,119 @@
package system
import (
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AutoCodePluginApi struct{}
// Install
// @Tags AutoCodePlugin
// @Summary 安装插件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param plug formData file true "this is a test file"
// @Success 200 {object} response.Response{data=[]interface{},msg=string} "安装插件成功"
// @Router /autoCode/installPlugin [post]
func (a *AutoCodePluginApi) Install(c *gin.Context) {
header, err := c.FormFile("plug")
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
web, server, err := autoCodePluginService.Install(header)
webStr := "web插件安装成功"
serverStr := "server插件安装成功"
if web == -1 {
webStr = "web端插件未成功安装,请按照文档自行解压安装,如果为纯后端插件请忽略此条提示"
}
if server == -1 {
serverStr = "server端插件未成功安装,请按照文档自行解压安装,如果为纯前端插件请忽略此条提示"
}
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
response.OkWithData([]interface{}{
gin.H{
"code": web,
"msg": webStr,
},
gin.H{
"code": server,
"msg": serverStr,
}}, c)
}
// Packaged
// @Tags AutoCodePlugin
// @Summary 打包插件
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param plugName query string true "插件名称"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功"
// @Router /autoCode/pubPlug [post]
func (a *AutoCodePluginApi) Packaged(c *gin.Context) {
plugName := c.Query("plugName")
zipPath, err := autoCodePluginService.PubPlug(plugName)
if err != nil {
global.GVA_LOG.Error("打包失败!", zap.Error(err))
response.FailWithMessage("打包失败"+err.Error(), c)
return
}
response.OkWithMessage(fmt.Sprintf("打包成功,文件路径为:%s", zipPath), c)
}
// InitMenu
// @Tags AutoCodePlugin
// @Summary 打包插件
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功"
// @Router /autoCode/initMenu [post]
func (a *AutoCodePluginApi) InitMenu(c *gin.Context) {
var menuInfo request.InitMenu
err := c.ShouldBindJSON(&menuInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = autoCodePluginService.InitMenu(menuInfo)
if err != nil {
global.GVA_LOG.Error("创建初始化Menu失败!", zap.Error(err))
response.FailWithMessage("创建初始化Menu失败"+err.Error(), c)
return
}
response.OkWithMessage("文件变更成功", c)
}
// InitAPI
// @Tags AutoCodePlugin
// @Summary 打包插件
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功"
// @Router /autoCode/initAPI [post]
func (a *AutoCodePluginApi) InitAPI(c *gin.Context) {
var apiInfo request.InitApi
err := c.ShouldBindJSON(&apiInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = autoCodePluginService.InitAPI(apiInfo)
if err != nil {
global.GVA_LOG.Error("创建初始化API失败!", zap.Error(err))
response.FailWithMessage("创建初始化API失败"+err.Error(), c)
return
}
response.OkWithMessage("文件变更成功", c)
}
+121
View File
@@ -0,0 +1,121 @@
package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AutoCodeTemplateApi struct{}
// Preview
// @Tags AutoCodeTemplate
// @Summary 预览创建后的代码
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.AutoCode true "预览创建代码"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "预览创建后的代码"
// @Router /autoCode/preview [post]
func (a *AutoCodeTemplateApi) Preview(c *gin.Context) {
var info request.AutoCode
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(info, utils.AutoCodeVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = info.Pretreatment()
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
info.PackageT = utils.FirstUpper(info.Package)
autoCode, err := autoCodeTemplateService.Preview(c.Request.Context(), info)
if err != nil {
global.GVA_LOG.Error(err.Error(), zap.Error(err))
response.FailWithMessage("预览失败:"+err.Error(), c)
} else {
response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c)
}
}
// Create
// @Tags AutoCodeTemplate
// @Summary 自动代码模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.AutoCode true "创建自动代码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCode/createTemp [post]
func (a *AutoCodeTemplateApi) Create(c *gin.Context) {
var info request.AutoCode
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(info, utils.AutoCodeVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = info.Pretreatment()
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = autoCodeTemplateService.Create(c.Request.Context(), info)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage(err.Error(), c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// AddFunc
// @Tags AddFunc
// @Summary 增加方法
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.AutoCode true "增加方法"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCode/addFunc [post]
func (a *AutoCodeTemplateApi) AddFunc(c *gin.Context) {
var info request.AutoFunc
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
var tempMap map[string]string
if info.IsPreview {
info.Router = "填充router"
info.FuncName = "填充funcName"
info.Method = "填充method"
info.Description = "填充description"
tempMap, err = autoCodeTemplateService.GetApiAndServer(info)
} else {
err = autoCodeTemplateService.AddFunc(info)
}
if err != nil {
global.GVA_LOG.Error("注入失败!", zap.Error(err))
response.FailWithMessage("注入失败", c)
} else {
if info.IsPreview {
response.OkWithDetailed(tempMap, "注入成功", c)
return
}
response.OkWithMessage("注入成功", c)
}
}
+14 -6
View File
@@ -14,10 +14,14 @@ type ApiGroup struct {
DictionaryApi
AuthorityMenuApi
OperationRecordApi
AutoCodeHistoryApi
DictionaryDetailApi
AuthorityBtnApi
SysExportTemplateApi
AutoCodePluginApi
AutoCodePackageApi
AutoCodeHistoryApi
AutoCodeTemplateApi
SysParamsApi
}
var (
@@ -27,13 +31,17 @@ var (
userService = service.ServiceGroupApp.SystemServiceGroup.UserService
initDBService = service.ServiceGroupApp.SystemServiceGroup.InitDBService
casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
autoCodeService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService
baseMenuService = service.ServiceGroupApp.SystemServiceGroup.BaseMenuService
authorityService = service.ServiceGroupApp.SystemServiceGroup.AuthorityService
dictionaryService = service.ServiceGroupApp.SystemServiceGroup.DictionaryService
systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService
operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService
dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService
authorityBtnService = service.ServiceGroupApp.SystemServiceGroup.AuthorityBtnService
systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService
sysParamsService = service.ServiceGroupApp.SystemServiceGroup.SysParamsService
operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService
autoCodeService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService
autoCodePluginService = service.ServiceGroupApp.SystemServiceGroup.AutoCodePlugin
autoCodePackageService = service.ServiceGroupApp.SystemServiceGroup.AutoCodePackage
autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistory
autoCodeTemplateService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeTemplate
)
+93 -1
View File
@@ -45,6 +45,97 @@ func (s *SystemApiApi) CreateApi(c *gin.Context) {
response.OkWithMessage("创建成功", c)
}
// SyncApi
// @Tags SysApi
// @Summary 同步API
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "同步API"
// @Router /api/syncApi [get]
func (s *SystemApiApi) SyncApi(c *gin.Context) {
newApis, deleteApis, ignoreApis, err := apiService.SyncApi()
if err != nil {
global.GVA_LOG.Error("同步失败!", zap.Error(err))
response.FailWithMessage("同步失败", c)
return
}
response.OkWithData(gin.H{
"newApis": newApis,
"deleteApis": deleteApis,
"ignoreApis": ignoreApis,
}, c)
}
// GetApiGroups
// @Tags SysApi
// @Summary 获取API分组
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "获取API分组"
// @Router /api/getApiGroups [get]
func (s *SystemApiApi) GetApiGroups(c *gin.Context) {
groups, apiGroupMap, err := apiService.GetApiGroups()
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
response.OkWithData(gin.H{
"groups": groups,
"apiGroupMap": apiGroupMap,
}, c)
}
// IgnoreApi
// @Tags IgnoreApi
// @Summary 忽略API
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "同步API"
// @Router /api/ignoreApi [post]
func (s *SystemApiApi) IgnoreApi(c *gin.Context) {
var ignoreApi system.SysIgnoreApi
err := c.ShouldBindJSON(&ignoreApi)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = apiService.IgnoreApi(ignoreApi)
if err != nil {
global.GVA_LOG.Error("忽略失败!", zap.Error(err))
response.FailWithMessage("忽略失败", c)
return
}
response.Ok(c)
}
// EnterSyncApi
// @Tags SysApi
// @Summary 确认同步API
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "确认同步API"
// @Router /api/enterSyncApi [post]
func (s *SystemApiApi) EnterSyncApi(c *gin.Context) {
var syncApi systemRes.SysSyncApis
err := c.ShouldBindJSON(&syncApi)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = apiService.EnterSyncApi(syncApi)
if err != nil {
global.GVA_LOG.Error("忽略失败!", zap.Error(err))
response.FailWithMessage("忽略失败", c)
return
}
response.Ok(c)
}
// DeleteApi
// @Tags SysApi
// @Summary 删除api
@@ -179,7 +270,8 @@ func (s *SystemApiApi) UpdateApi(c *gin.Context) {
// @Success 200 {object} response.Response{data=systemRes.SysAPIListResponse,msg=string} "获取所有的Api 不分页,返回包括api列表"
// @Router /api/getAllApis [post]
func (s *SystemApiApi) GetAllApis(c *gin.Context) {
apis, err := apiService.GetAllApis()
authorityID := utils.GetUserAuthorityId(c)
apis, err := apiService.GetAllApis(authorityID)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
+12 -22
View File
@@ -2,7 +2,6 @@ package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
@@ -37,6 +36,10 @@ func (a *AuthorityApi) CreateAuthority(c *gin.Context) {
return
}
if *authority.ParentId == 0 && global.GVA_CONFIG.System.UseStrictAuth {
authority.ParentId = utils.Pointer(utils.GetUserAuthorityId(c))
}
if authBack, err = authorityService.CreateAuthority(authority); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败"+err.Error(), c)
@@ -77,7 +80,8 @@ func (a *AuthorityApi) CopyAuthority(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
authBack, err := authorityService.CopyAuthority(copyInfo)
adminAuthorityID := utils.GetUserAuthorityId(c)
authBack, err := authorityService.CopyAuthority(adminAuthorityID, copyInfo)
if err != nil {
global.GVA_LOG.Error("拷贝失败!", zap.Error(err))
response.FailWithMessage("拷贝失败"+err.Error(), c)
@@ -124,7 +128,7 @@ func (a *AuthorityApi) DeleteAuthority(c *gin.Context) {
// @Produce application/json
// @Param data body system.SysAuthority true "权限id, 权限名, 父角色id"
// @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "更新角色信息,返回包括系统角色详情"
// @Router /authority/updateAuthority [post]
// @Router /authority/updateAuthority [put]
func (a *AuthorityApi) UpdateAuthority(c *gin.Context) {
var auth system.SysAuthority
err := c.ShouldBindJSON(&auth)
@@ -156,29 +160,14 @@ func (a *AuthorityApi) UpdateAuthority(c *gin.Context) {
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取角色列表,返回包括列表,总数,页码,每页数量"
// @Router /authority/getAuthorityList [post]
func (a *AuthorityApi) GetAuthorityList(c *gin.Context) {
var pageInfo request.PageInfo
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(pageInfo, utils.PageInfoVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := authorityService.GetAuthorityInfoList(pageInfo)
authorityID := utils.GetUserAuthorityId(c)
list, err := authorityService.GetAuthorityInfoList(authorityID)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败"+err.Error(), c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
response.OkWithDetailed(list, "获取成功", c)
}
// SetDataAuthority
@@ -202,7 +191,8 @@ func (a *AuthorityApi) SetDataAuthority(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
err = authorityService.SetDataAuthority(auth)
adminAuthorityID := utils.GetUserAuthorityId(c)
err = authorityService.SetDataAuthority(adminAuthorityID, auth)
if err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败"+err.Error(), c)
+58 -227
View File
@@ -1,108 +1,21 @@
package system
import (
"errors"
"fmt"
"net/url"
"os"
"github.com/flipped-aurora/gin-vue-admin/server/model/common"
"github.com/goccy/go-json"
"io"
"strings"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/flipped-aurora/gin-vue-admin/server/utils/request"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AutoCodeApi struct{}
// PreviewTemp
// @Tags AutoCode
// @Summary 预览创建后的代码
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.AutoCodeStruct true "预览创建代码"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "预览创建后的代码"
// @Router /autoCode/preview [post]
func (autoApi *AutoCodeApi) PreviewTemp(c *gin.Context) {
var a system.AutoCodeStruct
_ = c.ShouldBindJSON(&a)
if err := utils.Verify(a, utils.AutoCodeVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
a.Pretreatment() // 处理go关键字
a.PackageT = utils.FirstUpper(a.Package)
autoCode, err := autoCodeService.PreviewTemp(a)
if err != nil {
global.GVA_LOG.Error("预览失败!", zap.Error(err))
response.FailWithMessage("预览失败", c)
} else {
response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c)
}
}
// CreateTemp
// @Tags AutoCode
// @Summary 自动代码模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.AutoCodeStruct true "创建自动代码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCode/createTemp [post]
func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) {
var a system.AutoCodeStruct
_ = c.ShouldBindJSON(&a)
if err := utils.Verify(a, utils.AutoCodeVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
a.Pretreatment()
var apiIds []uint
var menuId uint
if a.AutoCreateApiToSql {
if ids, err := autoCodeService.AutoCreateApi(&a); err != nil {
global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Error(err))
c.Writer.Header().Add("success", "false")
c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
return
} else {
apiIds = ids
}
}
if a.AutoCreateMenuToSql {
if id, err := autoCodeService.AutoCreateMenu(&a); err != nil {
global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Error(err))
c.Writer.Header().Add("success", "false")
c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
} else {
menuId = id
}
}
a.PackageT = utils.FirstUpper(a.Package)
err := autoCodeService.CreateTemp(a, menuId, apiIds...)
if err != nil {
if errors.Is(err, system.ErrAutoMove) {
c.Writer.Header().Add("success", "true")
c.Writer.Header().Add("msg", url.QueryEscape(err.Error()))
} else {
c.Writer.Header().Add("success", "false")
c.Writer.Header().Add("msg", url.QueryEscape(err.Error()))
_ = os.Remove("./ginvueadmin.zip")
}
} else {
c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "ginvueadmin.zip")) // fmt.Sprintf("attachment; filename=%s", filename)对下载的文件重命名
c.Writer.Header().Add("Content-Type", "application/json")
c.Writer.Header().Add("success", "true")
c.File("./ginvueadmin.zip")
_ = os.Remove("./ginvueadmin.zip")
}
}
// GetDB
// @Tags AutoCode
// @Summary 获取当前所有数据库
@@ -110,7 +23,7 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) {
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前所有数据库"
// @Router /autoCode/getDatabase [get]
// @Router /autoCode/getDB [get]
func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
businessDB := c.Query("businessDB")
dbs, err := autoCodeService.Database(businessDB).GetDB(businessDB)
@@ -140,8 +53,19 @@ func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前数据库所有表"
// @Router /autoCode/getTables [get]
func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
dbName := c.Query("dbName")
businessDB := c.Query("businessDB")
if dbName == "" {
dbName = *global.GVA_ACTIVE_DBNAME
if businessDB != "" {
for _, db := range global.GVA_CONFIG.DBList {
if db.AliasName == businessDB {
dbName = db.Dbname
}
}
}
}
tables, err := autoCodeService.Database(businessDB).GetTables(businessDB, dbName)
if err != nil {
global.GVA_LOG.Error("查询table失败!", zap.Error(err))
@@ -161,7 +85,17 @@ func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
// @Router /autoCode/getColumn [get]
func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) {
businessDB := c.Query("businessDB")
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
dbName := c.Query("dbName")
if dbName == "" {
dbName = *global.GVA_ACTIVE_DBNAME
if businessDB != "" {
for _, db := range global.GVA_CONFIG.DBList {
if db.AliasName == businessDB {
dbName = db.Dbname
}
}
}
}
tableName := c.Query("tableName")
columns, err := autoCodeService.Database(businessDB).GetColumn(businessDB, tableName, dbName)
if err != nil {
@@ -172,153 +106,50 @@ func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) {
}
}
// CreatePackage
// @Tags AutoCode
// @Summary 创建package
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAutoCode true "创建package"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功"
// @Router /autoCode/createPackage [post]
func (autoApi *AutoCodeApi) CreatePackage(c *gin.Context) {
var a system.SysAutoCode
_ = c.ShouldBindJSON(&a)
if err := utils.Verify(a, utils.AutoPackageVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err := autoCodeService.CreateAutoCode(&a)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// GetPackage
// @Tags AutoCode
// @Summary 获取package
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建package成功"
// @Router /autoCode/getPackage [post]
func (autoApi *AutoCodeApi) GetPackage(c *gin.Context) {
pkgs, err := autoCodeService.GetPackage()
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"pkgs": pkgs}, "获取成功", c)
}
}
// DelPackage
// @Tags AutoCode
// @Summary 删除package
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAutoCode true "创建package"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "删除package成功"
// @Router /autoCode/delPackage [post]
func (autoApi *AutoCodeApi) DelPackage(c *gin.Context) {
var a system.SysAutoCode
_ = c.ShouldBindJSON(&a)
err := autoCodeService.DelPackage(a)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
}
}
// AutoPlug
// @Tags AutoCode
// @Summary 创建插件模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAutoCode true "创建插件模板"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建插件模板成功"
// @Router /autoCode/createPlug [post]
func (autoApi *AutoCodeApi) AutoPlug(c *gin.Context) {
var a system.AutoPlugReq
err := c.ShouldBindJSON(&a)
func (autoApi *AutoCodeApi) LLMAuto(c *gin.Context) {
var llm common.JSONMap
err := c.ShouldBindJSON(&llm)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
a.Snake = strings.ToLower(a.PlugName)
a.NeedModel = a.HasRequest || a.HasResponse
err = autoCodeService.CreatePlug(a)
if err != nil {
global.GVA_LOG.Error("预览失败!", zap.Error(err))
response.FailWithMessage("预览失败", c)
if global.GVA_CONFIG.AutoCode.AiPath == "" {
response.FailWithMessage("请先前往插件市场个人中心获取AiPath并填入config.yaml中", c)
return
}
response.Ok(c)
}
// InstallPlugin
// @Tags AutoCode
// @Summary 安装插件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param plug formData file true "this is a test file"
// @Success 200 {object} response.Response{data=[]interface{},msg=string} "安装插件成功"
// @Router /autoCode/installPlugin [post]
func (autoApi *AutoCodeApi) InstallPlugin(c *gin.Context) {
header, err := c.FormFile("plug")
path := strings.ReplaceAll(global.GVA_CONFIG.AutoCode.AiPath, "{FUNC}", fmt.Sprintf("api/chat/%s", llm["mode"]))
res, err := request.HttpRequest(
path,
"POST",
nil,
nil,
llm,
)
if err != nil {
response.FailWithMessage(err.Error(), c)
global.GVA_LOG.Error("大模型生成失败!", zap.Error(err))
response.FailWithMessage("大模型生成失败"+err.Error(), c)
return
}
web, server, err := autoCodeService.InstallPlugin(header)
webStr := "web插件安装成功"
serverStr := "server插件安装成功"
if web == -1 {
webStr = "web端插件未成功安装,请按照文档自行解压安装,如果为纯后端插件请忽略此条提示"
}
if server == -1 {
serverStr = "server端插件未成功安装,请按照文档自行解压安装,如果为纯前端插件请忽略此条提示"
}
var resStruct response.Response
b, err := io.ReadAll(res.Body)
defer res.Body.Close()
if err != nil {
response.FailWithMessage(err.Error(), c)
global.GVA_LOG.Error("大模型生成失败!", zap.Error(err))
response.FailWithMessage("大模型生成失败"+err.Error(), c)
return
}
err = json.Unmarshal(b, &resStruct)
if err != nil {
global.GVA_LOG.Error("大模型生成失败!", zap.Error(err))
response.FailWithMessage("大模型生成失败"+err.Error(), c)
return
}
response.OkWithData([]interface{}{
gin.H{
"code": web,
"msg": webStr,
},
gin.H{
"code": server,
"msg": serverStr,
}}, c)
}
// PubPlug
// @Tags AutoCode
// @Summary 打包插件
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAutoCode true "打包插件"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "打包插件成功"
// @Router /autoCode/pubPlug [get]
func (autoApi *AutoCodeApi) PubPlug(c *gin.Context) {
plugName := c.Query("plugName")
zipPath, err := autoCodeService.PubPlug(plugName)
if err != nil {
global.GVA_LOG.Error("打包失败!", zap.Error(err))
response.FailWithMessage("打包失败"+err.Error(), c)
if resStruct.Code == 7 {
global.GVA_LOG.Error("大模型生成失败!"+resStruct.Msg, zap.Error(err))
response.FailWithMessage("大模型生成失败"+resStruct.Msg, c)
return
}
response.OkWithMessage(fmt.Sprintf("打包成功,文件路径为:%s", zipPath), c)
response.OkWithData(resStruct.Data, c)
}
+1 -1
View File
@@ -44,7 +44,7 @@ func (b *BaseApi) Captcha(c *gin.Context) {
driver := base64Captcha.NewDriverDigit(global.GVA_CONFIG.Captcha.ImgHeight, global.GVA_CONFIG.Captcha.ImgWidth, global.GVA_CONFIG.Captcha.KeyLong, 0.7, 80)
// cp := base64Captcha.NewCaptcha(driver, store.UseWithCtx(c)) // v8下使用redis
cp := base64Captcha.NewCaptcha(driver, store)
id, b64s, err := cp.Generate()
id, b64s, _, err := cp.Generate()
if err != nil {
global.GVA_LOG.Error("验证码获取失败!", zap.Error(err))
response.FailWithMessage("验证码获取失败", c)
+2 -1
View File
@@ -33,7 +33,8 @@ func (cas *CasbinApi) UpdateCasbin(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
err = casbinService.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos)
adminAuthorityID := utils.GetUserAuthorityId(c)
err = casbinService.UpdateCasbin(adminAuthorityID, cmr.AuthorityId, cmr.CasbinInfos)
if err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
+179 -8
View File
@@ -2,6 +2,11 @@ package system
import (
"fmt"
"net/http"
"net/url"
"sync"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
@@ -11,9 +16,35 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
)
// 用于token一次性存储
var (
exportTokenCache = make(map[string]interface{})
exportTokenExpiration = make(map[string]time.Time)
tokenMutex sync.RWMutex
)
// 五分钟检测窗口过期
func cleanupExpiredTokens() {
for {
time.Sleep(5 * time.Minute)
tokenMutex.Lock()
now := time.Now()
for token, expiry := range exportTokenExpiration {
if now.After(expiry) {
delete(exportTokenCache, token)
delete(exportTokenExpiration, token)
}
}
tokenMutex.Unlock()
}
}
func init() {
go cleanupExpiredTokens()
}
type SysExportTemplateApi struct {
}
@@ -182,7 +213,7 @@ func (sysExportTemplateApi *SysExportTemplateApi) GetSysExportTemplateList(c *gi
}
}
// ExportExcel 导出表格
// ExportExcel 导出表格token
// @Tags SysExportTemplate
// @Summary 导出表格
// @Security ApiKeyAuth
@@ -191,45 +222,185 @@ func (sysExportTemplateApi *SysExportTemplateApi) GetSysExportTemplateList(c *gi
// @Router /sysExportTemplate/exportExcel [get]
func (sysExportTemplateApi *SysExportTemplateApi) ExportExcel(c *gin.Context) {
templateID := c.Query("templateID")
queryParams := c.Request.URL.Query()
if templateID == "" {
response.FailWithMessage("模板ID不能为空", c)
return
}
queryParams := c.Request.URL.Query()
//创造一次性token
token := utils.RandomString(32) // 随机32位
// 记录本次请求参数
exportParams := map[string]interface{}{
"templateID": templateID,
"queryParams": queryParams,
}
// 参数保留记录完成鉴权
tokenMutex.Lock()
exportTokenCache[token] = exportParams
exportTokenExpiration[token] = time.Now().Add(30 * time.Minute)
tokenMutex.Unlock()
// 生成一次性链接
exportUrl := fmt.Sprintf("/sysExportTemplate/exportExcelByToken?token=%s", token)
response.OkWithData(exportUrl, c)
}
// ExportExcelByToken 导出表格
// @Tags ExportExcelByToken
// @Summary 导出表格
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Router /sysExportTemplate/exportExcelByToken [get]
func (sysExportTemplateApi *SysExportTemplateApi) ExportExcelByToken(c *gin.Context) {
token := c.Query("token")
if token == "" {
response.FailWithMessage("导出token不能为空", c)
return
}
// 获取token并且从缓存中剔除
tokenMutex.RLock()
exportParamsRaw, exists := exportTokenCache[token]
expiry, _ := exportTokenExpiration[token]
tokenMutex.RUnlock()
if !exists || time.Now().After(expiry) {
global.GVA_LOG.Error("导出token无效或已过期!")
response.FailWithMessage("导出token无效或已过期", c)
return
}
// 从token获取参数
exportParams, ok := exportParamsRaw.(map[string]interface{})
if !ok {
global.GVA_LOG.Error("解析导出参数失败!")
response.FailWithMessage("解析导出参数失败", c)
return
}
// 获取导出参数
templateID := exportParams["templateID"].(string)
queryParams := exportParams["queryParams"].(url.Values)
// 清理一次性token
tokenMutex.Lock()
delete(exportTokenCache, token)
delete(exportTokenExpiration, token)
tokenMutex.Unlock()
// 导出
if file, name, err := sysExportTemplateService.ExportExcel(templateID, queryParams); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+utils.RandomString(6)+".xlsx")) // 对下载的文件重命名
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+utils.RandomString(6)+".xlsx"))
c.Header("success", "true")
c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file.Bytes())
}
}
// ExportExcel 导出表格模板
// ExportTemplate 导出表格模板
// @Tags SysExportTemplate
// @Summary 导出表格模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Router /sysExportTemplate/exportExcel [get]
// @Router /sysExportTemplate/exportTemplate [get]
func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplate(c *gin.Context) {
templateID := c.Query("templateID")
if templateID == "" {
response.FailWithMessage("模板ID不能为空", c)
return
}
// 创造一次性token
token := utils.RandomString(32) // 随机32位
// 记录本次请求参数
exportParams := map[string]interface{}{
"templateID": templateID,
"isTemplate": true,
}
// 参数保留记录完成鉴权
tokenMutex.Lock()
exportTokenCache[token] = exportParams
exportTokenExpiration[token] = time.Now().Add(30 * time.Minute)
tokenMutex.Unlock()
// 生成一次性链接
exportUrl := fmt.Sprintf("/sysExportTemplate/exportTemplateByToken?token=%s", token)
response.OkWithData(exportUrl, c)
}
// ExportTemplateByToken 通过token导出表格模板
// @Tags ExportTemplateByToken
// @Summary 通过token导出表格模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Router /sysExportTemplate/exportTemplateByToken [get]
func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplateByToken(c *gin.Context) {
token := c.Query("token")
if token == "" {
response.FailWithMessage("导出token不能为空", c)
return
}
// 获取token并且从缓存中剔除
tokenMutex.RLock()
exportParamsRaw, exists := exportTokenCache[token]
expiry, _ := exportTokenExpiration[token]
tokenMutex.RUnlock()
if !exists || time.Now().After(expiry) {
global.GVA_LOG.Error("导出token无效或已过期!")
response.FailWithMessage("导出token无效或已过期", c)
return
}
// 从token获取参数
exportParams, ok := exportParamsRaw.(map[string]interface{})
if !ok {
global.GVA_LOG.Error("解析导出参数失败!")
response.FailWithMessage("解析导出参数失败", c)
return
}
// 检查是否为模板导出
isTemplate, _ := exportParams["isTemplate"].(bool)
if !isTemplate {
global.GVA_LOG.Error("token类型错误!")
response.FailWithMessage("token类型错误", c)
return
}
// 获取导出参数
templateID := exportParams["templateID"].(string)
// 清理一次性token
tokenMutex.Lock()
delete(exportTokenCache, token)
delete(exportTokenExpiration, token)
tokenMutex.Unlock()
// 导出模板
if file, name, err := sysExportTemplateService.ExportTemplate(templateID); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+"模板.xlsx")) // 对下载的文件重命名
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+"模板.xlsx"))
c.Header("success", "true")
c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file.Bytes())
}
}
// ExportExcel 导入表格
// ImportExcel 导入表格
// @Tags SysImportTemplate
// @Summary 导入表格
// @Security ApiKeyAuth
+8 -21
View File
@@ -45,7 +45,8 @@ func (a *AuthorityMenuApi) GetMenu(c *gin.Context) {
// @Success 200 {object} response.Response{data=systemRes.SysBaseMenusResponse,msg=string} "获取用户动态路由,返回包括系统菜单列表"
// @Router /menu/getBaseMenuTree [post]
func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) {
menus, err := menuService.GetBaseMenuTree()
authority := utils.GetUserAuthorityId(c)
menus, err := menuService.GetBaseMenuTree(authority)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
@@ -74,7 +75,8 @@ func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
if err := menuService.AddMenuAuthority(authorityMenu.Menus, authorityMenu.AuthorityId); err != nil {
adminAuthorityID := utils.GetUserAuthorityId(c)
if err := menuService.AddMenuAuthority(authorityMenu.Menus, adminAuthorityID, authorityMenu.AuthorityId); err != nil {
global.GVA_LOG.Error("添加失败!", zap.Error(err))
response.FailWithMessage("添加失败", c)
} else {
@@ -171,7 +173,7 @@ func (a *AuthorityMenuApi) DeleteBaseMenu(c *gin.Context) {
err = baseMenuService.DeleteBaseMenu(menu.ID)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
response.FailWithMessage("删除失败:"+err.Error(), c)
return
}
response.OkWithMessage("删除成功", c)
@@ -252,27 +254,12 @@ func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) {
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取基础menu列表,返回包括列表,总数,页码,每页数量"
// @Router /menu/getMenuList [post]
func (a *AuthorityMenuApi) GetMenuList(c *gin.Context) {
var pageInfo request.PageInfo
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(pageInfo, utils.PageInfoVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
menuList, total, err := menuService.GetInfoList()
authorityID := utils.GetUserAuthorityId(c)
menuList, err := menuService.GetInfoList(authorityID)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
response.OkWithDetailed(response.PageResult{
List: menuList,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
response.OkWithDetailed(menuList, "获取成功", c)
}
+171
View File
@@ -0,0 +1,171 @@
package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type SysParamsApi struct{}
// CreateSysParams 创建参数
// @Tags SysParams
// @Summary 创建参数
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysParams true "创建参数"
// @Success 200 {object} response.Response{msg=string} "创建成功"
// @Router /sysParams/createSysParams [post]
func (sysParamsApi *SysParamsApi) CreateSysParams(c *gin.Context) {
var sysParams system.SysParams
err := c.ShouldBindJSON(&sysParams)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = sysParamsService.CreateSysParams(&sysParams)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败:"+err.Error(), c)
return
}
response.OkWithMessage("创建成功", c)
}
// DeleteSysParams 删除参数
// @Tags SysParams
// @Summary 删除参数
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysParams true "删除参数"
// @Success 200 {object} response.Response{msg=string} "删除成功"
// @Router /sysParams/deleteSysParams [delete]
func (sysParamsApi *SysParamsApi) DeleteSysParams(c *gin.Context) {
ID := c.Query("ID")
err := sysParamsService.DeleteSysParams(ID)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败:"+err.Error(), c)
return
}
response.OkWithMessage("删除成功", c)
}
// DeleteSysParamsByIds 批量删除参数
// @Tags SysParams
// @Summary 批量删除参数
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "批量删除成功"
// @Router /sysParams/deleteSysParamsByIds [delete]
func (sysParamsApi *SysParamsApi) DeleteSysParamsByIds(c *gin.Context) {
IDs := c.QueryArray("IDs[]")
err := sysParamsService.DeleteSysParamsByIds(IDs)
if err != nil {
global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
response.FailWithMessage("批量删除失败:"+err.Error(), c)
return
}
response.OkWithMessage("批量删除成功", c)
}
// UpdateSysParams 更新参数
// @Tags SysParams
// @Summary 更新参数
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysParams true "更新参数"
// @Success 200 {object} response.Response{msg=string} "更新成功"
// @Router /sysParams/updateSysParams [put]
func (sysParamsApi *SysParamsApi) UpdateSysParams(c *gin.Context) {
var sysParams system.SysParams
err := c.ShouldBindJSON(&sysParams)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = sysParamsService.UpdateSysParams(sysParams)
if err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败:"+err.Error(), c)
return
}
response.OkWithMessage("更新成功", c)
}
// FindSysParams 用id查询参数
// @Tags SysParams
// @Summary 用id查询参数
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query system.SysParams true "用id查询参数"
// @Success 200 {object} response.Response{data=system.SysParams,msg=string} "查询成功"
// @Router /sysParams/findSysParams [get]
func (sysParamsApi *SysParamsApi) FindSysParams(c *gin.Context) {
ID := c.Query("ID")
resysParams, err := sysParamsService.GetSysParams(ID)
if err != nil {
global.GVA_LOG.Error("查询失败!", zap.Error(err))
response.FailWithMessage("查询失败:"+err.Error(), c)
return
}
response.OkWithData(resysParams, c)
}
// GetSysParamsList 分页获取参数列表
// @Tags SysParams
// @Summary 分页获取参数列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query systemReq.SysParamsSearch true "分页获取参数列表"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "获取成功"
// @Router /sysParams/getSysParamsList [get]
func (sysParamsApi *SysParamsApi) GetSysParamsList(c *gin.Context) {
var pageInfo systemReq.SysParamsSearch
err := c.ShouldBindQuery(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := sysParamsService.GetSysParamsInfoList(pageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败:"+err.Error(), c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
// GetSysParam 根据key获取参数value
// @Tags SysParams
// @Summary 根据key获取参数value
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param key query string true "key"
// @Success 200 {object} response.Response{data=system.SysParams,msg=string} "获取成功"
// @Router /sysParams/getSysParam [get]
func (sysParamsApi *SysParamsApi) GetSysParam(c *gin.Context) {
k := c.Query("key")
params, err := sysParamsService.GetSysParam(k)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败:"+err.Error(), c)
return
}
response.OkWithDetailed(params, "获取成功", c)
}
-1
View File
@@ -6,7 +6,6 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
+43 -26
View File
@@ -5,13 +5,13 @@ import (
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
@@ -76,15 +76,7 @@ func (b *BaseApi) Login(c *gin.Context) {
// TokenNext 登录以后签发jwt
func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) {
j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
claims := j.CreateClaims(systemReq.BaseClaims{
UUID: user.UUID,
ID: user.ID,
NickName: user.NickName,
Username: user.Username,
AuthorityId: user.AuthorityId,
})
token, err := j.CreateToken(claims)
token, claims, err := utils.LoginToken(&user)
if err != nil {
global.GVA_LOG.Error("获取token失败!", zap.Error(err))
response.FailWithMessage("获取token失败", c)
@@ -122,7 +114,7 @@ func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) {
response.FailWithMessage("jwt作废失败", c)
return
}
if err := jwtService.SetRedisJWT(token, user.Username); err != nil {
if err := jwtService.SetRedisJWT(token, user.GetUsername()); err != nil {
response.FailWithMessage("设置登录状态失败", c)
return
}
@@ -207,11 +199,11 @@ func (b *BaseApi) ChangePassword(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @Param data body systemReq.GetUserList true "页码, 每页大小"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取用户列表,返回包括列表,总数,页码,每页数量"
// @Router /user/getUserList [post]
func (b *BaseApi) GetUserList(c *gin.Context) {
var pageInfo request.PageInfo
var pageInfo systemReq.GetUserList
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
@@ -264,17 +256,17 @@ func (b *BaseApi) SetUserAuthority(c *gin.Context) {
return
}
claims := utils.GetUserInfo(c)
j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
claims.AuthorityId = sua.AuthorityId
if token, err := j.CreateToken(*claims); err != nil {
token, err := utils.NewJWT().CreateToken(*claims)
if err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage(err.Error(), c)
} else {
c.Header("new-token", token)
c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt.Unix(), 10))
utils.SetToken(c, token, int((claims.ExpiresAt.Unix()-time.Now().Unix())/60))
response.OkWithMessage("修改成功", c)
return
}
c.Header("new-token", token)
c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt.Unix(), 10))
utils.SetToken(c, token, int((claims.ExpiresAt.Unix()-time.Now().Unix())/60))
response.OkWithMessage("修改成功", c)
}
// SetUserAuthorities
@@ -293,7 +285,8 @@ func (b *BaseApi) SetUserAuthorities(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
err = userService.SetUserAuthorities(sua.ID, sua.AuthorityIds)
authorityID := utils.GetUserAuthorityId(c)
err = userService.SetUserAuthorities(authorityID, sua.ID, sua.AuthorityIds)
if err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage("修改失败", c)
@@ -325,7 +318,7 @@ func (b *BaseApi) DeleteUser(c *gin.Context) {
}
jwtId := utils.GetUserID(c)
if jwtId == uint(reqId.ID) {
response.FailWithMessage("删除失败, 自杀失败", c)
response.FailWithMessage("删除失败, 无法删除自己。", c)
return
}
err = userService.DeleteUser(reqId.ID)
@@ -358,9 +351,9 @@ func (b *BaseApi) SetUserInfo(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
if len(user.AuthorityIds) != 0 {
err = userService.SetUserAuthorities(user.ID, user.AuthorityIds)
authorityID := utils.GetUserAuthorityId(c)
err = userService.SetUserAuthorities(authorityID, user.ID, user.AuthorityIds)
if err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败", c)
@@ -375,7 +368,6 @@ func (b *BaseApi) SetUserInfo(c *gin.Context) {
HeaderImg: user.HeaderImg,
Phone: user.Phone,
Email: user.Email,
SideMode: user.SideMode,
Enable: user.Enable,
})
if err != nil {
@@ -411,7 +403,6 @@ func (b *BaseApi) SetSelfInfo(c *gin.Context) {
HeaderImg: user.HeaderImg,
Phone: user.Phone,
Email: user.Email,
SideMode: user.SideMode,
Enable: user.Enable,
})
if err != nil {
@@ -422,6 +413,32 @@ func (b *BaseApi) SetSelfInfo(c *gin.Context) {
response.OkWithMessage("设置成功", c)
}
// SetSelfSetting
// @Tags SysUser
// @Summary 设置用户配置
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body map[string]interface{} true "用户配置数据"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "设置用户配置"
// @Router /user/SetSelfSetting [put]
func (b *BaseApi) SetSelfSetting(c *gin.Context) {
var req common.JSONMap
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = userService.SetSelfSetting(req, utils.GetUserID(c))
if err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败", c)
return
}
response.OkWithMessage("设置成功", c)
}
// GetUserInfo
// @Tags SysUser
// @Summary 获取用户信息
+210 -184
View File
@@ -2,150 +2,103 @@
# jwt configuration
jwt:
signing-key: qmPlus
expires-time: 7d
buffer-time: 1d
issuer: qmPlus
signing-key: qmPlus
expires-time: 7d
buffer-time: 1d
issuer: qmPlus
# zap logger configuration
zap:
level: info
format: console
prefix: "[github.com/flipped-aurora/gin-vue-admin/server]"
director: log
show-line: true
encode-level: LowercaseColorLevelEncoder
stacktrace-key: stacktrace
log-in-console: true
level: info
format: console
prefix: "[github.com/flipped-aurora/gin-vue-admin/server]"
director: log
show-line: true
encode-level: LowercaseColorLevelEncoder
stacktrace-key: stacktrace
log-in-console: true
retention-day: -1
# redis configuration
redis:
#是否使用redis集群模式
useCluster: false
#使用集群模式addr和db默认无效
addr: 127.0.0.1:6379
password: ""
db: 0
clusterAddrs:
- "172.21.0.3:7000"
- "172.21.0.4:7001"
- "172.21.0.2:7002"
#是否使用redis集群模式
useCluster: false
#使用集群模式addr和db默认无效
addr: 127.0.0.1:6379
password: ""
db: 0
clusterAddrs:
- "172.21.0.3:7000"
- "172.21.0.4:7001"
- "172.21.0.2:7002"
# redis-list configuration
redis-list:
- name: cache # 数据库的名称,注意: name 需要在 redis-list 中唯一
useCluster: false # 是否使用redis集群模式
addr: 127.0.0.1:6379 # 使用集群模式addr和db默认无效
password: ""
db: 0
clusterAddrs:
- "172.21.0.3:7000"
- "172.21.0.4:7001"
- "172.21.0.2:7002"
# mongo configuration
mongo:
coll: ''
options: ''
database: ''
username: ''
password: ''
auth-source: ''
min-pool-size: 0
max-pool-size: 100
socket-timeout-ms: 0
connect-timeout-ms: 0
is-zap: false
hosts:
- host: ''
port: ''
coll: ''
options: ''
database: ''
username: ''
password: ''
auth-source: ''
min-pool-size: 0
max-pool-size: 100
socket-timeout-ms: 0
connect-timeout-ms: 0
is-zap: false
hosts:
- host: ''
port: ''
# email configuration
email:
to: xxx@qq.com
port: 465
from: xxx@163.com
host: smtp.163.com
is-ssl: true
secret: xxx
nickname: test
to: xxx@qq.com
port: 465
from: xxx@163.com
host: smtp.163.com
is-ssl: true
secret: xxx
nickname: test
# system configuration
system:
env: local # 修改为public可以关闭路由日志输出
addr: 8888
db-type: mysql
oss-type: local # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
use-redis: false # 使用redis
use-mongo: false # 使用mongo
use-multipoint: false
# IP限制次数 一个小时15000次
iplimit-count: 15000
# IP限制一个小时
iplimit-time: 3600
# 路由全局前缀
router-prefix: ""
env: local # 修改为public可以关闭路由日志输出
addr: 8888
db-type: mysql
oss-type: local # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
use-redis: false # 使用redis
use-mongo: false # 使用mongo
use-multipoint: false
# IP限制次数 一个小时15000次
iplimit-count: 15000
# IP限制一个小时
iplimit-time: 3600
# 路由全局前缀
router-prefix: ""
# 严格角色模式 打开后权限将会存在上下级关系
use-strict-auth: false
# captcha configuration
captcha:
key-long: 6
img-width: 240
img-height: 80
open-captcha: 0 # 0代表一直开启,大于0代表限制次数
open-captcha-timeout: 3600 # open-captcha大于0时才生效
key-long: 6
img-width: 240
img-height: 80
open-captcha: 0 # 0代表一直开启,大于0代表限制次数
open-captcha-timeout: 3600 # open-captcha大于0时才生效
# mysql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
mysql:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
# pgsql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
pgsql:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
oracle:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
mssql:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
sqlite:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
db-list:
- disable: true # 是否禁用
type: "" # 数据库的类型,目前支持mysql、pgsql、mssql、oracle
alias-name: "" # 数据库的名称,注意: alias-name 需要在db-list中唯一
path: ""
port: ""
config: ""
@@ -157,95 +110,168 @@ db-list:
log-mode: ""
log-zap: false
# pgsql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
pgsql:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
oracle:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
mssql:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
sqlite:
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
db-list:
- disable: true # 是否禁用
type: "" # 数据库的类型,目前支持mysql、pgsql、mssql、oracle
alias-name: "" # 数据库的名称,注意: alias-name 需要在db-list中唯一
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
# local configuration
local:
path: uploads/file
store-path: uploads/file
path: uploads/file
store-path: uploads/file
# autocode configuration
autocode:
transfer-restart: true
# root 自动适配项目根目录
# 请不要手动配置,他会在项目加载的时候识别出根路径
root: ""
server: /server
server-plug: /plugin/%s
server-api: /api/v1/%s
server-initialize: /initialize
server-model: /model/%s
server-request: /model/%s/request/
server-router: /router/%s
server-service: /service/%s
web: /web/src
web-api: /api
web-form: /view
web-table: /view
web: web/src
root: "" # root 自动适配项目根目录, 请不要手动配置,他会在项目加载的时候识别出根路径
server: server
module: 'github.com/flipped-aurora/gin-vue-admin/server'
ai-path: "" # AI服务路径
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu:
zone: ZoneHuaDong
bucket: ""
img-path: ""
use-https: false
access-key: ""
secret-key: ""
use-cdn-domains: false
zone: ZoneHuaDong
bucket: ""
img-path: ""
use-https: false
access-key: ""
secret-key: ""
use-cdn-domains: false
# aliyun oss configuration
aliyun-oss:
# minio oss configuration
minio:
endpoint: yourEndpoint
access-key-id: yourAccessKeyId
access-key-secret: yourAccessKeySecret
bucket-name: yourBucketName
bucket-url: yourBucketUrl
base-path: yourBasePath
use-ssl: false
base-path: ""
bucket-url: "http://host:9000/yourBucketName"
# aliyun oss configuration
aliyun-oss:
endpoint: yourEndpoint
access-key-id: yourAccessKeyId
access-key-secret: yourAccessKeySecret
bucket-name: yourBucketName
bucket-url: yourBucketUrl
base-path: yourBasePath
# tencent cos configuration
tencent-cos:
bucket: xxxxx-10005608
region: ap-shanghai
secret-id: your-secret-id
secret-key: your-secret-key
base-url: https://gin.vue.admin
path-prefix: github.com/flipped-aurora/gin-vue-admin/server
bucket: xxxxx-10005608
region: ap-shanghai
secret-id: your-secret-id
secret-key: your-secret-key
base-url: https://gin.vue.admin
path-prefix: github.com/flipped-aurora/gin-vue-admin/server
# aws s3 configuration (minio compatible)
aws-s3:
bucket: xxxxx-10005608
region: ap-shanghai
endpoint: ""
s3-force-path-style: false
disable-ssl: false
secret-id: your-secret-id
secret-key: your-secret-key
base-url: https://gin.vue.admin
path-prefix: github.com/flipped-aurora/gin-vue-admin/server
bucket: xxxxx-10005608
region: ap-shanghai
endpoint: ""
s3-force-path-style: false
disable-ssl: false
secret-id: your-secret-id
secret-key: your-secret-key
base-url: https://gin.vue.admin
path-prefix: github.com/flipped-aurora/gin-vue-admin/server
# cloudflare r2 configuration
cloudflare-r2:
bucket: xxxx0bucket
base-url: https://gin.vue.admin.com
path: uploads
account-id: xxx_account_id
access-key-id: xxx_key_id
secret-access-key: xxx_secret_key
# huawei obs configuration
hua-wei-obs:
path: you-path
bucket: you-bucket
endpoint: you-endpoint
access-key: you-access-key
secret-key: you-secret-key
path: you-path
bucket: you-bucket
endpoint: you-endpoint
access-key: you-access-key
secret-key: you-secret-key
# excel configuration
excel:
dir: ./resource/excel/
dir: ./resource/excel/
# disk usage configuration
disk-list:
- mount-point: "/"
# 跨域配置
# 需要配合 server/initialize/router.go -> `Router.Use(middleware.CorsByRules())` 使用
cors:
mode: strict-whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
whitelist:
- allow-origin: example1.com
allow-headers: Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id
allow-methods: POST, GET
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type
mode: strict-whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
whitelist:
- allow-origin: example1.com
allow-headers: Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id
allow-methods: POST, GET
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type
allow-credentials: true # 布尔值
- allow-origin: example2.com
allow-headers: content-type
allow-methods: GET, POST
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type
allow-credentials: true # 布尔值
allow-credentials: true # 布尔值
- allow-origin: example2.com
allow-headers: content-type
allow-methods: GET, POST
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type
allow-credentials: true # 布尔值
+18 -14
View File
@@ -1,18 +1,22 @@
package config
import (
"path/filepath"
"strings"
)
type Autocode struct {
SModel string `mapstructure:"server-model" json:"server-model" yaml:"server-model"`
SRouter string `mapstructure:"server-router" json:"server-router" yaml:"server-router"`
Server string `mapstructure:"server" json:"server" yaml:"server"`
SApi string `mapstructure:"server-api" json:"server-api" yaml:"server-api"`
SPlug string `mapstructure:"server-plug" json:"server-plug" yaml:"server-plug"`
SInitialize string `mapstructure:"server-initialize" json:"server-initialize" yaml:"server-initialize"`
Root string `mapstructure:"root" json:"root" yaml:"root"`
WTable string `mapstructure:"web-table" json:"web-table" yaml:"web-table"`
Web string `mapstructure:"web" json:"web" yaml:"web"`
SService string `mapstructure:"server-service" json:"server-service" yaml:"server-service"`
SRequest string `mapstructure:"server-request" json:"server-request" yaml:"server-request"`
WApi string `mapstructure:"web-api" json:"web-api" yaml:"web-api"`
WForm string `mapstructure:"web-form" json:"web-form" yaml:"web-form"`
TransferRestart bool `mapstructure:"transfer-restart" json:"transfer-restart" yaml:"transfer-restart"`
Web string `mapstructure:"web" json:"web" yaml:"web"`
Root string `mapstructure:"root" json:"root" yaml:"root"`
Server string `mapstructure:"server" json:"server" yaml:"server"`
Module string `mapstructure:"module" json:"module" yaml:"module"`
AiPath string `mapstructure:"ai-path" json:"ai-path" yaml:"ai-path"`
}
func (a *Autocode) WebRoot() string {
webs := strings.Split(a.Web, "/")
if len(webs) == 0 {
webs = strings.Split(a.Web, "\\")
}
return filepath.Join(webs...)
}
+18 -13
View File
@@ -1,13 +1,14 @@
package config
type Server struct {
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
Mongo Mongo `mapstructure:"mongo" json:"mongo" yaml:"mongo"`
Email Email `mapstructure:"email" json:"email" yaml:"email"`
System System `mapstructure:"system" json:"system" yaml:"system"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
RedisList []Redis `mapstructure:"redis-list" json:"redis-list" yaml:"redis-list"`
Mongo Mongo `mapstructure:"mongo" json:"mongo" yaml:"mongo"`
Email Email `mapstructure:"email" json:"email" yaml:"email"`
System System `mapstructure:"system" json:"system" yaml:"system"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
// auto
AutoCode Autocode `mapstructure:"autocode" json:"autocode" yaml:"autocode"`
// gorm
@@ -18,15 +19,19 @@ type Server struct {
Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"`
DBList []SpecializedDB `mapstructure:"db-list" json:"db-list" yaml:"db-list"`
// oss
Local Local `mapstructure:"local" json:"local" yaml:"local"`
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyun-oss" yaml:"aliyun-oss"`
HuaWeiObs HuaWeiObs `mapstructure:"hua-wei-obs" json:"hua-wei-obs" yaml:"hua-wei-obs"`
TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencent-cos" yaml:"tencent-cos"`
AwsS3 AwsS3 `mapstructure:"aws-s3" json:"aws-s3" yaml:"aws-s3"`
Local Local `mapstructure:"local" json:"local" yaml:"local"`
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyun-oss" yaml:"aliyun-oss"`
HuaWeiObs HuaWeiObs `mapstructure:"hua-wei-obs" json:"hua-wei-obs" yaml:"hua-wei-obs"`
TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencent-cos" yaml:"tencent-cos"`
AwsS3 AwsS3 `mapstructure:"aws-s3" json:"aws-s3" yaml:"aws-s3"`
CloudflareR2 CloudflareR2 `mapstructure:"cloudflare-r2" json:"cloudflare-r2" yaml:"cloudflare-r2"`
Minio Minio `mapstructure:"minio" json:"minio" yaml:"minio"`
Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"`
DiskList []DiskList `mapstructure:"disk-list" json:"disk-list" yaml:"disk-list"`
// 跨域配置
Cors CORS `mapstructure:"cors" json:"cors" yaml:"cors"`
}
+29 -9
View File
@@ -1,5 +1,10 @@
package config
import (
"gorm.io/gorm/logger"
"strings"
)
type DsnProvider interface {
Dsn() string
}
@@ -9,21 +14,36 @@ type DsnProvider interface {
// GeneralDB 也被 Pgsql 和 Mysql 原样使用
type GeneralDB struct {
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`
Port string `mapstructure:"port" json:"port" yaml:"port"`
Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置
Dbname string `mapstructure:"db-name" json:"db-name" yaml:"db-name"` // 数据库名
Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库密码
Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
Path string `mapstructure:"path" json:"path" yaml:"path"`
Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` //数据库引擎,默认InnoDB
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` // 数据库前缀
Port string `mapstructure:"port" json:"port" yaml:"port"` // 数据库端口
Config string `mapstructure:"config" json:"config" yaml:"config"` // 高级配置
Dbname string `mapstructure:"db-name" json:"db-name" yaml:"db-name"` // 数据库名
Username string `mapstructure:"username" json:"username" yaml:"username"` // 数据库账号
Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
Path string `mapstructure:"path" json:"path" yaml:"path"` // 数据库地址
Engine string `mapstructure:"engine" json:"engine" yaml:"engine" default:"InnoDB"` // 数据库引擎,默认InnoDB
LogMode string `mapstructure:"log-mode" json:"log-mode" yaml:"log-mode"` // 是否开启Gorm全局日志
MaxIdleConns int `mapstructure:"max-idle-conns" json:"max-idle-conns" yaml:"max-idle-conns"` // 空闲中的最大连接数
MaxOpenConns int `mapstructure:"max-open-conns" json:"max-open-conns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` //是否开启全局禁用复数,true表示开启
Singular bool `mapstructure:"singular" json:"singular" yaml:"singular"` // 是否开启全局禁用复数,true表示开启
LogZap bool `mapstructure:"log-zap" json:"log-zap" yaml:"log-zap"` // 是否通过zap写入日志文件
}
func (c GeneralDB) LogLevel() logger.LogLevel {
switch strings.ToLower(c.LogMode) {
case "silent", "Silent":
return logger.Silent
case "error", "Error":
return logger.Error
case "warn", "Warn":
return logger.Warn
case "info", "Info":
return logger.Info
default:
return logger.Info
}
}
type SpecializedDB struct {
Type string `mapstructure:"type" json:"type" yaml:"type"`
AliasName string `mapstructure:"alias-name" json:"alias-name" yaml:"alias-name"`
+9
View File
@@ -0,0 +1,9 @@
package config
type Disk struct {
MountPoint string `mapstructure:"mount-point" json:"mount-point" yaml:"mount-point"`
}
type DiskList struct {
Disk `yaml:",inline" mapstructure:",squash"`
}
+2 -5
View File
@@ -3,11 +3,8 @@ package config
type Mssql struct {
GeneralDB `yaml:",inline" mapstructure:",squash"`
}
//dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
// Dsn "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
func (m *Mssql) Dsn() string {
return "sqlserver://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "?database=" + m.Dbname + "&encrypt=disable"
}
func (m *Mssql) GetLogMode() string {
return m.LogMode
}
-4
View File
@@ -7,7 +7,3 @@ type Mysql struct {
func (m *Mysql) Dsn() string {
return m.Username + ":" + m.Password + "@tcp(" + m.Path + ":" + m.Port + ")/" + m.Dbname + "?" + m.Config
}
func (m *Mysql) GetLogMode() string {
return m.LogMode
}
-4
View File
@@ -8,7 +8,3 @@ func (m *Oracle) Dsn() string {
return "oracle://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "/" + m.Dbname + "?" + m.Config
}
func (m *Oracle) GetLogMode() string {
return m.LogMode
}
-4
View File
@@ -15,7 +15,3 @@ func (p *Pgsql) Dsn() string {
func (p *Pgsql) LinkDsn(dbname string) string {
return "host=" + p.Path + " user=" + p.Username + " password=" + p.Password + " dbname=" + dbname + " port=" + p.Port + " " + p.Config
}
func (m *Pgsql) GetLogMode() string {
return m.LogMode
}
-4
View File
@@ -11,7 +11,3 @@ type Sqlite struct {
func (s *Sqlite) Dsn() string {
return filepath.Join(s.Path, s.Dbname+".db")
}
func (s *Sqlite) GetLogMode() string {
return s.LogMode
}
+10
View File
@@ -0,0 +1,10 @@
package config
type CloudflareR2 struct {
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
BaseURL string `mapstructure:"base-url" json:"base-url" yaml:"base-url"`
Path string `mapstructure:"path" json:"path" yaml:"path"`
AccountID string `mapstructure:"account-id" json:"account-id" yaml:"account-id"`
AccessKeyID string `mapstructure:"access-key-id" json:"access-key-id" yaml:"access-key-id"`
SecretAccessKey string `mapstructure:"secret-access-key" json:"secret-access-key" yaml:"secret-access-key"`
}
+11
View File
@@ -0,0 +1,11 @@
package config
type Minio struct {
Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"`
AccessKeyId string `mapstructure:"access-key-id" json:"access-key-id" yaml:"access-key-id"`
AccessKeySecret string `mapstructure:"access-key-secret" json:"access-key-secret" yaml:"access-key-secret"`
BucketName string `mapstructure:"bucket-name" json:"bucket-name" yaml:"bucket-name"`
UseSSL bool `mapstructure:"use-ssl" json:"use-ssl" yaml:"use-ssl"`
BasePath string `mapstructure:"base-path" json:"base-path" yaml:"base-path"`
BucketUrl string `mapstructure:"bucket-url" json:"bucket-url" yaml:"bucket-url"`
}
+1
View File
@@ -1,6 +1,7 @@
package config
type Redis struct {
Name string `mapstructure:"name" json:"name" yaml:"name"` // 代表当前实例的名字
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` // 服务器地址:端口
Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码
DB int `mapstructure:"db" json:"db" yaml:"db"` // 单实例模式下redis的哪个数据库
+4 -3
View File
@@ -7,7 +7,8 @@ type System struct {
Addr int `mapstructure:"addr" json:"addr" yaml:"addr"` // 端口值
LimitCountIP int `mapstructure:"iplimit-count" json:"iplimit-count" yaml:"iplimit-count"`
LimitTimeIP int `mapstructure:"iplimit-time" json:"iplimit-time" yaml:"iplimit-time"`
UseMultipoint bool `mapstructure:"use-multipoint" json:"use-multipoint" yaml:"use-multipoint"` // 多点登录拦截
UseRedis bool `mapstructure:"use-redis" json:"use-redis" yaml:"use-redis"` // 使用redis
UseMongo bool `mapstructure:"use-mongo" json:"use-mongo" yaml:"use-mongo"` // 使用mongo
UseMultipoint bool `mapstructure:"use-multipoint" json:"use-multipoint" yaml:"use-multipoint"` // 多点登录拦截
UseRedis bool `mapstructure:"use-redis" json:"use-redis" yaml:"use-redis"` // 使用redis
UseMongo bool `mapstructure:"use-mongo" json:"use-mongo" yaml:"use-mongo"` // 使用mongo
UseStrictAuth bool `mapstructure:"use-strict-auth" json:"use-strict-auth" yaml:"use-strict-auth"` // 使用树形角色分配模式
}
+46 -35
View File
@@ -2,7 +2,7 @@ package config
import (
"go.uber.org/zap/zapcore"
"strings"
"time"
)
type Zap struct {
@@ -12,49 +12,60 @@ type Zap struct {
Director string `mapstructure:"director" json:"director" yaml:"director"` // 日志文件夹
EncodeLevel string `mapstructure:"encode-level" json:"encode-level" yaml:"encode-level"` // 编码级
StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktrace-key" yaml:"stacktrace-key"` // 栈名
MaxAge int `mapstructure:"max-age" json:"max-age" yaml:"max-age"` // 日志留存时间
ShowLine bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"` // 显示行
LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台
ShowLine bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"` // 显示行
LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"` // 输出控制台
RetentionDay int `mapstructure:"retention-day" json:"retention-day" yaml:"retention-day"` // 日志保留天数
}
// ZapEncodeLevel 根据 EncodeLevel 返回 zapcore.LevelEncoder
// Levels 根据字符串转化为 zapcore.Levels
func (c *Zap) Levels() []zapcore.Level {
levels := make([]zapcore.Level, 0, 7)
level, err := zapcore.ParseLevel(c.Level)
if err != nil {
level = zapcore.DebugLevel
}
for ; level <= zapcore.FatalLevel; level++ {
levels = append(levels, level)
}
return levels
}
func (c *Zap) Encoder() zapcore.Encoder {
config := zapcore.EncoderConfig{
TimeKey: "time",
NameKey: "name",
LevelKey: "level",
CallerKey: "caller",
MessageKey: "message",
StacktraceKey: c.StacktraceKey,
LineEnding: zapcore.DefaultLineEnding,
EncodeTime: func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
encoder.AppendString(c.Prefix + t.Format("2006-01-02 15:04:05.000"))
},
EncodeLevel: c.LevelEncoder(),
EncodeCaller: zapcore.FullCallerEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
}
if c.Format == "json" {
return zapcore.NewJSONEncoder(config)
}
return zapcore.NewConsoleEncoder(config)
}
// LevelEncoder 根据 EncodeLevel 返回 zapcore.LevelEncoder
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *Zap) ZapEncodeLevel() zapcore.LevelEncoder {
func (c *Zap) LevelEncoder() zapcore.LevelEncoder {
switch {
case z.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
case c.EncodeLevel == "LowercaseLevelEncoder": // 小写编码器(默认)
return zapcore.LowercaseLevelEncoder
case z.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
case c.EncodeLevel == "LowercaseColorLevelEncoder": // 小写编码器带颜色
return zapcore.LowercaseColorLevelEncoder
case z.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
case c.EncodeLevel == "CapitalLevelEncoder": // 大写编码器
return zapcore.CapitalLevelEncoder
case z.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
case c.EncodeLevel == "CapitalColorLevelEncoder": // 大写编码器带颜色
return zapcore.CapitalColorLevelEncoder
default:
return zapcore.LowercaseLevelEncoder
}
}
// TransportLevel 根据字符串转化为 zapcore.Level
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *Zap) TransportLevel() zapcore.Level {
z.Level = strings.ToLower(z.Level)
switch z.Level {
case "debug":
return zapcore.DebugLevel
case "info":
return zapcore.InfoLevel
case "warn":
return zapcore.WarnLevel
case "error":
return zapcore.ErrorLevel
case "dpanic":
return zapcore.DPanicLevel
case "panic":
return zapcore.PanicLevel
case "fatal":
return zapcore.FatalLevel
default:
return zapcore.DebugLevel
}
}
+70 -46
View File
@@ -3,34 +3,46 @@ package internal
import (
"os"
"path/filepath"
"regexp"
"strings"
"sync"
"time"
)
// Cutter 实现 io.Writer 接口
// 用于日志切割, strings.Join([]string{director,layout, formats..., level+".log"}, os.PathSeparator)
type Cutter struct {
level string // 日志级别(debug, info, warn, error, dpanic, panic, fatal)
format string // 时间格式(2006-01-02)
Director string // 日志文件夹
file *os.File // 文件句柄
mutex *sync.RWMutex // 读写锁
level string // 日志级别(debug, info, warn, error, dpanic, panic, fatal)
layout string // 时间格式 2006-01-02 15:04:05
formats []string // 自定义参数([]string{Director,"2006-01-02", "business"(此参数可不写), level+".log"}
director string // 日志文件夹
retentionDay int //日志保留天数
file *os.File // 文件句柄
mutex *sync.RWMutex // 读写锁
}
type CutterOption func(*Cutter)
// WithCutterFormat 设置时间格式
func WithCutterFormat(format string) CutterOption {
// CutterWithLayout 时间格式
func CutterWithLayout(layout string) CutterOption {
return func(c *Cutter) {
c.format = format
c.layout = layout
}
}
func NewCutter(director string, level string, options ...CutterOption) *Cutter {
// CutterWithFormats 格式化参数
func CutterWithFormats(format ...string) CutterOption {
return func(c *Cutter) {
if len(format) > 0 {
c.formats = format
}
}
}
func NewCutter(director string, level string, retentionDay int, options ...CutterOption) *Cutter {
rotate := &Cutter{
level: level,
Director: director,
mutex: new(sync.RWMutex),
level: level,
director: director,
retentionDay: retentionDay,
mutex: new(sync.RWMutex),
}
for i := 0; i < len(options); i++ {
options[i](rotate)
@@ -51,41 +63,23 @@ func (c *Cutter) Write(bytes []byte) (n int, err error) {
}
c.mutex.Unlock()
}()
var business string
if strings.Contains(string(bytes), "business") {
var compile *regexp.Regexp
compile, err = regexp.Compile(`{"business": "([^,]+)"}`)
if err != nil {
return 0, err
}
if compile.Match(bytes) {
finds := compile.FindSubmatch(bytes)
business = string(finds[len(finds)-1])
bytes = compile.ReplaceAll(bytes, []byte(""))
}
compile, err = regexp.Compile(`"business": "([^,]+)"`)
if err != nil {
return 0, err
}
if compile.Match(bytes) {
finds := compile.FindSubmatch(bytes)
business = string(finds[len(finds)-1])
bytes = compile.ReplaceAll(bytes, []byte(""))
}
length := len(c.formats)
values := make([]string, 0, 3+length)
values = append(values, c.director)
if c.layout != "" {
values = append(values, time.Now().Format(c.layout))
}
format := time.Now().Format(c.format)
formats := make([]string, 0, 4)
formats = append(formats, c.Director)
if format != "" {
formats = append(formats, format)
for i := 0; i < length; i++ {
values = append(values, c.formats[i])
}
if business != "" {
formats = append(formats, business)
values = append(values, c.level+".log")
filename := filepath.Join(values...)
director := filepath.Dir(filename)
err = os.MkdirAll(director, os.ModePerm)
if err != nil {
return 0, err
}
formats = append(formats, c.level+".log")
filename := filepath.Join(formats...)
dirname := filepath.Dir(filename)
err = os.MkdirAll(dirname, 0755)
err = removeNDaysFolders(c.director, c.retentionDay)
if err != nil {
return 0, err
}
@@ -95,3 +89,33 @@ func (c *Cutter) Write(bytes []byte) (n int, err error) {
}
return c.file.Write(bytes)
}
func (c *Cutter) Sync() error {
c.mutex.Lock()
defer c.mutex.Unlock()
if c.file != nil {
return c.file.Sync()
}
return nil
}
// 增加日志目录文件清理 小于等于零的值默认忽略不再处理
func removeNDaysFolders(dir string, days int) error {
if days <= 0 {
return nil
}
cutoff := time.Now().AddDate(0, 0, -days)
return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() && info.ModTime().Before(cutoff) && path != dir {
err = os.RemoveAll(path)
if err != nil {
return err
}
}
return nil
})
}
-21
View File
@@ -1,21 +0,0 @@
package internal
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"go.uber.org/zap/zapcore"
"os"
)
var FileRotatelogs = new(fileRotatelogs)
type fileRotatelogs struct{}
// GetWriteSyncer 获取 zapcore.WriteSyncer
// Author [SliverHorn](https://github.com/SliverHorn)
func (r *fileRotatelogs) GetWriteSyncer(level string) zapcore.WriteSyncer {
fileWriter := NewCutter(global.GVA_CONFIG.Zap.Director, level, WithCutterFormat("2006-01-02"))
if global.GVA_CONFIG.Zap.LogInConsole {
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter))
}
return zapcore.AddSync(fileWriter)
}
-101
View File
@@ -1,101 +0,0 @@
package internal
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"time"
)
var Zap = new(_zap)
type _zap struct{}
// GetEncoder 获取 zapcore.Encoder
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *_zap) GetEncoder() zapcore.Encoder {
if global.GVA_CONFIG.Zap.Format == "json" {
return zapcore.NewJSONEncoder(z.GetEncoderConfig())
}
return zapcore.NewConsoleEncoder(z.GetEncoderConfig())
}
// GetEncoderConfig 获取zapcore.EncoderConfig
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *_zap) GetEncoderConfig() zapcore.EncoderConfig {
return zapcore.EncoderConfig{
MessageKey: "message",
LevelKey: "level",
TimeKey: "time",
NameKey: "logger",
CallerKey: "caller",
StacktraceKey: global.GVA_CONFIG.Zap.StacktraceKey,
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: global.GVA_CONFIG.Zap.ZapEncodeLevel(),
EncodeTime: z.CustomTimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.FullCallerEncoder,
}
}
// GetEncoderCore 获取Encoder的 zapcore.Core
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *_zap) GetEncoderCore(l zapcore.Level, level zap.LevelEnablerFunc) zapcore.Core {
writer := FileRotatelogs.GetWriteSyncer(l.String()) // 日志分割
return zapcore.NewCore(z.GetEncoder(), writer, level)
}
// CustomTimeEncoder 自定义日志输出时间格式
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *_zap) CustomTimeEncoder(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
encoder.AppendString(global.GVA_CONFIG.Zap.Prefix + t.Format("2006/01/02 - 15:04:05.000"))
}
// GetZapCores 根据配置文件的Level获取 []zapcore.Core
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *_zap) GetZapCores() []zapcore.Core {
cores := make([]zapcore.Core, 0, 7)
for level := global.GVA_CONFIG.Zap.TransportLevel(); level <= zapcore.FatalLevel; level++ {
cores = append(cores, z.GetEncoderCore(level, z.GetLevelPriority(level)))
}
return cores
}
// GetLevelPriority 根据 zapcore.Level 获取 zap.LevelEnablerFunc
// Author [SliverHorn](https://github.com/SliverHorn)
func (z *_zap) GetLevelPriority(level zapcore.Level) zap.LevelEnablerFunc {
switch level {
case zapcore.DebugLevel:
return func(level zapcore.Level) bool { // 调试级别
return level == zap.DebugLevel
}
case zapcore.InfoLevel:
return func(level zapcore.Level) bool { // 日志级别
return level == zap.InfoLevel
}
case zapcore.WarnLevel:
return func(level zapcore.Level) bool { // 警告级别
return level == zap.WarnLevel
}
case zapcore.ErrorLevel:
return func(level zapcore.Level) bool { // 错误级别
return level == zap.ErrorLevel
}
case zapcore.DPanicLevel:
return func(level zapcore.Level) bool { // dpanic级别
return level == zap.DPanicLevel
}
case zapcore.PanicLevel:
return func(level zapcore.Level) bool { // panic级别
return level == zap.PanicLevel
}
case zapcore.FatalLevel:
return func(level zapcore.Level) bool { // 终止级别
return level == zap.FatalLevel
}
default:
return func(level zapcore.Level) bool { // 调试级别
return level == zap.DebugLevel
}
}
}
+68
View File
@@ -0,0 +1,68 @@
package internal
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"time"
)
type ZapCore struct {
level zapcore.Level
zapcore.Core
}
func NewZapCore(level zapcore.Level) *ZapCore {
entity := &ZapCore{level: level}
syncer := entity.WriteSyncer()
levelEnabler := zap.LevelEnablerFunc(func(l zapcore.Level) bool {
return l == level
})
entity.Core = zapcore.NewCore(global.GVA_CONFIG.Zap.Encoder(), syncer, levelEnabler)
return entity
}
func (z *ZapCore) WriteSyncer(formats ...string) zapcore.WriteSyncer {
cutter := NewCutter(
global.GVA_CONFIG.Zap.Director,
z.level.String(),
global.GVA_CONFIG.Zap.RetentionDay,
CutterWithLayout(time.DateOnly),
CutterWithFormats(formats...),
)
if global.GVA_CONFIG.Zap.LogInConsole {
multiSyncer := zapcore.NewMultiWriteSyncer(os.Stdout, cutter)
return zapcore.AddSync(multiSyncer)
}
return zapcore.AddSync(cutter)
}
func (z *ZapCore) Enabled(level zapcore.Level) bool {
return z.level == level
}
func (z *ZapCore) With(fields []zapcore.Field) zapcore.Core {
return z.Core.With(fields)
}
func (z *ZapCore) Check(entry zapcore.Entry, check *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if z.Enabled(entry.Level) {
return check.AddCore(entry, z)
}
return check
}
func (z *ZapCore) Write(entry zapcore.Entry, fields []zapcore.Field) error {
for i := 0; i < len(fields); i++ {
if fields[i].Key == "business" || fields[i].Key == "folder" || fields[i].Key == "directory" {
syncer := z.WriteSyncer(fields[i].String)
z.Core = zapcore.NewCore(global.GVA_CONFIG.Zap.Encoder(), syncer, z.level)
}
}
return z.Core.Write(entry, fields)
}
func (z *ZapCore) Sync() error {
return z.Core.Sync()
}
+9 -4
View File
@@ -16,7 +16,9 @@ func RunWindowsServer() {
if global.GVA_CONFIG.System.UseMultipoint || global.GVA_CONFIG.System.UseRedis {
// 初始化redis服务
initialize.Redis()
initialize.RedisList()
}
if global.GVA_CONFIG.System.UseMongo {
err := initialize.Mongo.Initialization()
if err != nil {
@@ -29,7 +31,6 @@ func RunWindowsServer() {
}
Router := initialize.Routers()
Router.Static("/form-generator", "./resource/page")
address := fmt.Sprintf(":%d", global.GVA_CONFIG.System.Addr)
s := initServer(address, Router)
@@ -38,13 +39,17 @@ func RunWindowsServer() {
fmt.Printf(`
欢迎使用 gin-vue-admin
当前版本:v2.6.2
加群方式:微信号:shouzi_1994 QQ群:470239250
当前版本:v2.8.0
加群方式:微信号:shouzi_1994 QQ群:470239250
项目地址:https://github.com/flipped-aurora/gin-vue-admin
插件市场:https://plugin.gin-vue-admin.com
GVA讨论社区:https://support.qq.com/products/371961
默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
默认前端文件运行地址:http://127.0.0.1:8080
如果项目让您获得了收益,希望您能请团队喝杯可乐:https://www.gin-vue-admin.com/coffee/index.html
--------------------------------------版权声明--------------------------------------
** 版权所有方:flipped-aurora开源团队 **
** 版权持有公司:北京翻转极光科技有限责任公司 **
** 剔除授权标识需购买商用授权:https://gin-vue-admin.com/empower/index.html **
`, address)
global.GVA_LOG.Error(s.ListenAndServe().Error())
}
+2 -2
View File
@@ -12,8 +12,8 @@ import (
func initServer(address string, router *gin.Engine) server {
s := endless.NewServer(address, router)
s.ReadHeaderTimeout = 20 * time.Second
s.WriteTimeout = 20 * time.Second
s.ReadHeaderTimeout = 10 * time.Minute
s.WriteTimeout = 10 * time.Minute
s.MaxHeaderBytes = 1 << 20
return s
}
+2 -2
View File
@@ -14,8 +14,8 @@ func initServer(address string, router *gin.Engine) server {
return &http.Server{
Addr: address,
Handler: router,
ReadTimeout: 20 * time.Second,
WriteTimeout: 20 * time.Second,
ReadTimeout: 10 * time.Minute,
WriteTimeout: 10 * time.Minute,
MaxHeaderBytes: 1 << 20,
}
}
+1 -4
View File
@@ -12,7 +12,6 @@ import (
"github.com/spf13/viper"
"github.com/flipped-aurora/gin-vue-admin/server/global"
_ "github.com/flipped-aurora/gin-vue-admin/server/packfile"
)
// Viper //
@@ -29,14 +28,12 @@ func Viper(path ...string) *viper.Viper {
switch gin.Mode() {
case gin.DebugMode:
config = internal.ConfigDefaultFile
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigDefaultFile)
case gin.ReleaseMode:
config = internal.ConfigReleaseFile
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigReleaseFile)
case gin.TestMode:
config = internal.ConfigTestFile
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), internal.ConfigTestFile)
}
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), config)
} else { // internal.ConfigEnv 常量存储的环境变量不为空 将值赋值于config
config = configEnv
fmt.Printf("您正在使用%s环境变量,config的路径为%s\n", internal.ConfigEnv, config)
+7 -3
View File
@@ -17,10 +17,14 @@ func Zap() (logger *zap.Logger) {
fmt.Printf("create %v directory\n", global.GVA_CONFIG.Zap.Director)
_ = os.Mkdir(global.GVA_CONFIG.Zap.Director, os.ModePerm)
}
cores := internal.Zap.GetZapCores()
levels := global.GVA_CONFIG.Zap.Levels()
length := len(levels)
cores := make([]zapcore.Core, 0, length)
for i := 0; i < length; i++ {
core := internal.NewZapCore(levels[i])
cores = append(cores, core)
}
logger = zap.New(zapcore.NewTee(cores...))
if global.GVA_CONFIG.Zap.ShowLine {
logger = logger.WithOptions(zap.AddCaller())
}
+2573 -280
View File
File diff suppressed because it is too large Load Diff
+2572 -278
View File
File diff suppressed because it is too large Load Diff
+1606 -208
View File
File diff suppressed because it is too large Load Diff
+23 -10
View File
@@ -1,9 +1,12 @@
package global
import (
"github.com/qiniu/qmgo"
"fmt"
"sync"
"github.com/gin-gonic/gin"
"github.com/qiniu/qmgo"
"github.com/flipped-aurora/gin-vue-admin/server/utils/timer"
"github.com/songzhibin97/gkit/cache/local_cache"
@@ -19,19 +22,21 @@ import (
)
var (
GVA_DB *gorm.DB
GVA_DBList map[string]*gorm.DB
GVA_REDIS redis.UniversalClient
GVA_MONGO *qmgo.QmgoClient
GVA_CONFIG config.Server
GVA_VP *viper.Viper
GVA_DB *gorm.DB
GVA_DBList map[string]*gorm.DB
GVA_REDIS redis.UniversalClient
GVA_REDISList map[string]redis.UniversalClient
GVA_MONGO *qmgo.QmgoClient
GVA_CONFIG config.Server
GVA_VP *viper.Viper
// GVA_LOG *oplogging.Logger
GVA_LOG *zap.Logger
GVA_Timer timer.Timer = timer.NewTimerTask()
GVA_Concurrency_Control = &singleflight.Group{}
BlackCache local_cache.Cache
lock sync.RWMutex
GVA_ROUTERS gin.RoutesInfo
GVA_ACTIVE_DBNAME *string
BlackCache local_cache.Cache
lock sync.RWMutex
)
// GetGlobalDBByDBName 通过名称获取db list中的db
@@ -51,3 +56,11 @@ func MustGetGlobalDBByDBName(dbname string) *gorm.DB {
}
return db
}
func GetRedis(name string) redis.UniversalClient {
redis, ok := GVA_REDISList[name]
if !ok || redis == nil {
panic(fmt.Sprintf("redis `%s` no init", name))
}
return redis
}
+133 -98
View File
@@ -1,142 +1,177 @@
module github.com/flipped-aurora/gin-vue-admin/server
go 1.20
go 1.22.2
require (
github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible
github.com/aws/aws-sdk-go v1.44.307
github.com/casbin/casbin/v2 v2.71.1
github.com/casbin/gorm-adapter/v3 v3.18.0
github.com/flipped-aurora/ws v1.0.2
github.com/fsnotify/fsnotify v1.6.0
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/aws/aws-sdk-go v1.55.6
github.com/casbin/casbin/v2 v2.103.0
github.com/casbin/gorm-adapter/v3 v3.32.0
github.com/fsnotify/fsnotify v1.8.0
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
github.com/gin-gonic/gin v1.9.1
github.com/glebarez/sqlite v1.8.0
github.com/go-sql-driver/mysql v1.7.1
github.com/gofrs/uuid/v5 v5.0.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/gin-gonic/gin v1.10.0
github.com/glebarez/sqlite v1.11.0
github.com/go-sql-driver/mysql v1.8.1
github.com/goccy/go-json v0.10.4
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/uuid v1.6.0
github.com/gookit/color v1.5.4
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible
github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84
github.com/mojocn/base64Captcha v1.3.5
github.com/otiai10/copy v1.7.0
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
github.com/mholt/archiver/v4 v4.0.0-alpha.9
github.com/minio/minio-go/v7 v7.0.84
github.com/mojocn/base64Captcha v1.3.8
github.com/otiai10/copy v1.14.1
github.com/pkg/errors v0.9.1
github.com/qiniu/api.v7/v7 v7.4.1
github.com/qiniu/qmgo v1.1.8
github.com/redis/go-redis/v9 v9.0.5
github.com/qiniu/go-sdk/v7 v7.25.2
github.com/qiniu/qmgo v1.1.9
github.com/redis/go-redis/v9 v9.7.0
github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil/v3 v3.23.6
github.com/songzhibin97/gkit v1.2.11
github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.4
github.com/shirou/gopsutil/v3 v3.24.5
github.com/songzhibin97/gkit v1.2.13
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.10.0
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.2
github.com/tencentyun/cos-go-sdk-v5 v0.7.42
github.com/unrolled/secure v1.13.0
github.com/xuri/excelize/v2 v2.8.0
go.mongodb.org/mongo-driver v1.12.1
go.uber.org/automaxprocs v1.5.3
go.uber.org/zap v1.24.0
golang.org/x/crypto v0.16.0
golang.org/x/sync v0.5.0
golang.org/x/text v0.14.0
gorm.io/driver/mysql v1.5.6
gorm.io/driver/postgres v1.5.2
gorm.io/driver/sqlserver v1.5.1
gorm.io/gorm v1.25.7
nhooyr.io/websocket v1.8.7
github.com/swaggo/swag v1.16.4
github.com/tencentyun/cos-go-sdk-v5 v0.7.60
github.com/unrolled/secure v1.17.0
github.com/xuri/excelize/v2 v2.9.0
go.mongodb.org/mongo-driver v1.17.2
go.uber.org/automaxprocs v1.6.0
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.32.0
golang.org/x/sync v0.10.0
golang.org/x/text v0.21.0
gorm.io/datatypes v1.2.5
gorm.io/driver/mysql v1.5.7
gorm.io/driver/postgres v1.5.11
gorm.io/driver/sqlserver v1.5.4
gorm.io/gen v0.3.26
gorm.io/gorm v1.25.12
)
require (
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/STARRY-S/zip v0.1.0 // indirect
github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/bmatcuk/doublestar/v4 v4.8.0 // indirect
github.com/bodgit/plumbing v1.3.0 // indirect
github.com/bodgit/sevenzip v1.6.0 // indirect
github.com/bodgit/windows v1.0.1 // indirect
github.com/bytedance/sonic v1.12.7 // indirect
github.com/bytedance/sonic/loader v0.2.3 // indirect
github.com/casbin/govaluate v1.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clbanning/mxj v1.8.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/glebarez/go-sqlite v1.21.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.3 // indirect
github.com/go-openapi/spec v0.20.12 // indirect
github.com/go-openapi/swag v0.22.5 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gammazero/toposort v0.1.1 // indirect
github.com/gin-contrib/sse v1.0.0 // indirect
github.com/glebarez/go-sqlite v1.22.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/go-playground/validator/v10 v10.24.0 // indirect
github.com/gofrs/flock v0.12.1 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.3.1 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.7.2 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/microsoft/go-mssqldb v1.1.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect
github.com/magiconair/properties v1.8.9 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/microsoft/go-mssqldb v1.8.0 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/montanaflynn/stats v0.7.0 // indirect
github.com/mozillazg/go-httpheader v0.2.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/mozillazg/go-httpheader v0.4.0 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/nwaples/rardecode/v2 v2.0.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.3 // indirect
github.com/richardlehane/msoleps v1.0.4 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/sorairolake/lzip-go v0.3.5 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.12.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/therootcompany/xz v1.0.1 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.9.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca // indirect
github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/image v0.11.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/time v0.1.0 // indirect
golang.org/x/tools v0.16.1 // indirect
google.golang.org/protobuf v1.30.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/xuri/efp v0.0.0-20241211021726-c4e992084aa6 // indirect
github.com/xuri/nfp v0.0.0-20250111060730-82a408b9aa71 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/multierr v1.11.0 // indirect
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/arch v0.13.0 // indirect
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
golang.org/x/image v0.23.0 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.29.0 // indirect
google.golang.org/protobuf v1.36.3 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/plugin/dbresolver v1.4.1 // indirect
modernc.org/libc v1.24.1 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.6.0 // indirect
modernc.org/sqlite v1.23.0 // indirect
gorm.io/hints v1.1.2 // indirect
gorm.io/plugin/dbresolver v1.5.3 // indirect
modernc.org/fileutil v1.3.0 // indirect
modernc.org/libc v1.61.9 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.8.2 // indirect
modernc.org/sqlite v1.34.5 // indirect
)
+419 -468
View File
File diff suppressed because it is too large Load Diff
+13 -3
View File
@@ -5,6 +5,7 @@ import (
adapter "github.com/casbin/gorm-adapter/v3"
"github.com/flipped-aurora/gin-vue-admin/server/model/example"
sysModel "github.com/flipped-aurora/gin-vue-admin/server/model/system"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/model"
"github.com/flipped-aurora/gin-vue-admin/server/service/system"
"gorm.io/gorm"
)
@@ -18,7 +19,7 @@ func init() {
system.RegisterInit(initOrderEnsureTables, &ensureTables{})
}
func (ensureTables) InitializerName() string {
func (e *ensureTables) InitializerName() string {
return "ensure_tables_created"
}
func (e *ensureTables) InitializeData(ctx context.Context) (next context.Context, err error) {
@@ -47,9 +48,11 @@ func (e *ensureTables) MigrateTable(ctx context.Context) (context.Context, error
sysModel.SysBaseMenuParameter{},
sysModel.SysBaseMenuBtn{},
sysModel.SysAuthorityBtn{},
sysModel.SysAutoCode{},
sysModel.SysAutoCodePackage{},
sysModel.SysExportTemplate{},
sysModel.Condition{},
sysModel.JoinTemplate{},
sysModel.SysParams{},
adapter.CasbinRule{},
@@ -57,6 +60,9 @@ func (e *ensureTables) MigrateTable(ctx context.Context) (context.Context, error
example.ExaCustomer{},
example.ExaFileChunk{},
example.ExaFileUploadAndDownload{},
example.ExaAttachmentCategory{},
model.Info{},
}
for _, t := range tables {
_ = db.AutoMigrate(&t)
@@ -84,9 +90,10 @@ func (e *ensureTables) TableCreated(ctx context.Context) bool {
sysModel.SysBaseMenuParameter{},
sysModel.SysBaseMenuBtn{},
sysModel.SysAuthorityBtn{},
sysModel.SysAutoCode{},
sysModel.SysAutoCodePackage{},
sysModel.SysExportTemplate{},
sysModel.Condition{},
sysModel.JoinTemplate{},
adapter.CasbinRule{},
@@ -94,6 +101,9 @@ func (e *ensureTables) TableCreated(ctx context.Context) bool {
example.ExaCustomer{},
example.ExaFileChunk{},
example.ExaFileUploadAndDownload{},
example.ExaAttachmentCategory{},
model.Info{},
}
yes := true
for _, t := range tables {
+18 -1
View File
@@ -14,16 +14,22 @@ import (
func Gorm() *gorm.DB {
switch global.GVA_CONFIG.System.DbType {
case "mysql":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mysql.Dbname
return GormMysql()
case "pgsql":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Pgsql.Dbname
return GormPgSql()
case "oracle":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Oracle.Dbname
return GormOracle()
case "mssql":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mssql.Dbname
return GormMssql()
case "sqlite":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Sqlite.Dbname
return GormSqlite()
default:
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mysql.Dbname
return GormMysql()
}
}
@@ -33,6 +39,7 @@ func RegisterTables() {
err := db.AutoMigrate(
system.SysApi{},
system.SysIgnoreApi{},
system.SysUser{},
system.SysBaseMenu{},
system.JwtBlacklist{},
@@ -44,18 +51,28 @@ func RegisterTables() {
system.SysBaseMenuParameter{},
system.SysBaseMenuBtn{},
system.SysAuthorityBtn{},
system.SysAutoCode{},
system.SysAutoCodePackage{},
system.SysExportTemplate{},
system.Condition{},
system.JoinTemplate{},
system.SysParams{},
example.ExaFile{},
example.ExaCustomer{},
example.ExaFileChunk{},
example.ExaFileUploadAndDownload{},
example.ExaAttachmentCategory{},
)
if err != nil {
global.GVA_LOG.Error("register table failed", zap.Error(err))
os.Exit(0)
}
err = bizModel()
if err != nil {
global.GVA_LOG.Error("register biz_table failed", zap.Error(err))
os.Exit(0)
}
global.GVA_LOG.Info("register table success")
}
+14
View File
@@ -0,0 +1,14 @@
package initialize
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
)
func bizModel() error {
db := global.GVA_DB
err := db.AutoMigrate()
if err != nil {
return err
}
return nil
}
+4 -3
View File
@@ -1,3 +1,5 @@
package initialize
/*
* @Author: 逆光飞翔 191180776@qq.com
* @Date: 2022-12-08 17:25:49
@@ -6,7 +8,6 @@
* @FilePath: \server\initialize\gorm_mssql.go
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
package initialize
import (
"github.com/flipped-aurora/gin-vue-admin/server/config"
@@ -44,8 +45,8 @@ func GormMssqlByConfig(m config.Mssql) *gorm.DB {
return nil
}
mssqlConfig := sqlserver.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
panic(err)
+24 -40
View File
@@ -1,20 +1,14 @@
package internal
import (
"gorm.io/gorm/schema"
"log"
"os"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"time"
)
type DBBASE interface {
GetLogMode() string
}
var Gorm = new(_gorm)
type _gorm struct{}
@@ -22,41 +16,31 @@ type _gorm struct{}
// Config gorm 自定义配置
// Author [SliverHorn](https://github.com/SliverHorn)
func (g *_gorm) Config(prefix string, singular bool) *gorm.Config {
config := &gorm.Config{
var general config.GeneralDB
switch global.GVA_CONFIG.System.DbType {
case "mysql":
general = global.GVA_CONFIG.Mysql.GeneralDB
case "pgsql":
general = global.GVA_CONFIG.Pgsql.GeneralDB
case "oracle":
general = global.GVA_CONFIG.Oracle.GeneralDB
case "sqlite":
general = global.GVA_CONFIG.Sqlite.GeneralDB
case "mssql":
general = global.GVA_CONFIG.Mssql.GeneralDB
default:
general = global.GVA_CONFIG.Mysql.GeneralDB
}
return &gorm.Config{
Logger: logger.New(NewWriter(general), logger.Config{
SlowThreshold: 200 * time.Millisecond,
LogLevel: general.LogLevel(),
Colorful: true,
}),
NamingStrategy: schema.NamingStrategy{
TablePrefix: prefix,
SingularTable: singular,
},
DisableForeignKeyConstraintWhenMigrating: true,
}
_default := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{
SlowThreshold: 200 * time.Millisecond,
LogLevel: logger.Warn,
Colorful: true,
})
var logMode DBBASE
switch global.GVA_CONFIG.System.DbType {
case "mysql":
logMode = &global.GVA_CONFIG.Mysql
case "pgsql":
logMode = &global.GVA_CONFIG.Pgsql
case "oracle":
logMode = &global.GVA_CONFIG.Oracle
default:
logMode = &global.GVA_CONFIG.Mysql
}
switch logMode.GetLogMode() {
case "silent", "Silent":
config.Logger = _default.LogMode(logger.Silent)
case "error", "Error":
config.Logger = _default.LogMode(logger.Error)
case "warn", "Warn":
config.Logger = _default.LogMode(logger.Warn)
case "info", "Info":
config.Logger = _default.LogMode(logger.Info)
default:
config.Logger = _default.LogMode(logger.Info)
}
return config
}
@@ -0,0 +1,41 @@
package internal
import (
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"gorm.io/gorm/logger"
)
type Writer struct {
config config.GeneralDB
writer logger.Writer
}
func NewWriter(config config.GeneralDB) *Writer {
return &Writer{config: config}
}
// Printf 格式化打印日志
func (c *Writer) Printf(message string, data ...any) {
// 当有日志时候均需要输出到控制台
fmt.Printf(message, data...)
// 当开启了zap的情况,会打印到日志记录
if c.config.LogZap {
switch c.config.LogLevel() {
case logger.Silent:
global.GVA_LOG.Debug(fmt.Sprintf(message, data...))
case logger.Error:
global.GVA_LOG.Error(fmt.Sprintf(message, data...))
case logger.Warn:
global.GVA_LOG.Warn(fmt.Sprintf(message, data...))
case logger.Info:
global.GVA_LOG.Info(fmt.Sprintf(message, data...))
default:
global.GVA_LOG.Info(fmt.Sprintf(message, data...))
}
return
}
}
-35
View File
@@ -1,35 +0,0 @@
package internal
import (
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"gorm.io/gorm/logger"
)
type writer struct {
logger.Writer
}
// NewWriter writer 构造函数
// Author [SliverHorn](https://github.com/SliverHorn)
func NewWriter(w logger.Writer) *writer {
return &writer{Writer: w}
}
// Printf 格式化打印日志
// Author [SliverHorn](https://github.com/SliverHorn)
func (w *writer) Printf(message string, data ...interface{}) {
var logZap bool
switch global.GVA_CONFIG.System.DbType {
case "mysql":
logZap = global.GVA_CONFIG.Mysql.LogZap
case "pgsql":
logZap = global.GVA_CONFIG.Pgsql.LogZap
}
if logZap {
global.GVA_LOG.Info(fmt.Sprintf(message+"\n", data...))
} else {
w.Writer.Printf(message, data...)
}
}
+8 -4
View File
@@ -45,7 +45,7 @@ func (m *mongo) Initialization() error {
opts = internal.Mongo.GetClientOptions()
}
ctx := context.Background()
client, err := qmgo.Open(ctx, &qmgo.Config{
config := &qmgo.Config{
Uri: global.GVA_CONFIG.Mongo.Uri(),
Coll: global.GVA_CONFIG.Mongo.Coll,
Database: global.GVA_CONFIG.Mongo.Database,
@@ -53,12 +53,16 @@ func (m *mongo) Initialization() error {
MaxPoolSize: &global.GVA_CONFIG.Mongo.MaxPoolSize,
SocketTimeoutMS: &global.GVA_CONFIG.Mongo.SocketTimeoutMs,
ConnectTimeoutMS: &global.GVA_CONFIG.Mongo.ConnectTimeoutMs,
Auth: &qmgo.Credential{
}
if global.GVA_CONFIG.Mongo.Username != "" && global.GVA_CONFIG.Mongo.Password != "" {
config.Auth = &qmgo.Credential{
Username: global.GVA_CONFIG.Mongo.Username,
Password: global.GVA_CONFIG.Mongo.Password,
AuthSource: global.GVA_CONFIG.Mongo.AuthSource,
},
}, opts...)
}
}
client, err := qmgo.Open(ctx, config, opts...)
if err != nil {
return errors.Wrap(err, "链接mongodb数据库失败!")
}
+9
View File
@@ -1,7 +1,10 @@
package initialize
import (
"bufio"
"github.com/songzhibin97/gkit/cache/local_cache"
"os"
"strings"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
@@ -20,4 +23,10 @@ func OtherInit() {
global.BlackCache = local_cache.NewCache(
local_cache.SetDefaultExpire(dr),
)
file, err := os.Open("go.mod")
if err == nil && global.GVA_CONFIG.AutoCode.Module == "" {
scanner := bufio.NewScanner(file)
scanner.Scan()
global.GVA_CONFIG.AutoCode.Module = strings.TrimPrefix(scanner.Text(), "module ")
}
}
+6 -27
View File
@@ -1,36 +1,15 @@
package initialize
import (
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/middleware"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/email"
"github.com/flipped-aurora/gin-vue-admin/server/utils/plugin"
"github.com/gin-gonic/gin"
)
func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) {
for i := range Plugin {
PluginGroup := group.Group(Plugin[i].RouterPath())
Plugin[i].Register(PluginGroup)
func InstallPlugin(PrivateGroup *gin.RouterGroup, PublicRouter *gin.RouterGroup, engine *gin.Engine) {
if global.GVA_DB == nil {
global.GVA_LOG.Info("项目暂未初始化,无法安装插件,初始化后重启项目即可完成插件安装")
return
}
}
func InstallPlugin(Router *gin.Engine) {
PublicGroup := Router.Group("")
fmt.Println("无鉴权插件安装==》", PublicGroup)
PrivateGroup := Router.Group("")
fmt.Println("鉴权插件安装==》", PrivateGroup)
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
// 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同
PluginInit(PrivateGroup, email.CreateEmailPlug(
global.GVA_CONFIG.Email.To,
global.GVA_CONFIG.Email.From,
global.GVA_CONFIG.Email.Host,
global.GVA_CONFIG.Email.Secret,
global.GVA_CONFIG.Email.Nickname,
global.GVA_CONFIG.Email.Port,
global.GVA_CONFIG.Email.IsSSL,
))
bizPluginV1(PrivateGroup, PublicRouter)
bizPluginV2(engine)
}
+34
View File
@@ -0,0 +1,34 @@
package initialize
import (
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/email"
"github.com/flipped-aurora/gin-vue-admin/server/utils/plugin"
"github.com/gin-gonic/gin"
)
func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) {
for i := range Plugin {
fmt.Println(Plugin[i].RouterPath(), "注册开始!")
PluginGroup := group.Group(Plugin[i].RouterPath())
Plugin[i].Register(PluginGroup)
fmt.Println(Plugin[i].RouterPath(), "注册成功!")
}
}
func bizPluginV1(group ...*gin.RouterGroup) {
private := group[0]
public := group[1]
// 添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同
PluginInit(private, email.CreateEmailPlug(
global.GVA_CONFIG.Email.To,
global.GVA_CONFIG.Email.From,
global.GVA_CONFIG.Email.Host,
global.GVA_CONFIG.Email.Secret,
global.GVA_CONFIG.Email.Nickname,
global.GVA_CONFIG.Email.Port,
global.GVA_CONFIG.Email.IsSSL,
))
holder(public, private)
}
+16
View File
@@ -0,0 +1,16 @@
package initialize
import (
"github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement"
"github.com/flipped-aurora/gin-vue-admin/server/utils/plugin/v2"
"github.com/gin-gonic/gin"
)
func PluginInitV2(group *gin.Engine, plugins ...plugin.Plugin) {
for i := 0; i < len(plugins); i++ {
plugins[i].Register(group)
}
}
func bizPluginV2(engine *gin.Engine) {
PluginInitV2(engine, announcement.Plugin)
}
+29 -7
View File
@@ -3,14 +3,14 @@ package initialize
import (
"context"
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
)
func Redis() {
redisCfg := global.GVA_CONFIG.Redis
func initRedisClient(redisCfg config.Redis) (redis.UniversalClient, error) {
var client redis.UniversalClient
// 使用集群模式
if redisCfg.UseCluster {
@@ -28,10 +28,32 @@ func Redis() {
}
pong, err := client.Ping(context.Background()).Result()
if err != nil {
global.GVA_LOG.Error("redis connect ping failed, err:", zap.Error(err))
panic(err)
} else {
global.GVA_LOG.Info("redis connect ping response:", zap.String("pong", pong))
global.GVA_REDIS = client
global.GVA_LOG.Error("redis connect ping failed, err:", zap.String("name", redisCfg.Name), zap.Error(err))
return nil, err
}
global.GVA_LOG.Info("redis connect ping response:", zap.String("name", redisCfg.Name), zap.String("pong", pong))
return client, nil
}
func Redis() {
redisClient, err := initRedisClient(global.GVA_CONFIG.Redis)
if err != nil {
panic(err)
}
global.GVA_REDIS = redisClient
}
func RedisList() {
redisMap := make(map[string]redis.UniversalClient)
for _, redisCfg := range global.GVA_CONFIG.RedisList {
client, err := initRedisClient(redisCfg)
if err != nil {
panic(err)
}
redisMap[redisCfg.Name] = client
}
global.GVA_REDISList = redisMap
}
+38 -25
View File
@@ -1,6 +1,9 @@
package initialize
import (
"net/http"
"os"
"github.com/flipped-aurora/gin-vue-admin/server/docs"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/middleware"
@@ -8,8 +11,6 @@ import (
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"net/http"
"os"
)
type justFilesFilesystem struct {
@@ -39,28 +40,31 @@ func Routers() *gin.Engine {
Router.Use(gin.Logger())
}
InstallPlugin(Router) // 安装插件
systemRouter := router.RouterGroupApp.System
exampleRouter := router.RouterGroupApp.Example
// 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的
// VUE_APP_BASE_API = /
// VUE_APP_BASE_PATH = http://localhost
// 然后执行打包命令 npm run build。在打开下面3行注释
//Router.Static("/favicon.ico", "./dist/favicon.ico")
//Router.Static("/assets", "./dist/assets") // dist里面的静态资源
//Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面
// Router.Static("/favicon.ico", "./dist/favicon.ico")
// Router.Static("/assets", "./dist/assets") // dist里面的静态资源
// Router.StaticFile("/", "./dist/index.html") // 前端网页入口页面
Router.StaticFS(global.GVA_CONFIG.Local.StorePath, justFilesFilesystem{http.Dir(global.GVA_CONFIG.Local.StorePath)}) // Router.Use(middleware.LoadTls()) // 如果需要使用https 请打开此中间件 然后前往 core/server.go 将启动模式 更变为 Router.RunTLS("端口","你的cre/pem文件","你的key文件")
// 跨域,如需跨域可以打开下面的注释
// Router.Use(middleware.Cors()) // 直接放行全部跨域请求
// Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求
//global.GVA_LOG.Info("use middleware cors")
// global.GVA_LOG.Info("use middleware cors")
docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix
Router.GET(global.GVA_CONFIG.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
global.GVA_LOG.Info("register swagger handler")
// 方便统一添加路由组前缀 多服务器上线使用
PublicGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
{
// 健康监测
PublicGroup.GET("/health", func(c *gin.Context) {
@@ -71,28 +75,37 @@ func Routers() *gin.Engine {
systemRouter.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权
systemRouter.InitInitRouter(PublicGroup) // 自动初始化相关
}
PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
{
systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由
systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由
systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
systemRouter.InitSystemRouter(PrivateGroup) // system相关路由
systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由
systemRouter.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码
systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由
systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理
systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史
systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 字典详情管理
systemRouter.InitSysExportTemplateRouter(PrivateGroup) // 导出模板
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由
systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由
systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
systemRouter.InitSystemRouter(PrivateGroup) // system相关路由
systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由
systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码
systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由
systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理
systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史
systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 按钮权限管理
systemRouter.InitSysExportTemplateRouter(PrivateGroup, PublicGroup) // 导出模板
systemRouter.InitSysParamsRouter(PrivateGroup, PublicGroup) // 参数管理
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
exampleRouter.InitAttachmentCategoryRouterRouter(PrivateGroup) // 文件上传下载分类
}
//插件路由安装
InstallPlugin(PrivateGroup, PublicGroup, Router)
// 注册业务路由
initBizRouter(PrivateGroup, PublicGroup)
global.GVA_ROUTERS = Router.Routes()
global.GVA_LOG.Info("router register success")
return Router
}
+19
View File
@@ -0,0 +1,19 @@
package initialize
import (
"github.com/flipped-aurora/gin-vue-admin/server/router"
"github.com/gin-gonic/gin"
)
// 占位方法,保证文件可以正确加载,避免go空变量检测报错,请勿删除。
func holder(routers ...*gin.RouterGroup) {
_ = routers
_ = router.RouterGroupApp
}
func initBizRouter(routers ...*gin.RouterGroup) {
privateGroup := routers[0]
publicGroup := routers[1]
holder(publicGroup, privateGroup)
}
+10 -4
View File
@@ -1,12 +1,11 @@
package main
import (
_ "go.uber.org/automaxprocs"
"go.uber.org/zap"
"github.com/flipped-aurora/gin-vue-admin/server/core"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/initialize"
_ "go.uber.org/automaxprocs"
"go.uber.org/zap"
)
//go:generate go env -w GO111MODULE=on
@@ -14,8 +13,15 @@ import (
//go:generate go mod tidy
//go:generate go mod download
// 这部分 @Tag 设置用于排序, 需要排序的接口请按照下面的格式添加
// swag init 对 @Tag 只会从入口文件解析, 默认 main.go
// 也可通过 --generalInfo flag 指定其他文件
// @Tag.Name Base
// @Tag.Name SysUser
// @Tag.Description 用户
// @title Gin-Vue-Admin Swagger API接口文档
// @version v2.6.2
// @version v2.8.0
// @description 使用gin+vue进行极速开发的全栈开发基础平台
// @securityDefinitions.apikey ApiKeyAuth
// @in header
+2 -11
View File
@@ -3,16 +3,13 @@ package middleware
import (
"errors"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/golang-jwt/jwt/v4"
"go.uber.org/zap"
"github.com/golang-jwt/jwt/v5"
"strconv"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/service"
"github.com/gin-gonic/gin"
)
@@ -67,13 +64,7 @@ func JWTAuth() gin.HandlerFunc {
c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt.Unix(), 10))
utils.SetToken(c, newToken, int(dr.Seconds()))
if global.GVA_CONFIG.System.UseMultipoint {
RedisJwtToken, err := jwtService.GetRedisJWT(newClaims.Username)
if err != nil {
global.GVA_LOG.Error("get redis jwt failed", zap.Error(err))
} else { // 当之前的取成功时才进行拉黑操作
_ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: RedisJwtToken})
}
// 无论如何都要记录当前的活跃状态
// 记录新的活跃jwt
_ = jwtService.SetRedisJWT(newToken, newClaims.Username)
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ type LimitConfig struct {
func (l LimitConfig) LimitWithTime() gin.HandlerFunc {
return func(c *gin.Context) {
if err := l.CheckOrMark(l.GenerationKey(c), l.Expire, l.Limit); err != nil {
c.JSON(http.StatusOK, gin.H{"code": response.ERROR, "msg": err})
c.JSON(http.StatusOK, gin.H{"code": response.ERROR, "msg": err.Error()})
c.Abort()
return
} else {
+43
View File
@@ -0,0 +1,43 @@
package common
import (
"database/sql/driver"
"encoding/json"
"errors"
)
type JSONMap map[string]interface{}
func (m JSONMap) Value() (driver.Value, error) {
if m == nil {
return nil, nil
}
return json.Marshal(m)
}
func (m *JSONMap) Scan(value interface{}) error {
if value == nil {
*m = make(map[string]interface{})
return nil
}
var err error
switch value.(type) {
case []byte:
err = json.Unmarshal(value.([]byte), m)
case string:
err = json.Unmarshal([]byte(value.(string)), m)
default:
err = errors.New("basetypes.JSONMap.Scan: invalid value type")
}
if err != nil {
return err
}
return nil
}
type TreeNode[T any] interface {
GetChildren() []T
SetChildren(children T)
GetID() int
GetParentID() int
}
+21 -1
View File
@@ -1,10 +1,30 @@
package request
import (
"gorm.io/gorm"
)
// PageInfo Paging common input parameter structure
type PageInfo struct {
Page int `json:"page" form:"page"` // 页码
PageSize int `json:"pageSize" form:"pageSize"` // 每页大小
Keyword string `json:"keyword" form:"keyword"` //关键字
Keyword string `json:"keyword" form:"keyword"` // 关键字
}
func (r *PageInfo) Paginate() func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
if r.Page <= 0 {
r.Page = 1
}
switch {
case r.PageSize > 100:
r.PageSize = 100
case r.PageSize <= 0:
r.PageSize = 10
}
offset := (r.Page - 1) * r.PageSize
return db.Offset(offset).Limit(r.PageSize)
}
}
// GetById Find by id structure
+1 -1
View File
@@ -35,7 +35,7 @@ func OkWithMessage(message string, c *gin.Context) {
}
func OkWithData(data interface{}, c *gin.Context) {
Result(SUCCESS, data, "查询成功", c)
Result(SUCCESS, data, "成功", c)
}
func OkWithDetailed(data interface{}, message string, c *gin.Context) {
@@ -0,0 +1,16 @@
package example
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
)
type ExaAttachmentCategory struct {
global.GVA_MODEL
Name string `json:"name" form:"name" gorm:"default:null;type:varchar(255);column:name;comment:分类名称;"`
Pid uint `json:"pid" form:"pid" gorm:"default:0;type:int;column:pid;comment:父节点ID;"`
Children []*ExaAttachmentCategory `json:"children" gorm:"-"`
}
func (ExaAttachmentCategory) TableName() string {
return "exa_attachment_category"
}
@@ -6,10 +6,11 @@ import (
type ExaFileUploadAndDownload struct {
global.GVA_MODEL
Name string `json:"name" gorm:"comment:文件名"` // 文件名
Url string `json:"url" gorm:"comment:文件地址"` // 文件地址
Tag string `json:"tag" gorm:"comment:文件标签"` // 文件标签
Key string `json:"key" gorm:"comment:编号"` // 编号
Name string `json:"name" form:"name" gorm:"column:name;comment:文件名"` // 文件名
ClassId int `json:"classId" form:"classId" gorm:"default:0;type:int;column:class_id;comment:分类id;"` // 分类id
Url string `json:"url" form:"url" gorm:"column:url;comment:文件地址"` // 文件地址
Tag string `json:"tag" form:"tag" gorm:"column:tag;comment:文件标签"` // 文件标签
Key string `json:"key" form:"key" gorm:"column:key;comment:编号"` // 编号
}
func (ExaFileUploadAndDownload) TableName() string {
@@ -0,0 +1,10 @@
package request
import (
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
)
type ExaAttachmentCategorySearch struct {
ClassId int `json:"classId" form:"classId"`
request.PageInfo
}
+3 -3
View File
@@ -1,11 +1,11 @@
package request
import (
"github.com/gofrs/uuid/v5"
jwt "github.com/golang-jwt/jwt/v4"
jwt "github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
)
// Custom claims structure
// CustomClaims structure
type CustomClaims struct {
BaseClaims
BufferTime int64
@@ -0,0 +1,286 @@
package request
import (
"encoding/json"
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/global"
model "github.com/flipped-aurora/gin-vue-admin/server/model/system"
"github.com/pkg/errors"
"go/token"
"strings"
)
type AutoCode struct {
Package string `json:"package"`
PackageT string `json:"-"`
TableName string `json:"tableName" example:"表名"` // 表名
BusinessDB string `json:"businessDB" example:"业务数据库"` // 业务数据库
StructName string `json:"structName" example:"Struct名称"` // Struct名称
PackageName string `json:"packageName" example:"文件名称"` // 文件名称
Description string `json:"description" example:"Struct中文名称"` // Struct中文名称
Abbreviation string `json:"abbreviation" example:"Struct简称"` // Struct简称
HumpPackageName string `json:"humpPackageName" example:"go文件名称"` // go文件名称
GvaModel bool `json:"gvaModel" example:"false"` // 是否使用gva默认Model
AutoMigrate bool `json:"autoMigrate" example:"false"` // 是否自动迁移表结构
AutoCreateResource bool `json:"autoCreateResource" example:"false"` // 是否自动创建资源标识
AutoCreateApiToSql bool `json:"autoCreateApiToSql" example:"false"` // 是否自动创建api
AutoCreateMenuToSql bool `json:"autoCreateMenuToSql" example:"false"` // 是否自动创建menu
AutoCreateBtnAuth bool `json:"autoCreateBtnAuth" example:"false"` // 是否自动创建按钮权限
OnlyTemplate bool `json:"onlyTemplate" example:"false"` // 是否只生成模板
IsTree bool `json:"isTree" example:"false"` // 是否树形结构
TreeJson string `json:"treeJson" example:"展示的树json字段"` // 展示的树json字段
IsAdd bool `json:"isAdd" example:"false"` // 是否新增
Fields []*AutoCodeField `json:"fields"`
GenerateWeb bool `json:"generateWeb" example:"true"` // 是否生成web
GenerateServer bool `json:"generateServer" example:"true"` // 是否生成server
Module string `json:"-"`
DictTypes []string `json:"-"`
PrimaryField *AutoCodeField `json:"primaryField"`
DataSourceMap map[string]*DataSource `json:"-"`
HasPic bool `json:"-"`
HasFile bool `json:"-"`
HasTimer bool `json:"-"`
NeedSort bool `json:"-"`
NeedJSON bool `json:"-"`
HasRichText bool `json:"-"`
HasDataSource bool `json:"-"`
HasSearchTimer bool `json:"-"`
HasArray bool `json:"-"`
HasExcel bool `json:"-"`
}
type DataSource struct {
DBName string `json:"dbName"`
Table string `json:"table"`
Label string `json:"label"`
Value string `json:"value"`
Association int `json:"association"` // 关联关系 1 一对一 2 一对多
HasDeletedAt bool `json:"hasDeletedAt"`
}
func (r *AutoCode) Apis() []model.SysApi {
return []model.SysApi{
{
Path: "/" + r.Abbreviation + "/" + "create" + r.StructName,
Description: "新增" + r.Description,
ApiGroup: r.Description,
Method: "POST",
},
{
Path: "/" + r.Abbreviation + "/" + "delete" + r.StructName,
Description: "删除" + r.Description,
ApiGroup: r.Description,
Method: "DELETE",
},
{
Path: "/" + r.Abbreviation + "/" + "delete" + r.StructName + "ByIds",
Description: "批量删除" + r.Description,
ApiGroup: r.Description,
Method: "DELETE",
},
{
Path: "/" + r.Abbreviation + "/" + "update" + r.StructName,
Description: "更新" + r.Description,
ApiGroup: r.Description,
Method: "PUT",
},
{
Path: "/" + r.Abbreviation + "/" + "find" + r.StructName,
Description: "根据ID获取" + r.Description,
ApiGroup: r.Description,
Method: "GET",
},
{
Path: "/" + r.Abbreviation + "/" + "get" + r.StructName + "List",
Description: "获取" + r.Description + "列表",
ApiGroup: r.Description,
Method: "GET",
},
}
}
func (r *AutoCode) Menu(template string) model.SysBaseMenu {
component := fmt.Sprintf("view/%s/%s/%s.vue", r.Package, r.PackageName, r.PackageName)
if template != "package" {
component = fmt.Sprintf("plugin/%s/view/%s.vue", r.Package, r.PackageName)
}
return model.SysBaseMenu{
ParentId: 0,
Path: r.Abbreviation,
Name: r.Abbreviation,
Component: component,
Meta: model.Meta{
Title: r.Description,
},
}
}
// Pretreatment 预处理
// Author [SliverHorn](https://github.com/SliverHorn)
func (r *AutoCode) Pretreatment() error {
r.Module = global.GVA_CONFIG.AutoCode.Module
if token.IsKeyword(r.Abbreviation) {
r.Abbreviation = r.Abbreviation + "_"
} // go 关键字处理
if strings.HasSuffix(r.HumpPackageName, "test") {
r.HumpPackageName = r.HumpPackageName + "_"
} // test
length := len(r.Fields)
dict := make(map[string]string, length)
r.DataSourceMap = make(map[string]*DataSource, length)
for i := 0; i < length; i++ {
if r.Fields[i].Excel {
r.HasExcel = true
}
if r.Fields[i].DictType != "" {
dict[r.Fields[i].DictType] = ""
}
if r.Fields[i].Sort {
r.NeedSort = true
}
switch r.Fields[i].FieldType {
case "file":
r.HasFile = true
r.NeedJSON = true
case "json":
r.NeedJSON = true
case "array":
r.NeedJSON = true
r.HasArray = true
case "video":
r.HasPic = true
case "richtext":
r.HasRichText = true
case "picture":
r.HasPic = true
case "pictures":
r.HasPic = true
r.NeedJSON = true
case "time.Time":
r.HasTimer = true
if r.Fields[i].FieldSearchType != "" {
r.HasSearchTimer = true
}
}
if r.Fields[i].DataSource != nil {
if r.Fields[i].DataSource.Table != "" && r.Fields[i].DataSource.Label != "" && r.Fields[i].DataSource.Value != "" {
r.HasDataSource = true
r.Fields[i].CheckDataSource = true
r.DataSourceMap[r.Fields[i].FieldJson] = r.Fields[i].DataSource
}
}
if !r.GvaModel && r.PrimaryField == nil && r.Fields[i].PrimaryKey {
r.PrimaryField = r.Fields[i]
} // 自定义主键
}
{
for key := range dict {
r.DictTypes = append(r.DictTypes, key)
}
} // DictTypes => 字典
{
if r.GvaModel {
r.PrimaryField = &AutoCodeField{
FieldName: "ID",
FieldType: "uint",
FieldDesc: "ID",
FieldJson: "ID",
DataTypeLong: "20",
Comment: "主键ID",
ColumnName: "id",
}
}
} // GvaModel
{
if r.IsAdd && r.PrimaryField == nil {
r.PrimaryField = new(AutoCodeField)
}
} // 新增字段模式下不关注主键
if r.Package == "" {
return errors.New("Package为空!")
} // 增加判断:Package不为空
packages := []rune(r.Package)
if len(packages) > 0 {
if packages[0] >= 97 && packages[0] <= 122 {
packages[0] = packages[0] - 32
}
r.PackageT = string(packages)
} // PackageT 是 Package 的首字母大写
return nil
}
func (r *AutoCode) History() SysAutoHistoryCreate {
bytes, _ := json.Marshal(r)
return SysAutoHistoryCreate{
Table: r.TableName,
Package: r.Package,
Request: string(bytes),
StructName: r.StructName,
BusinessDB: r.BusinessDB,
Description: r.Description,
}
}
type AutoCodeField struct {
FieldName string `json:"fieldName"` // Field名
FieldDesc string `json:"fieldDesc"` // 中文名
FieldType string `json:"fieldType"` // Field数据类型
FieldJson string `json:"fieldJson"` // FieldJson
DataTypeLong string `json:"dataTypeLong"` // 数据库字段长度
Comment string `json:"comment"` // 数据库字段描述
ColumnName string `json:"columnName"` // 数据库字段
FieldSearchType string `json:"fieldSearchType"` // 搜索条件
FieldSearchHide bool `json:"fieldSearchHide"` // 是否隐藏查询条件
DictType string `json:"dictType"` // 字典
//Front bool `json:"front"` // 是否前端可见
Form bool `json:"form"` // 是否前端新建/编辑
Table bool `json:"table"` // 是否前端表格列
Desc bool `json:"desc"` // 是否前端详情
Excel bool `json:"excel"` // 是否导入/导出
Require bool `json:"require"` // 是否必填
DefaultValue string `json:"defaultValue"` // 是否必填
ErrorText string `json:"errorText"` // 校验失败文字
Clearable bool `json:"clearable"` // 是否可清空
Sort bool `json:"sort"` // 是否增加排序
PrimaryKey bool `json:"primaryKey"` // 是否主键
DataSource *DataSource `json:"dataSource"` // 数据源
CheckDataSource bool `json:"checkDataSource"` // 是否检查数据源
FieldIndexType string `json:"fieldIndexType"` // 索引类型
}
type AutoFunc struct {
Package string `json:"package"`
FuncName string `json:"funcName"` // 方法名称
Router string `json:"router"` // 路由名称
FuncDesc string `json:"funcDesc"` // 方法介绍
BusinessDB string `json:"businessDB"` // 业务库
StructName string `json:"structName"` // Struct名称
PackageName string `json:"packageName"` // 文件名称
Description string `json:"description"` // Struct中文名称
Abbreviation string `json:"abbreviation"` // Struct简称
HumpPackageName string `json:"humpPackageName"` // go文件名称
Method string `json:"method"` // 方法
IsPlugin bool `json:"isPlugin"` // 是否插件
IsAuth bool `json:"isAuth"` // 是否鉴权
IsPreview bool `json:"isPreview"` // 是否预览
IsAi bool `json:"isAi"` // 是否AI
ApiFunc string `json:"apiFunc"` // API方法
ServerFunc string `json:"serverFunc"` // 服务方法
JsFunc string `json:"jsFunc"` // JS方法
}
type InitMenu struct {
PlugName string `json:"plugName"`
ParentMenu string `json:"parentMenu"`
Menus []uint `json:"menus"`
}
type InitApi struct {
PlugName string `json:"plugName"`
APIs []uint `json:"apis"`
}
type LLMAutoCode struct {
Prompt string `json:"prompt" form:"prompt" gorm:"column:prompt;comment:提示语;type:text;"` //提示语
Mode string `json:"mode" form:"mode" gorm:"column:mode;comment:模式;type:text;"` //模式
}
@@ -0,0 +1,31 @@
package request
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
model "github.com/flipped-aurora/gin-vue-admin/server/model/system"
)
type SysAutoCodePackageCreate struct {
Desc string `json:"desc" example:"描述"`
Label string `json:"label" example:"展示名"`
Template string `json:"template" example:"模版"`
PackageName string `json:"packageName" example:"包名"`
Module string `json:"-" example:"模块"`
}
func (r *SysAutoCodePackageCreate) AutoCode() AutoCode {
return AutoCode{
Package: r.PackageName,
Module: global.GVA_CONFIG.AutoCode.Module,
}
}
func (r *SysAutoCodePackageCreate) Create() model.SysAutoCodePackage {
return model.SysAutoCodePackage{
Desc: r.Desc,
Label: r.Label,
Template: r.Template,
PackageName: r.PackageName,
Module: global.GVA_CONFIG.AutoCode.Module,
}
}
@@ -1,13 +1,57 @@
package request
import "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
import (
common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
model "github.com/flipped-aurora/gin-vue-admin/server/model/system"
)
type SysAutoHistory struct {
request.PageInfo
type SysAutoHistoryCreate struct {
Table string // 表名
Package string // 模块名/插件名
Request string // 前端传入的结构化信息
StructName string // 结构体名称
BusinessDB string // 业务库
Description string // Struct中文名称
Injections map[string]string // 注入路径
Templates map[string]string // 模板信息
ApiIDs []uint // api表注册内容
MenuID uint // 菜单ID
ExportTemplateID uint // 导出模板ID
}
// GetById Find by id structure
type RollBack struct {
ID int `json:"id" form:"id"` // 主键ID
func (r *SysAutoHistoryCreate) Create() model.SysAutoCodeHistory {
entity := model.SysAutoCodeHistory{
Package: r.Package,
Request: r.Request,
Table: r.Table,
StructName: r.StructName,
Abbreviation: r.StructName,
BusinessDB: r.BusinessDB,
Description: r.Description,
Injections: r.Injections,
Templates: r.Templates,
ApiIDs: r.ApiIDs,
MenuID: r.MenuID,
ExportTemplateID: r.ExportTemplateID,
}
if entity.Table == "" {
entity.Table = r.StructName
}
return entity
}
type SysAutoHistoryRollBack struct {
common.GetById
DeleteApi bool `json:"deleteApi" form:"deleteApi"` // 是否删除接口
DeleteMenu bool `json:"deleteMenu" form:"deleteMenu"` // 是否删除菜单
DeleteTable bool `json:"deleteTable" form:"deleteTable"` // 是否删除表
}
func (r *SysAutoHistoryRollBack) ApiIds(entity model.SysAutoCodeHistory) common.IdsReq {
length := len(entity.ApiIDs)
ids := make([]int, 0)
for i := 0; i < length; i++ {
ids = append(ids, int(entity.ApiIDs[i]))
}
return common.IdsReq{Ids: ids}
}
+5 -4
View File
@@ -1,12 +1,12 @@
package request
// Casbin info structure
// CasbinInfo Casbin info structure
type CasbinInfo struct {
Path string `json:"path"` // 路径
Method string `json:"method"` // 方法
}
// Casbin structure for input parameters
// CasbinInReceive Casbin structure for input parameters
type CasbinInReceive struct {
AuthorityId uint `json:"authorityId"` // 权限id
CasbinInfos []CasbinInfo `json:"casbinInfos"`
@@ -17,10 +17,11 @@ func DefaultCasbin() []CasbinInfo {
{Path: "/menu/getMenu", Method: "POST"},
{Path: "/jwt/jsonInBlacklist", Method: "POST"},
{Path: "/base/login", Method: "POST"},
{Path: "/user/admin_register", Method: "POST"},
{Path: "/user/changePassword", Method: "POST"},
{Path: "/user/setUserAuthority", Method: "POST"},
{Path: "/user/setUserInfo", Method: "PUT"},
{Path: "/user/getUserInfo", Method: "GET"},
{Path: "/user/setSelfInfo", Method: "PUT"},
{Path: "/fileUploadAndDownload/upload", Method: "POST"},
{Path: "/sysDictionary/findSysDictionary", Method: "GET"},
}
}
+9 -7
View File
@@ -7,13 +7,15 @@ import (
)
type InitDB struct {
DBType string `json:"dbType"` // 数据库类型
Host string `json:"host"` // 服务器地址
Port string `json:"port"` // 数据库连接端口
UserName string `json:"userName"` // 数据库用户名
Password string `json:"password"` // 数据库密码
DBName string `json:"dbName" binding:"required"` // 数据库名
DBPath string `json:"dbPath"` // sqlite数据库文件路径
AdminPassword string `json:"adminPassword" binding:"required"`
DBType string `json:"dbType"` // 数据库类型
Host string `json:"host"` // 服务器地址
Port string `json:"port"` // 数据库连接端口
UserName string `json:"userName"` // 数据库用户名
Password string `json:"password"` // 数据库密码
DBName string `json:"dbName" binding:"required"` // 数据库名
DBPath string `json:"dbPath"` // sqlite数据库文件路径
Template string `json:"template"` // postgresql指定template
}
// MysqlEmptyDsn msyql 空数据库 建库链接
+2 -2
View File
@@ -5,7 +5,7 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
)
// Add menu authority info structure
// AddMenuAuthorityInfo Add menu authority info structure
type AddMenuAuthorityInfo struct {
Menus []system.SysBaseMenu `json:"menus"`
AuthorityId uint `json:"authorityId"` // 角色ID
@@ -14,7 +14,7 @@ type AddMenuAuthorityInfo struct {
func DefaultMenu() []system.SysBaseMenu {
return []system.SysBaseMenu{{
GVA_MODEL: global.GVA_MODEL{ID: 1},
ParentId: "0",
ParentId: 0,
Path: "dashboard",
Name: "dashboard",
Component: "view/dashboard/index.vue",
+14
View File
@@ -0,0 +1,14 @@
package request
import (
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"time"
)
type SysParamsSearch struct {
StartCreatedAt *time.Time `json:"startCreatedAt" form:"startCreatedAt"`
EndCreatedAt *time.Time `json:"endCreatedAt" form:"endCreatedAt"`
Name string `json:"name" form:"name" `
Key string `json:"key" form:"key" `
request.PageInfo
}
+13 -4
View File
@@ -1,6 +1,7 @@
package request
import (
common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
)
@@ -17,7 +18,7 @@ type Register struct {
Email string `json:"email" example:"电子邮箱"`
}
// User login structure
// Login User login structure
type Login struct {
Username string `json:"username"` // 用户名
Password string `json:"password"` // 密码
@@ -25,19 +26,19 @@ type Login struct {
CaptchaId string `json:"captchaId"` // 验证码ID
}
// Modify password structure
// ChangePasswordReq Modify password structure
type ChangePasswordReq struct {
ID uint `json:"-"` // 从 JWT 中提取 user id,避免越权
Password string `json:"password"` // 密码
NewPassword string `json:"newPassword"` // 新密码
}
// Modify user's auth structure
// SetUserAuth Modify user's auth structure
type SetUserAuth struct {
AuthorityId uint `json:"authorityId"` // 角色ID
}
// Modify user's auth structure
// SetUserAuthorities Modify user's auth structure
type SetUserAuthorities struct {
ID uint
AuthorityIds []uint `json:"authorityIds"` // 角色ID
@@ -54,3 +55,11 @@ type ChangeUserInfo struct {
Enable int `json:"enable" gorm:"comment:冻结用户"` //冻结用户
Authorities []system.SysAuthority `json:"-" gorm:"many2many:sys_user_authority;"`
}
type GetUserList struct {
common.PageInfo
Username string `json:"username" form:"username"`
NickName string `json:"nickName" form:"nickName"`
Phone string `json:"phone" form:"phone"`
Email string `json:"email" form:"email"`
}
+8 -1
View File
@@ -1,6 +1,8 @@
package response
import "github.com/flipped-aurora/gin-vue-admin/server/model/system"
import (
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
)
type SysAPIResponse struct {
Api system.SysApi `json:"api"`
@@ -9,3 +11,8 @@ type SysAPIResponse struct {
type SysAPIListResponse struct {
Apis []system.SysApi `json:"apis"`
}
type SysSyncApis struct {
NewApis []system.SysApi `json:"newApis"`
DeleteApis []system.SysApi `json:"deleteApis"`
}
@@ -1,14 +0,0 @@
package response
import "time"
type AutoCodeHistory struct {
ID uint `json:"ID" gorm:"column:id"`
CreatedAt time.Time `json:"CreatedAt" gorm:"column:created_at"`
UpdatedAt time.Time `json:"UpdatedAt" gorm:"column:updated_at"`
BusinessDB string `json:"businessDB" gorm:"column:business_db"`
TableName string `json:"tableName" gorm:"column:table_name"`
StructName string `json:"structName" gorm:"column:struct_name"`
StructCNName string `json:"structCNName" gorm:"column:struct_cn_name"`
Flag int `json:"flag" gorm:"column:flag"`
}
+11
View File
@@ -15,3 +15,14 @@ type SysApi struct {
func (SysApi) TableName() string {
return "sys_apis"
}
type SysIgnoreApi struct {
global.GVA_MODEL
Path string `json:"path" gorm:"comment:api路径"` // api路径
Method string `json:"method" gorm:"default:POST;comment:方法"` // 方法:创建POST(默认)|查看GET|更新PUT|删除DELETE
Flag bool `json:"flag" gorm:"-"` // 是否忽略
}
func (SysIgnoreApi) TableName() string {
return "sys_ignore_apis"
}
+1 -1
View File
@@ -2,7 +2,7 @@ package system
type SysMenu struct {
SysBaseMenu
MenuId string `json:"menuId" gorm:"comment:菜单ID"`
MenuId uint `json:"menuId" gorm:"comment:菜单ID"`
AuthorityId uint `json:"-" gorm:"comment:角色ID"`
Children []SysMenu `json:"children" gorm:"-"`
Parameters []SysBaseMenuParameter `json:"parameters" gorm:"foreignKey:SysBaseMenuID;references:MenuId"`
-123
View File
@@ -1,123 +0,0 @@
package system
import (
"errors"
"go/token"
"strings"
"github.com/flipped-aurora/gin-vue-admin/server/global"
)
// AutoCodeStruct 初始版本自动化代码工具
type AutoCodeStruct struct {
StructName string `json:"structName"` // Struct名称
TableName string `json:"tableName"` // 表名
PackageName string `json:"packageName"` // 文件名称
HumpPackageName string `json:"humpPackageName"` // go文件名称
Abbreviation string `json:"abbreviation"` // Struct简称
Description string `json:"description"` // Struct中文名称
AutoCreateApiToSql bool `json:"autoCreateApiToSql"` // 是否自动创建api
AutoCreateMenuToSql bool `json:"autoCreateMenuToSql"` // 是否自动创建menu
AutoCreateResource bool `json:"autoCreateResource"` // 是否自动创建资源标识
AutoMoveFile bool `json:"autoMoveFile"` // 是否自动移动文件
BusinessDB string `json:"businessDB"` // 业务数据库
GvaModel bool `json:"gvaModel"` // 是否使用gva默认Model
Fields []*Field `json:"fields"`
PrimaryField *Field `json:"primaryField"`
HasTimer bool `json:"-"`
HasSearchTimer bool `json:"-"`
DictTypes []string `json:"-"`
Package string `json:"package"`
PackageT string `json:"-"`
NeedSort bool `json:"-"`
HasPic bool `json:"-"`
HasRichText bool `json:"-"`
HasFile bool `json:"-"`
NeedJSON bool `json:"-"`
}
func (a *AutoCodeStruct) Pretreatment() {
a.KeyWord()
a.SuffixTest()
}
// KeyWord 是go关键字的处理加上 _ ,防止编译报错
// Author [SliverHorn](https://github.com/SliverHorn)
func (a *AutoCodeStruct) KeyWord() {
if token.IsKeyword(a.Abbreviation) {
a.Abbreviation = a.Abbreviation + "_"
}
}
// SuffixTest 处理_test 后缀
// Author [SliverHorn](https://github.com/SliverHorn)
func (a *AutoCodeStruct) SuffixTest() {
if strings.HasSuffix(a.HumpPackageName, "test") {
a.HumpPackageName = a.HumpPackageName + "_"
}
}
type Field struct {
FieldName string `json:"fieldName"` // Field名
FieldDesc string `json:"fieldDesc"` // 中文名
FieldType string `json:"fieldType"` // Field数据类型
FieldJson string `json:"fieldJson"` // FieldJson
DataTypeLong string `json:"dataTypeLong"` // 数据库字段长度
Comment string `json:"comment"` // 数据库字段描述
ColumnName string `json:"columnName"` // 数据库字段
FieldSearchType string `json:"fieldSearchType"` // 搜索条件
DictType string `json:"dictType"` // 字典
Require bool `json:"require"` // 是否必填
ErrorText string `json:"errorText"` // 校验失败文字
Clearable bool `json:"clearable"` // 是否可清空
Sort bool `json:"sort"` // 是否增加排序
PrimaryKey bool `json:"primaryKey"` // 是否主键
}
var ErrAutoMove error = errors.New("创建代码成功并移动文件成功")
type SysAutoCode struct {
global.GVA_MODEL
PackageName string `json:"packageName" gorm:"comment:包名"`
Label string `json:"label" gorm:"comment:展示名"`
Desc string `json:"desc" gorm:"comment:描述"`
}
type AutoPlugReq struct {
PlugName string `json:"plugName"` // 必然大写开头
Snake string `json:"snake"` // 后端自动转为 snake
RouterGroup string `json:"routerGroup"`
HasGlobal bool `json:"hasGlobal"`
HasRequest bool `json:"hasRequest"`
HasResponse bool `json:"hasResponse"`
NeedModel bool `json:"needModel"`
Global []AutoPlugInfo `json:"global,omitempty"`
Request []AutoPlugInfo `json:"request,omitempty"`
Response []AutoPlugInfo `json:"response,omitempty"`
}
func (a *AutoPlugReq) CheckList() {
a.Global = bind(a.Global)
a.Request = bind(a.Request)
a.Response = bind(a.Response)
}
func bind(req []AutoPlugInfo) []AutoPlugInfo {
var r []AutoPlugInfo
for _, info := range req {
if info.Effective() {
r = append(r, info)
}
}
return r
}
type AutoPlugInfo struct {
Key string `json:"key"`
Type string `json:"type"`
Desc string `json:"desc"`
}
func (a AutoPlugInfo) Effective() bool {
return a.Key != "" && a.Type != "" && a.Desc != ""
}
@@ -0,0 +1,68 @@
package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"gorm.io/gorm"
"os"
"path"
"path/filepath"
"strings"
)
// SysAutoCodeHistory 自动迁移代码记录,用于回滚,重放使用
type SysAutoCodeHistory struct {
global.GVA_MODEL
Table string `json:"tableName" gorm:"column:table_name;comment:表名"`
Package string `json:"package" gorm:"column:package;comment:模块名/插件名"`
Request string `json:"request" gorm:"type:text;column:request;comment:前端传入的结构化信息"`
StructName string `json:"structName" gorm:"column:struct_name;comment:结构体名称"`
Abbreviation string `json:"abbreviation" gorm:"column:abbreviation;comment:结构体名称缩写"`
BusinessDB string `json:"businessDb" gorm:"column:business_db;comment:业务库"`
Description string `json:"description" gorm:"column:description;comment:Struct中文名称"`
Templates map[string]string `json:"template" gorm:"serializer:json;type:text;column:templates;comment:模板信息"`
Injections map[string]string `json:"injections" gorm:"serializer:json;type:text;column:Injections;comment:注入路径"`
Flag int `json:"flag" gorm:"column:flag;comment:[0:创建,1:回滚]"`
ApiIDs []uint `json:"apiIDs" gorm:"serializer:json;column:api_ids;comment:api表注册内容"`
MenuID uint `json:"menuId" gorm:"column:menu_id;comment:菜单ID"`
ExportTemplateID uint `json:"exportTemplateID" gorm:"column:export_template_id;comment:导出模板ID"`
AutoCodePackage SysAutoCodePackage `json:"autoCodePackage" gorm:"foreignKey:ID;references:PackageID"`
PackageID uint `json:"packageID" gorm:"column:package_id;comment:包ID"`
}
func (s *SysAutoCodeHistory) BeforeCreate(db *gorm.DB) error {
templates := make(map[string]string, len(s.Templates))
for key, value := range s.Templates {
server := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server)
{
hasServer := strings.Index(key, server)
if hasServer != -1 {
key = strings.TrimPrefix(key, server)
keys := strings.Split(key, string(os.PathSeparator))
key = path.Join(keys...)
}
} // key
web := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.WebRoot())
hasWeb := strings.Index(value, web)
if hasWeb != -1 {
value = strings.TrimPrefix(value, web)
values := strings.Split(value, string(os.PathSeparator))
value = path.Join(values...)
templates[key] = value
continue
}
hasServer := strings.Index(value, server)
if hasServer != -1 {
value = strings.TrimPrefix(value, server)
values := strings.Split(value, string(os.PathSeparator))
value = path.Join(values...)
templates[key] = value
continue
}
}
s.Templates = templates
return nil
}
func (s *SysAutoCodeHistory) TableName() string {
return "sys_auto_code_histories"
}
@@ -0,0 +1,18 @@
package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
)
type SysAutoCodePackage struct {
global.GVA_MODEL
Desc string `json:"desc" gorm:"comment:描述"`
Label string `json:"label" gorm:"comment:展示名"`
Template string `json:"template" gorm:"comment:模版"`
PackageName string `json:"packageName" gorm:"comment:包名"`
Module string `json:"-" example:"模块"`
}
func (s *SysAutoCodePackage) TableName() string {
return "sys_auto_code_packages"
}
@@ -1,41 +0,0 @@
package system
import (
"strconv"
"strings"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
)
// SysAutoCodeHistory 自动迁移代码记录,用于回滚,重放使用
type SysAutoCodeHistory struct {
global.GVA_MODEL
Package string `json:"package"`
BusinessDB string `json:"businessDB"`
TableName string `json:"tableName"`
MenuID uint `json:"menuID"`
RequestMeta string `gorm:"type:text" json:"requestMeta,omitempty"` // 前端传入的结构化信息
AutoCodePath string `gorm:"type:text" json:"autoCodePath,omitempty"` // 其他meta信息 path;path
InjectionMeta string `gorm:"type:text" json:"injectionMeta,omitempty"` // 注入的内容 RouterPath@functionName@RouterString;
StructName string `json:"structName"`
StructCNName string `json:"structCNName"`
ApiIDs string `json:"apiIDs,omitempty"` // api表注册内容
Flag int `json:"flag"` // 表示对应状态 0 代表创建, 1 代表回滚 ...
}
// ToRequestIds ApiIDs 转换 request.IdsReq
// Author [SliverHorn](https://github.com/SliverHorn)
func (m *SysAutoCodeHistory) ToRequestIds() request.IdsReq {
if m.ApiIDs == "" {
return request.IdsReq{}
}
slice := strings.Split(m.ApiIDs, ";")
ids := make([]int, 0, len(slice))
length := len(slice)
for i := 0; i < length; i++ {
id, _ := strconv.ParseInt(slice[i], 10, 32)
ids = append(ids, int(id))
}
return request.IdsReq{Ids: ids}
}
+17 -17
View File
@@ -6,34 +6,34 @@ import (
type SysBaseMenu struct {
global.GVA_MODEL
MenuLevel uint `json:"-"`
ParentId string `json:"parentId" gorm:"comment:父菜单ID"` // 父菜单ID
Path string `json:"path" gorm:"comment:路由path"` // 路由path
Name string `json:"name" gorm:"comment:路由name"` // 路由name
Hidden bool `json:"hidden" gorm:"comment:是否在列表隐藏"` // 是否在列表隐藏
Component string `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
Sort int `json:"sort" gorm:"comment:排序标记"` // 排序标记
Meta `json:"meta" gorm:"embedded;comment:附加属性"` // 附加属性
SysAuthoritys []SysAuthority `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
Children []SysBaseMenu `json:"children" gorm:"-"`
Parameters []SysBaseMenuParameter `json:"parameters"`
MenuBtn []SysBaseMenuBtn `json:"menuBtn"`
MenuLevel uint `json:"-"`
ParentId uint `json:"parentId" gorm:"comment:父菜单ID"` // 父菜单ID
Path string `json:"path" gorm:"comment:路由path"` // 路由path
Name string `json:"name" gorm:"comment:路由name"` // 路由name
Hidden bool `json:"hidden" gorm:"comment:是否在列表隐藏"` // 是否在列表隐藏
Component string `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
Sort int `json:"sort" gorm:"comment:排序标记"` // 排序标记
Meta `json:"meta" gorm:"embedded;comment:附加属性"` // 附加属性
SysAuthoritys []SysAuthority `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
Children []SysBaseMenu `json:"children" gorm:"-"`
Parameters []SysBaseMenuParameter `json:"parameters"`
MenuBtn []SysBaseMenuBtn `json:"menuBtn"`
}
type Meta struct {
ActiveName string `json:"activeName" gorm:"comment:高亮菜单"`
KeepAlive bool `json:"keepAlive" gorm:"comment:是否缓存"` // 是否缓存
KeepAlive bool `json:"keepAlive" gorm:"comment:是否缓存"` // 是否缓存
DefaultMenu bool `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"` // 是否是基础路由(开发中)
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
}
type SysBaseMenuParameter struct {
global.GVA_MODEL
SysBaseMenuID uint
Type string `json:"type" gorm:"comment:地址栏携带参数为params还是query"` // 地址栏携带参数为params还是query
Key string `json:"key" gorm:"comment:地址栏携带参数的key"` // 地址栏携带参数的key
Key string `json:"key" gorm:"comment:地址栏携带参数的key"` // 地址栏携带参数的key
Value string `json:"value" gorm:"comment:地址栏携带参数的值"` // 地址栏携带参数的值
}
+21 -8
View File
@@ -8,14 +8,27 @@ import (
// 导出模板 结构体 SysExportTemplate
type SysExportTemplate struct {
global.GVA_MODEL
DBName string `json:"dbName" form:"dbName" gorm:"column:db_name;comment:数据库名称;"` //数据库名称
Name string `json:"name" form:"name" gorm:"column:name;comment:模板名称;"` //模板名称
TableName string `json:"tableName" form:"tableName" gorm:"column:table_name;comment:表名称;"` //表名称
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识;"` //模板标识
TemplateInfo string `json:"templateInfo" form:"templateInfo" gorm:"column:template_info;type:text;"` //模板信息
Limit int `json:"limit" form:"limit" gorm:"column:limit;comment:导出限制"`
Order string `json:"order" form:"order" gorm:"column:order;comment:排序"`
Conditions []Condition `json:"conditions" form:"conditions" gorm:"foreignKey:TemplateID;references:TemplateID;comment:条件"`
DBName string `json:"dbName" form:"dbName" gorm:"column:db_name;comment:数据库名称;"` //数据库名称
Name string `json:"name" form:"name" gorm:"column:name;comment:模板名称;"` //模板名称
TableName string `json:"tableName" form:"tableName" gorm:"column:table_name;comment:表名称;"` //表名称
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识;"` //模板标识
TemplateInfo string `json:"templateInfo" form:"templateInfo" gorm:"column:template_info;type:text;"` //模板信息
Limit *int `json:"limit" form:"limit" gorm:"column:limit;comment:导出限制"`
Order string `json:"order" form:"order" gorm:"column:order;comment:排序"`
Conditions []Condition `json:"conditions" form:"conditions" gorm:"foreignKey:TemplateID;references:TemplateID;comment:条件"`
JoinTemplate []JoinTemplate `json:"joinTemplate" form:"joinTemplate" gorm:"foreignKey:TemplateID;references:TemplateID;comment:关联"`
}
type JoinTemplate struct {
global.GVA_MODEL
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识"`
JOINS string `json:"joins" form:"joins" gorm:"column:joins;comment:关联"`
Table string `json:"table" form:"table" gorm:"column:table;comment:关联表"`
ON string `json:"on" form:"on" gorm:"column:on;comment:关联条件"`
}
func (JoinTemplate) TableName() string {
return "sys_export_template_join"
}
type Condition struct {

Some files were not shown because too many files have changed in this diff Show More