Compare commits

...
336 Commits
Author SHA1 Message Date
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
chenlianghong e918af0a0c adjust sys_user.go message when del logined self (#1909) 2024-10-18 10:34:24 +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
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
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
PiexlMax(奇淼 c226a9476f Merge pull request #1694 from xue-ding-e/main
增加redis集群设置
2024-03-31 17:51:56 +08:00
pixelmaxQM 8ca5600286 feature: 修改版本号发布v2.6.2 2024-03-31 17:50:07 +08:00
薛定饿了不养喵 9729bc00a0 删掉了不必要的增加(就是之前说的那个样式bug其实不是bug)
style="width:194px"
2024-03-31 03:58:55 +08:00
xuedinge f9c9af8261 增加redis集群连接方式 2024-03-31 01:15:20 +08:00
薛定饿了不养喵 c9e64373fb Merge branch 'flipped-aurora:main' into main 2024-03-31 00:33:51 +08:00
pixelmaxQM 262febf486 feature:增加API导入导出,方便填写录入,暂时屏蔽自动书写导入的创建时间的功能,等待gorm合并pr后恢复。 2024-03-30 20:54:34 +08:00
pixelmaxQM eca9c4d7f8 fixed:#1692 统一前端操作模式 2024-03-29 20:53:19 +08:00
薛定饿了不养喵 a20083bb9c Merge branch 'flipped-aurora:main' into main 2024-03-28 01:59:21 +08:00
piexlMax d31b01415b feature:自动化代码支持基础菜单创建 2024-03-27 21:18:34 +08:00
piexlMax 26cdb472f0 feature:自动创建基本菜单 2024-03-27 20:55:03 +08:00
pixelMax(奇淼 3c2595aaf9 feature:调整jwt令牌过期展现形式和返回错误编码形式,方便用户重新登录和知晓错误原因。 2024-03-27 17:35:24 +08:00
PiexlMax(奇淼 ad323a0dff Update config.js 2024-03-27 16:48:22 +08:00
PiexlMax(奇淼 9a0417b1a7 Update server.go 2024-03-27 16:47:59 +08:00
PiexlMax(奇淼 3324a816ee Update README.md 2024-03-27 16:47:32 +08:00
piexlmax(奇淼 cc4135a2d7 feature:禁止选中角色的子以及后代节点 2024-03-27 10:45:19 +08:00
piexlmax(奇淼 2d884c83cc feature:调整jwt续期功能,保证新的token返回和一致性 2024-03-27 10:39:19 +08:00
piexlmax(奇淼 619c5b5e1d feature:消除icon缓存 2024-03-27 10:11:19 +08:00
傅鹏 33afa9adfc feat: ignore go debug bin file (#1687)
* fix: k8s cpu num

* feat: ignore go debug bin file
2024-03-25 13:38:40 +08:00
CC11001100 0c141cc6f7 fix: 应该调用filepath.Join的地方调用了path.Join (#1688) 2024-03-25 13:38:22 +08:00
傅鹏 efdff2ab0c fix: k8s cpu num (#1685) 2024-03-21 10:16:06 +08:00
hooraymanand胡浩 ebefb0eba4 feat: docker-compose healthz check (#1680)
Co-authored-by: 胡浩 <huhao@anesec.cn>
2024-03-20 15:08:39 +08:00
奇淼(piexlmax d4b9c2c97b loading增加定制属性,可自行配置 (#1683)
* feature:增加区域loading功能

* feature:增加修改loading配置
2024-03-20 10:44:21 +08:00
piexlMax d4db16b501 增加json model模板 2024-03-18 22:32:14 +08:00
piexlMax a5cbd7387b feature:#1647 自动化代码支持纯json 2024-03-18 22:25:50 +08:00
piexlMax 99d6b4a361 feature:#1671调整字典的value属性为string 自动化模板随改 2024-03-18 21:44:14 +08:00
piexlMax 18365689e6 调整字典的value属性为string 不再限制为int 2024-03-18 21:23:53 +08:00
piexlMax 8ea827412a 同步清理前端timer配置 2024-03-17 12:52:57 +08:00
piexlMax 4d8979c4ad 调整抽屉框格式 2024-03-16 00:29:03 +08:00
piexlMax 236357baa8 调整自动化代码的新增,编辑,删除为抽屉模式 2024-03-16 00:22:36 +08:00
piexlMax 5ef4b21858 增加表格导出多数据库支持 2024-03-15 23:22:20 +08:00
piexlmax(奇淼 3b3441851c feature:保证存在GVA默认结构的表格导入自动填充created和updated 2024-03-15 14:55:20 +08:00
piexlmax(奇淼 5517987e14 feature:保证表格导出的列顺序和json录入顺序一致 2024-03-15 11:38:34 +08:00
奇淼(piexlmax 7e98f61bec Revert "fix:保证excel每次导出列顺序一致 (#1677)" (#1678)
This reverts commit e2d360e8b1.
2024-03-15 11:23:21 +08:00
e2d360e8b1 fix:保证excel每次导出列顺序一致 (#1677)
* fix:保证excel每次导出列顺序一致

* Update sys_export_template.go

---------

Co-authored-by: Li vito <vito.li@shopee.com>
Co-authored-by: 奇淼(piexlmax <qimiaojiangjizhao@gmail.com>
2024-03-15 11:16:24 +08:00
piexlmax(奇淼 57cfedfd7c typo修复,正则字符串修复 2024-03-14 14:50:41 +08:00
piexlMax 50b1d21d13 调整删除方法 放弃使用el-popover 删除操作使用弹窗提示 2024-03-13 22:37:07 +08:00
Alex Lin 7b79ec6c66 fixed: api管理中的 popover 触发改为 click (#1673) 2024-03-13 20:14:27 +08:00
piexlmax(奇淼 7a5b31530f 清理错误提交的测试代码 2024-03-13 16:25:01 +08:00
piexlmax(奇淼 e9100a9542 替换v-model API 为 defineModel 2024-03-13 15:17:57 +08:00
piexlmax(奇淼 421304d4a3 提升最低VUE版本至3.4.x 2024-03-13 14:49:28 +08:00
piexlMax 10d61bbbb3 导出功能可传入limit、offset和order,优先级高于默认配置 2024-03-12 21:08:25 +08:00
piexlmax(奇淼 095709fb19 fixed:退出只清理特定的localStorage 不再进行全部清理操作 2024-03-11 11:47:59 +08:00
piexlMax 725f4150fc 统一调整element form inline元素的属性 2024-03-07 22:35:02 +08:00
andywu1998 93ac2e70d2 feat(gin.Mode()): 由环境变量决定,不再依赖于配置文件system.Env (#1668)
* feat(gin.Mode()): 由环境变量决定,不再依赖于配置文件system.Env

* feat(casbin):不需要判断是否是debug模式,都要附带参数

* feat(前端配置):去掉环境之的配置
2024-03-06 23:38:17 +08:00
andywu1998 f4c2b50ca5 feat(config init log): modify constant value GIN_MODE to gin.Mode() (#1667) 2024-03-06 22:32:42 +08:00
piexlMax 3354edbb1c 在初始化时候添加excelTemplate的关联表 2024-03-06 22:22:27 +08:00
piexlMax d3600499af fixed:剔除错误提交的测试用代码 2024-03-06 00:19:17 +08:00
奇淼(piexlmax 35e2c2cfe8 feature:表格导出支持配置limit order和where条件 (#1665)
* feature:导出功能可携带条件

* feature:组件增加导出入参

* 带条件导出Excel功能
2024-03-05 23:29:59 +08:00
piexlmax(奇淼 1e4970469f publish:调整版本号v2.6.1 2024-03-04 17:06:34 +08:00
piexlMax 4cbfd7c9b1 消除el-descriptions的warning 2024-03-03 17:35:38 +08:00
piexlmax(奇淼 deb32fa0fa fixed:#1659 调整table中sort驼峰对应不到数据库字段的问题 2024-03-01 11:04:52 +08:00
piexlmax(奇淼 f17a738780 fix:switchTab,query=>params。 2024-03-01 10:04:18 +08:00
piexlmax(奇淼 2f53d0efae feat:增加全局订阅switchTab,用户可以给tab添加参数跳转且不打开新tab。 2024-02-29 18:06:29 +08:00
piexlmax(奇淼 3e43c2e6e6 type:限=>线 2024-02-29 16:34:53 +08:00
piexlmax(奇淼 96919a9f79 fix:取消重复方法 2024-02-29 16:34:08 +08:00
piexlmax(奇淼 a23fb627cd feat:#1658 增加全局订阅 setQuery 用户可以动态变更当前页query而不产生新的tab 2024-02-29 16:32:09 +08:00
Leo Wang aae915b092 fix: 解决build时,会有浏览器缓存问题。 (#1661) 2024-02-29 16:26:45 +08:00
Leo Wangand奇淼(piexlmax 160c8e814b bugfix:修复新增菜单强制默认icon的bug;修复production环境变量容易造成困惑的问题; (#1660)
* fix: 解决每次新增菜单时,默认都会选中第一个aim图标的问题

* fix: 修订production的环境变量,去除那些在生产环境会造成困惑的项目

* Update .env.production

合理性调整

---------

Co-authored-by: 奇淼(piexlmax <qimiaojiangjizhao@gmail.com>
2024-02-29 16:18:07 +08:00
piexlmax(奇淼 88f48baba1 feat:#1658 增加全局订阅 setQuery 用户可以动态变更当前页query而不产生新的tab 2024-02-29 16:08:36 +08:00
piexlMax 7835efbf37 调整自动化代码模板的格式 2024-02-26 23:09:51 +08:00
shan_lu 455fbb505e fix the word spelling error for acitveAxios (#1655) 2024-02-23 11:31:15 +08:00
ipanghuand陶正虎 df3f7090e8 fix:修改操作记录中间件,文件类型统一记录为[文件] (#1656)
Co-authored-by: 陶正虎 <zhenghu.tao@jutze.com.cn>
2024-02-23 11:30:52 +08:00
piexlmax(奇淼 632b3c200c 调整cookie写入方法 2024-02-22 13:43:53 +08:00
piexlmax(奇淼 5b203326ae 清理文本输出之前的sleep 2024-02-21 17:44:25 +08:00
piexlMax fd87aca57d 前端跟随增加cookie管理方法,防止后端无法设置cookie的情况下导致的某些功能不可用问题。 2024-02-20 16:06:08 +08:00
piexlMax b9b7e556e3 修复表格导出和模板导出的bug 2024-02-20 15:06:17 +08:00
piexlmax(奇淼 5b9a7e6a2a 调整mssql自动化 2024-02-19 10:48:38 +08:00
rightSun d278e19367 dictionary.js update 优化字典文字展示方法 (#1652)
优化字典文字展示方法
新增可配置的参数 keyCode 和valueCode 使用字典字段更加灵活
2024-02-07 17:40:01 +08:00
piexlmax(奇淼 342030ca47 Merge remote-tracking branch 'origin/main' 2024-02-04 17:47:43 +08:00
piexlmax(奇淼 f90e241cc9 调整mssql初始化 2024-02-04 17:47:30 +08:00
lenandwangshenglei ff6bcc437c [Bug]:修复使用页面内按钮权限不生效问题 (#1621)
Co-authored-by: wangshenglei <wangshenglei@zhuanzhuan.com>
2024-02-04 11:36:06 +08:00
G-XD e32dbb5125 fix: 更新api路径时使用binary区分大小写进行查询 (#1645)
* fix: 更新api路径时使用`binary`区分大小写进行查询

* fix: 修改相同api路径判断逻辑
2024-02-04 11:35:45 +08:00
Sonui 06701cc7d1 fix(Server): 静态资源目录错误 (#1648) 2024-02-04 11:33:29 +08:00
piexlMax ccb31bc1b4 调整静态文件读取 防止文件目录暴露 2024-01-30 23:33:38 +08:00
myface-wang 7e2e29e2e8 Update svgIcon.vue (#1642)
删除不必要的导入,defineProps
2024-01-30 22:56:02 +08:00
piexlMax 0c76995f6d 修复菜单select展示的bug 2024-01-30 22:43:22 +08:00
xuedinge 6bbb4f577e 修改样式 系统工具 -> 代码生成器 下的 '点这里从现有数据库创建代码' 内容显示不全 2024-01-18 18:48:47 +08:00
421 changed files with 26115 additions and 11385 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
+4
View File
@@ -22,9 +22,13 @@ 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
+2 -2
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
#配置文件目录
+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/
+9 -21
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.20-blue"/>
@@ -12,15 +12,6 @@
[English](./README-en.md) | 简体中文
## 不同版本
我们会对以下四个版本持续维护,请选择适合自己的版本使用。最新技术栈为组合式api版本,已支持多语言(I18N)
[组合式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
@@ -42,9 +33,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 +76,7 @@ Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-adm
```
- node版本 > v16.8.3
- golang版本 >= v1.16
- golang版本 >= v1.22
- IDE推荐:Goland
```
@@ -101,11 +94,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,10 +322,7 @@ swag init
### 7.1 技术群
### QQ交流群:622360840
| QQ 群 |
| :---: |
| <img src="http://qmplusimg.henrongyi.top/qq.jpg" width="180"/> |
### QQ交流群:470239250
### 微信交流群
| 微信 |
+17 -5
View File
@@ -15,7 +15,7 @@ volumes:
services:
web:
image: node:16
image: node:20
container_name: gva-web
hostname: gva-web #可以通过容器名访问
restart: always
@@ -25,7 +25,7 @@ services:
- 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 config set registry https://registry.npmmirror.com --global && yarn install && yarn serve"
command: bash -c "yarn install && yarn serve"
volumes:
- ../../web:/web
@@ -34,15 +34,17 @@ services:
ipv4_address: 177.7.0.11
server:
image: golang:1.18
image: golang:1.22
container_name: gva-server
hostname: gva-server
restart: always
ports:
- '8888:8888'
depends_on:
- mysql
- redis
mysql:
condition: service_healthy
redis:
condition: service_healthy
volumes:
- ../../server:/server
working_dir: /server # 如果docker 设置了workdir 则此处不需要设置
@@ -67,6 +69,11 @@ services:
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:
@@ -80,6 +87,11 @@ services:
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:
+14 -2
View File
@@ -38,8 +38,10 @@ services:
ports:
- '8888:8888'
depends_on:
- mysql
- redis
mysql:
condition: service_healthy
redis:
condition: service_healthy
links:
- mysql
- redis
@@ -59,6 +61,11 @@ services:
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:
@@ -71,6 +78,11 @@ services:
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:
+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)
@@ -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")
@@ -32,8 +32,8 @@ func (b *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
}
file, err = fileUploadAndDownloadService.UploadFile(header, noSave) // 文件上传后拿到文件路径
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)
@@ -108,3 +108,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)
}
// Packaged
// @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)
}
// Packaged
// @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)
}
+108
View File
@@ -0,0 +1,108 @@
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("预览失败!", zap.Error(err))
response.FailWithMessage("预览失败", 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)
}
}
// Create
// @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
}
err = autoCodeTemplateService.AddFunc(info)
if err != nil {
global.GVA_LOG.Error("注入失败!", zap.Error(err))
response.FailWithMessage("注入失败", c)
} else {
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 -217
View File
@@ -1,98 +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
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
}
}
a.PackageT = utils.FirstUpper(a.Package)
err := autoCodeService.CreateTemp(a, 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 获取当前所有数据库
@@ -100,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)
@@ -130,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))
@@ -151,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 {
@@ -162,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)
+6 -4
View File
@@ -2,6 +2,8 @@ package system
import (
"fmt"
"net/http"
"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,7 +13,6 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
)
type SysExportTemplateApi struct {
@@ -191,11 +192,12 @@ 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
}
if file, name, err := sysExportTemplateService.ExportExcel(templateID); err != nil {
if file, name, err := sysExportTemplateService.ExportExcel(templateID, queryParams); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
@@ -205,7 +207,7 @@ func (sysExportTemplateApi *SysExportTemplateApi) ExportExcel(c *gin.Context) {
}
}
// ExportExcel 导出表格模板
// ExportTemplate 导出表格模板
// @Tags SysExportTemplate
// @Summary 导出表格模板
// @Security ApiKeyAuth
@@ -228,7 +230,7 @@ func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplate(c *gin.Context)
}
}
// 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"
)
+36 -18
View File
@@ -1,6 +1,7 @@
package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/model/common"
"strconv"
"time"
@@ -76,15 +77,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 +115,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 +200,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)
@@ -293,7 +286,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 +319,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 +352,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 +369,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 +404,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 +414,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 获取用户信息
+203 -179
View File
@@ -2,142 +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:
db: 0
addr: 127.0.0.1:6379
password: ""
#是否使用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: ""
@@ -149,95 +110,158 @@ 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:
endpoint: yourEndpoint
access-key-id: yourAccessKeyId
access-key-secret: yourAccessKeySecret
bucket-name: yourBucketName
bucket-url: yourBucketUrl
base-path: yourBasePath
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...)
}
+17 -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,18 @@ 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"`
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"`
}
+6 -3
View File
@@ -1,7 +1,10 @@
package config
type Redis struct {
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的哪个数据库
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的哪个数据库
UseCluster bool `mapstructure:"useCluster" json:"useCluster" yaml:"useCluster"` // 是否使用集群模式
ClusterAddrs []string `mapstructure:"clusterAddrs" json:"clusterAddrs" yaml:"clusterAddrs"` // 集群模式下的节点地址列表
}
+4 -4
View File
@@ -1,14 +1,14 @@
package config
type System struct {
Env string `mapstructure:"env" json:"env" yaml:"env"` // 环境值
DbType string `mapstructure:"db-type" json:"db-type" yaml:"db-type"` // 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql
OssType string `mapstructure:"oss-type" json:"oss-type" yaml:"oss-type"` // Oss类型
RouterPrefix string `mapstructure:"router-prefix" json:"router-prefix" yaml:"router-prefix"`
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()
}
+10 -9
View File
@@ -2,8 +2,6 @@ package core
import (
"fmt"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/initialize"
"github.com/flipped-aurora/gin-vue-admin/server/service/system"
@@ -18,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 {
@@ -31,24 +31,25 @@ func RunWindowsServer() {
}
Router := initialize.Routers()
Router.Static("/form-generator", "./resource/page")
address := fmt.Sprintf(":%d", global.GVA_CONFIG.System.Addr)
s := initServer(address, Router)
// 保证文本顺序输出
// In order to ensure that the text order output can be deleted
time.Sleep(10 * time.Microsecond)
global.GVA_LOG.Info("server run success on ", zap.String("address", address))
fmt.Printf(`
欢迎使用 gin-vue-admin
当前版本:v2.6.0
加群方式:微信号:shouzi_1994 QQ群:622360840
当前版本:v2.7.6
加群方式:微信号: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.EnvGinMode, internal.ConfigDefaultFile)
case gin.ReleaseMode:
config = internal.ConfigReleaseFile
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.EnvGinMode, internal.ConfigReleaseFile)
case gin.TestMode:
config = internal.ConfigTestFile
fmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.EnvGinMode, 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())
}
+1347 -261
View File
File diff suppressed because it is too large Load Diff
+1348 -262
View File
File diff suppressed because it is too large Load Diff
+843 -195
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.Client
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
}
+130 -93
View File
@@ -1,142 +1,179 @@
module github.com/flipped-aurora/gin-vue-admin/server
go 1.20
go 1.22.0
toolchain go1.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.5
github.com/casbin/casbin/v2 v2.100.0
github.com/casbin/gorm-adapter/v3 v3.28.0
github.com/fsnotify/fsnotify v1.7.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/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.3
github.com/gofrs/uuid/v5 v5.3.0
github.com/golang-jwt/jwt/v4 v4.5.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.8
github.com/mojocn/base64Captcha v1.3.6
github.com/otiai10/copy v1.14.0
github.com/pkg/errors v0.9.1
github.com/qiniu/api.v7/v7 v7.4.1
github.com/qiniu/go-sdk/v7 v7.23.0
github.com/qiniu/qmgo v1.1.8
github.com/redis/go-redis/v9 v9.0.5
github.com/redis/go-redis/v9 v9.6.2
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.9.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/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.1
gorm.io/driver/postgres v1.5.2
gorm.io/driver/sqlserver v1.5.1
gorm.io/gorm v1.25.2
nhooyr.io/websocket v1.8.7
github.com/swaggo/swag v1.16.3
github.com/tencentyun/cos-go-sdk-v5 v0.7.55
github.com/unrolled/secure v1.16.0
github.com/xuri/excelize/v2 v2.9.0
go.mongodb.org/mongo-driver v1.17.1
go.uber.org/automaxprocs v1.6.0
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.28.0
golang.org/x/sync v0.8.0
golang.org/x/text v0.19.0
gorm.io/datatypes v1.2.3
gorm.io/driver/mysql v1.5.7
gorm.io/driver/postgres v1.5.9
gorm.io/driver/sqlserver v1.5.3
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/alex-ant/gomath v0.0.0-20160516115720-89013a210a82 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
github.com/bodgit/plumbing v1.3.0 // indirect
github.com/bodgit/sevenzip v1.5.2 // indirect
github.com/bodgit/windows v1.0.1 // indirect
github.com/bytedance/sonic v1.12.3 // indirect
github.com/bytedance/sonic/loader v0.2.0 // indirect
github.com/casbin/govaluate v1.2.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.4 // indirect
github.com/cloudwego/iasm v0.2.0 // 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.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/elastic/go-sysinfo v1.14.2 // indirect
github.com/elastic/go-windows v1.0.2 // indirect
github.com/gabriel-vasile/mimetype v1.4.6 // indirect
github.com/gammazero/toposort v0.1.1 // 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/glebarez/go-sqlite v1.22.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.22.1 // 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/google/uuid v1.6.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.1 // 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/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // 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/klauspost/compress v1.17.11 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // 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.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/mattn/go-isatty v0.0.20 // indirect
github.com/microsoft/go-mssqldb v1.7.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.0-beta.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // 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/prometheus/procfs v0.15.1 // 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/sagikazarmark/locafero v0.6.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/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.7.0 // 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-20240408161823-9ad904a10d6d // indirect
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // 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.11.0 // indirect
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
golang.org/x/image v0.21.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/datatypes v1.2.0 // 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
howett.net/plist v1.0.1 // indirect
modernc.org/fileutil v1.3.0 // indirect
modernc.org/libc v1.61.0 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.8.0 // indirect
modernc.org/sqlite v1.33.1 // indirect
)
+425 -421
View File
File diff suppressed because it is too large Load Diff
+7 -2
View File
@@ -47,8 +47,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{},
@@ -83,8 +86,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{},
+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,8 +51,11 @@ func RegisterTables() {
system.SysBaseMenuParameter{},
system.SysBaseMenuBtn{},
system.SysAuthorityBtn{},
system.SysAutoCode{},
system.SysAutoCodePackage{},
system.SysExportTemplate{},
system.Condition{},
system.JoinTemplate{},
system.SysParams{},
example.ExaFile{},
example.ExaCustomer{},
@@ -56,5 +66,12 @@ func RegisterTables() {
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
}
+25 -39
View File
@@ -1,20 +1,16 @@
package internal
import (
"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"
"log"
"os"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
type DBBASE interface {
GetLogMode() string
}
var Gorm = new(_gorm)
type _gorm struct{}
@@ -22,41 +18,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, log.New(os.Stdout, "\r\n", log.LstdFlags)), 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,37 @@
package internal
import (
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/config"
"go.uber.org/zap"
"gorm.io/gorm/logger"
)
type Writer struct {
config config.GeneralDB
writer logger.Writer
}
func NewWriter(config config.GeneralDB, writer logger.Writer) *Writer {
return &Writer{config: config, writer: writer}
}
// Printf 格式化打印日志
func (c *Writer) Printf(message string, data ...any) {
if c.config.LogZap {
switch c.config.LogLevel() {
case logger.Silent:
zap.L().Debug(fmt.Sprintf(message, data...))
case logger.Error:
zap.L().Error(fmt.Sprintf(message, data...))
case logger.Warn:
zap.L().Warn(fmt.Sprintf(message, data...))
case logger.Info:
zap.L().Info(fmt.Sprintf(message, data...))
default:
zap.L().Info(fmt.Sprintf(message, data...))
}
return
}
c.writer.Printf(message, data...)
}
-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...)
}
}
+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)
}
+44 -12
View File
@@ -3,25 +3,57 @@ 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
client := redis.NewClient(&redis.Options{
Addr: redisCfg.Addr,
Password: redisCfg.Password, // no password set
DB: redisCfg.DB, // use default DB
})
func initRedisClient(redisCfg config.Redis) (redis.UniversalClient, error) {
var client redis.UniversalClient
// 使用集群模式
if redisCfg.UseCluster {
client = redis.NewClusterClient(&redis.ClusterOptions{
Addrs: redisCfg.ClusterAddrs,
Password: redisCfg.Password,
})
} else {
// 使用单例模式
client = redis.NewClient(&redis.Options{
Addr: redisCfg.Addr,
Password: redisCfg.Password,
DB: redisCfg.DB,
})
}
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
}
+42 -19
View File
@@ -1,55 +1,70 @@
package initialize
import (
swaggerFiles "github.com/swaggo/files"
"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"
"github.com/flipped-aurora/gin-vue-admin/server/router"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)
type justFilesFilesystem struct {
fs http.FileSystem
}
func (fs justFilesFilesystem) Open(name string) (http.File, error) {
f, err := fs.fs.Open(name)
if err != nil {
return nil, err
}
stat, err := f.Stat()
if stat.IsDir() {
return nil, os.ErrPermission
}
return f, nil
}
// 初始化总路由
func Routers() *gin.Engine {
// 设置为发布模式
if global.GVA_CONFIG.System.Env == "public" {
gin.SetMode(gin.ReleaseMode) //DebugMode ReleaseMode TestMode
}
Router := gin.New()
Router.Use(gin.Recovery())
if global.GVA_CONFIG.System.Env != "public" {
if gin.Mode() == gin.DebugMode {
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("/static", "./dist/static") // 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, http.Dir(global.GVA_CONFIG.Local.StorePath)) // 为用户头像和文件提供静态地址
// Router.Use(middleware.LoadTls()) // 如果需要使用https 请打开此中间件 然后前往 core/server.go 将启动模式 更变为 Router.RunTLS("端口","你的cre/pem文件","你的key文件")
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) {
@@ -60,8 +75,7 @@ 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相关路由
@@ -69,19 +83,28 @@ func Routers() *gin.Engine {
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
systemRouter.InitSystemRouter(PrivateGroup) // system相关路由
systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由
systemRouter.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码
systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码
systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由
systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理
systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史
systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 字典详情管理
systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 按钮权限管理
systemRouter.InitSysExportTemplateRouter(PrivateGroup) // 导出模板
systemRouter.InitSysParamsRouter(PrivateGroup, PublicGroup) // 参数管理
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
exampleRouter.InitFileUploadAndDownloadRouter(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)
}
+3 -3
View File
@@ -1,11 +1,11 @@
package main
import (
"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,7 +14,7 @@ import (
//go:generate go mod download
// @title Gin-Vue-Admin Swagger API接口文档
// @version v2.6.0
// @version v2.7.6
// @description 使用gin+vue进行极速开发的全栈开发基础平台
// @securityDefinitions.apikey ApiKeyAuth
// @in header
+14 -16
View File
@@ -16,22 +16,20 @@ var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
// CasbinHandler 拦截器
func CasbinHandler() gin.HandlerFunc {
return func(c *gin.Context) {
if global.GVA_CONFIG.System.Env != "develop" {
waitUse, _ := utils.GetClaims(c)
//获取请求的PATH
path := c.Request.URL.Path
obj := strings.TrimPrefix(path, global.GVA_CONFIG.System.RouterPrefix)
// 获取请求方法
act := c.Request.Method
// 获取用户的角色
sub := strconv.Itoa(int(waitUse.AuthorityId))
e := casbinService.Casbin() // 判断策略中是否存在
success, _ := e.Enforce(sub, obj, act)
if !success {
response.FailWithDetailed(gin.H{}, "权限不足", c)
c.Abort()
return
}
waitUse, _ := utils.GetClaims(c)
//获取请求的PATH
path := c.Request.URL.Path
obj := strings.TrimPrefix(path, global.GVA_CONFIG.System.RouterPrefix)
// 获取请求方法
act := c.Request.Method
// 获取用户的角色
sub := strconv.Itoa(int(waitUse.AuthorityId))
e := casbinService.Casbin() // 判断策略中是否存在
success, _ := e.Enforce(sub, obj, act)
if !success {
response.FailWithDetailed(gin.H{}, "权限不足", c)
c.Abort()
return
}
c.Next()
}
+13 -14
View File
@@ -3,10 +3,8 @@ 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"
"strconv"
"time"
@@ -23,12 +21,12 @@ func JWTAuth() gin.HandlerFunc {
// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
token := utils.GetToken(c)
if token == "" {
response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
response.NoAuth("未登录或非法访问", c)
c.Abort()
return
}
if jwtService.IsBlacklist(token) {
response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
response.NoAuth("您的帐户异地登陆或令牌失效", c)
utils.ClearToken(c)
c.Abort()
return
@@ -38,12 +36,12 @@ func JWTAuth() gin.HandlerFunc {
claims, err := j.ParseToken(token)
if err != nil {
if errors.Is(err, utils.TokenExpired) {
response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
response.NoAuth("授权已过期", c)
utils.ClearToken(c)
c.Abort()
return
}
response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
response.NoAuth(err.Error(), c)
utils.ClearToken(c)
c.Abort()
return
@@ -58,7 +56,6 @@ func JWTAuth() gin.HandlerFunc {
// c.Abort()
//}
c.Set("claims", claims)
c.Next()
if claims.ExpiresAt.Unix()-time.Now().Unix() < claims.BufferTime {
dr, _ := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(dr))
@@ -68,15 +65,17 @@ 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)
}
}
c.Next()
if newToken, exists := c.Get("new-token"); exists {
c.Header("new-token", newToken.(string))
}
if newExpiresAt, exists := c.Get("new-expires-at"); exists {
c.Header("new-expires-at", newExpiresAt.(string))
}
}
}
+7 -3
View File
@@ -71,14 +71,18 @@ func OperationRecord() gin.HandlerFunc {
Method: c.Request.Method,
Path: c.Request.URL.Path,
Agent: c.Request.UserAgent(),
Body: string(body),
Body: "",
UserID: userId,
}
// 上传文件时候 中间件日志进行裁断操作
if strings.Contains(c.GetHeader("Content-Type"), "multipart/form-data") {
if len(record.Body) > bufferSize {
record.Body = "[文件]"
record.Body = "[文件]"
} else {
if len(body) > bufferSize {
record.Body = "[超出记录长度]"
} else {
record.Body = string(body)
}
}
+36
View File
@@ -0,0 +1,36 @@
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
}
+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
+9 -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) {
@@ -50,6 +50,14 @@ func FailWithMessage(message string, c *gin.Context) {
Result(ERROR, map[string]interface{}{}, message, c)
}
func NoAuth(message string, c *gin.Context) {
c.JSON(http.StatusUnauthorized, Response{
7,
nil,
message,
})
}
func FailWithDetailed(data interface{}, message string, c *gin.Context) {
Result(ERROR, data, message, c)
}
@@ -0,0 +1,267 @@
package request
import (
"encoding/json"
"fmt"
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"` // 是否只生成模板
Fields []*AutoCodeField `json:"fields"`
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 一对多
}
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 {
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.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"` // 是否鉴权
}
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,27 @@
package request
import (
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:"包名"`
}
func (r *SysAutoCodePackageCreate) AutoCode() AutoCode {
return AutoCode{
Package: r.PackageName,
}
}
func (r *SysAutoCodePackageCreate) Create() model.SysAutoCodePackage {
return model.SysAutoCodePackage{
Desc: r.Desc,
Label: r.Label,
Template: r.Template,
PackageName: r.PackageName,
}
}
@@ -1,13 +1,56 @@
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,
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}
}
+3 -2
View File
@@ -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"},
}
}
+28 -7
View File
@@ -7,13 +7,14 @@ 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数据库文件路径
}
// MysqlEmptyDsn msyql 空数据库 建库链接
@@ -47,6 +48,10 @@ func (i *InitDB) SqliteEmptyDsn() string {
return i.DBPath + separator + i.DBName + ".db"
}
func (i *InitDB) MssqlEmptyDsn() string {
return "sqlserver://" + i.UserName + ":" + i.Password + "@" + i.Host + ":" + i.Port + "?database=" + i.DBName + "&encrypt=disable"
}
// ToMysqlConfig 转换 config.Mysql
// Author [SliverHorn](https://github.com/SliverHorn)
func (i *InitDB) ToMysqlConfig() config.Mysql {
@@ -100,3 +105,19 @@ func (i *InitDB) ToSqliteConfig() config.Sqlite {
},
}
}
func (i *InitDB) ToMssqlConfig() config.Mssql {
return config.Mssql{
GeneralDB: config.GeneralDB{
Path: i.DBPath,
Port: i.Port,
Dbname: i.DBName,
Username: i.UserName,
Password: i.Password,
MaxIdleConns: 10,
MaxOpenConns: 100,
LogMode: "error",
Config: "",
},
}
}
+1 -1
View File
@@ -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
}
+9
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"
)
@@ -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"`
-122
View File
@@ -1,122 +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
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,67 @@
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:结构体名称"`
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,17 @@
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:包名"`
}
func (s *SysAutoCodePackage) TableName() string {
return "sys_auto_code_packages"
}
@@ -1,40 +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"`
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:地址栏携带参数的值"` // 地址栏携带参数的值
}
+1 -1
View File
@@ -9,7 +9,7 @@ import (
type SysDictionaryDetail struct {
global.GVA_MODEL
Label string `json:"label" form:"label" gorm:"column:label;comment:展示值"` // 展示值
Value int `json:"value" form:"value" gorm:"column:value;comment:字典值"` // 字典值
Value string `json:"value" form:"value" gorm:"column:value;comment:字典值"` // 字典值
Extend string `json:"extend" form:"extend" gorm:"column:extend;comment:扩展值"` // 扩展值
Status *bool `json:"status" form:"status" gorm:"column:status;comment:启用状态"` // 启用状态
Sort int `json:"sort" form:"sort" gorm:"column:sort;comment:排序标记"` // 排序标记
+33 -4
View File
@@ -8,8 +8,37 @@ import (
// 导出模板 结构体 SysExportTemplate
type SysExportTemplate struct {
global.GVA_MODEL
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;"` //模板信息
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 {
global.GVA_MODEL
TemplateID string `json:"templateID" form:"templateID" gorm:"column:template_id;comment:模板标识"`
From string `json:"from" form:"from" gorm:"column:from;comment:条件取的key"`
Column string `json:"column" form:"column" gorm:"column:column;comment:作为查询条件的字段"`
Operator string `json:"operator" form:"operator" gorm:"column:operator;comment:操作符"`
}
func (Condition) TableName() string {
return "sys_export_template_condition"
}
+1 -1
View File
@@ -15,7 +15,7 @@ type SysOperationRecord struct {
Path string `json:"path" form:"path" gorm:"column:path;comment:请求路径"` // 请求路径
Status int `json:"status" form:"status" gorm:"column:status;comment:请求状态"` // 请求状态
Latency time.Duration `json:"latency" form:"latency" gorm:"column:latency;comment:延迟" swaggertype:"string"` // 延迟
Agent string `json:"agent" form:"agent" gorm:"column:agent;comment:代理"` // 代理
Agent string `json:"agent" form:"agent" gorm:"type:text;column:agent;comment:代理"` // 代理
ErrorMessage string `json:"error_message" form:"error_message" gorm:"column:error_message;comment:错误信息"` // 错误信息
Body string `json:"body" form:"body" gorm:"type:text;column:body;comment:请求Body"` // 请求Body
Resp string `json:"resp" form:"resp" gorm:"type:text;column:resp;comment:响应Body"` // 响应Body
+20
View File
@@ -0,0 +1,20 @@
// 自动生成模板SysParams
package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
)
// 参数 结构体 SysParams
type SysParams struct {
global.GVA_MODEL
Name string `json:"name" form:"name" gorm:"column:name;comment:参数名称;" binding:"required"` //参数名称
Key string `json:"key" form:"key" gorm:"column:key;comment:参数键;" binding:"required"` //参数键
Value string `json:"value" form:"value" gorm:"column:value;comment:参数值;" binding:"required"` //参数值
Desc string `json:"desc" form:"desc" gorm:"column:desc;comment:参数说明;"` //参数说明
}
// TableName 参数 SysParams自定义表名 sys_params
func (SysParams) TableName() string {
return "sys_params"
}
+48 -14
View File
@@ -2,27 +2,61 @@ package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common"
"github.com/gofrs/uuid/v5"
)
type Login interface {
GetUsername() string
GetNickname() string
GetUUID() uuid.UUID
GetUserId() uint
GetAuthorityId() uint
GetUserInfo() any
}
var _ Login = new(SysUser)
type SysUser struct {
global.GVA_MODEL
UUID uuid.UUID `json:"uuid" gorm:"index;comment:用户UUID"` // 用户UUID
Username string `json:"userName" gorm:"index;comment:用户登录名"` // 用户登录名
Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
SideMode string `json:"sideMode" gorm:"default:dark;comment:用户侧边主题"` // 用户侧边主题
HeaderImg string `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
BaseColor string `json:"baseColor" gorm:"default:#fff;comment:基础颜色"` // 基础颜色
ActiveColor string `json:"activeColor" gorm:"default:#1890ff;comment:活跃颜色"` // 活跃颜色
AuthorityId uint `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID
Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"`
Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"`
Phone string `json:"phone" gorm:"comment:用户手机号"` // 用户手机号
Email string `json:"email" gorm:"comment:用户邮箱"` // 用户邮箱
Enable int `json:"enable" gorm:"default:1;comment:用户是否被冻结 1正常 2冻结"` //用户是否被冻结 1正常 2冻结
UUID uuid.UUID `json:"uuid" gorm:"index;comment:用户UUID"` // 用户UUID
Username string `json:"userName" gorm:"index;comment:用户登录名"` // 用户登录名
Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
HeaderImg string `json:"headerImg" gorm:"default:https://qmplusimg.henrongyi.top/gva_header.jpg;comment:用户头像"` // 用户头像
AuthorityId uint `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID
Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"` // 用户角色
Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"` // 多用户角色
Phone string `json:"phone" gorm:"comment:用户手机号"` // 用户手机号
Email string `json:"email" gorm:"comment:用户邮箱"` // 用户邮箱
Enable int `json:"enable" gorm:"default:1;comment:用户是否被冻结 1正常 2冻结"` //用户是否被冻结 1正常 2冻结
OriginSetting common.JSONMap `json:"originSetting" form:"originSetting" gorm:"type:text;default:null;column:origin_setting;comment:配置;"` //配置
}
func (SysUser) TableName() string {
return "sys_users"
}
func (s *SysUser) GetUsername() string {
return s.Username
}
func (s *SysUser) GetNickname() string {
return s.NickName
}
func (s *SysUser) GetUUID() uuid.UUID {
return s.UUID
}
func (s *SysUser) GetUserId() uint {
return s.ID
}
func (s *SysUser) GetAuthorityId() uint {
return s.AuthorityId
}
func (s *SysUser) GetUserInfo() any {
return *s
}
-4
View File
@@ -1,4 +0,0 @@
//go:build !packfile
// +build !packfile
package packfile
-45
View File
@@ -1,45 +0,0 @@
//go:build packfile
// +build packfile
package packfile
import (
"fmt"
"os"
"path/filepath"
"strings"
)
//go:generate go-bindata -o=staticFile.go -pkg=packfile -tags=packfile ../resource/... ../config.yaml
func writeFile(path string, data []byte) {
// 如果文件夹不存在,预先创建文件夹
if lastSeparator := strings.LastIndex(path, "/"); lastSeparator != -1 {
dirPath := path[:lastSeparator]
if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) {
os.MkdirAll(dirPath, os.ModePerm)
}
}
// 已存在的文件,不应该覆盖重写,可能在前端更改了配置文件等
if _, err := os.Stat(path); os.IsNotExist(err) {
if err2 := os.WriteFile(path, data, os.ModePerm); err2 != nil {
fmt.Printf("Write file failed: %s\n", path)
}
} else {
fmt.Printf("File exist, skip: %s\n", path)
}
}
func init() {
for key := range _bindata {
filePath, _ := filepath.Abs(strings.TrimPrefix(key, "."))
data, err := Asset(key)
if err != nil {
// Asset was not found.
fmt.Printf("Fail to find: %s\n", filePath)
} else {
writeFile(filePath, data)
}
}
}
+10
View File
@@ -0,0 +1,10 @@
package api
import "github.com/flipped-aurora/gin-vue-admin/server/plugin/announcement/service"
var (
Api = new(api)
serviceInfo = service.Service.Info
)
type api struct{ Info info }

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