Compare commits

...
621 Commits
Author SHA1 Message Date
千石 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
piexlMax 17cab8fcb7 更换版本号 2024-01-28 16:40:08 +08:00
Krane d64753859d 解决drawer和dialog层级冲突问题 (#1640) 2024-01-26 14:35:54 +08:00
piexlMax 48b1c24c95 [fixed]:修复超出26个英文字母后表格的导出导入bug 2024-01-25 19:41:52 +08:00
piexlmax(奇淼 7e5e12b139 前端dist代码位置变更 2024-01-25 16:14:28 +08:00
59ba4752c0 [server/config/system.go]: fix a comment error (#1638)
Co-authored-by: liweiwu.wlw <liweiwu.wlw@xiaoman.cn>
Co-authored-by: 奇淼(piexlmax <303176530@qq.com>
2024-01-24 16:01:36 +08:00
piexlmax(奇淼 189219c673 typo修复 2024-01-24 15:59:02 +08:00
piexlmax(奇淼 4b54262edd Merge remote-tracking branch 'origin/main' 2024-01-24 15:50:37 +08:00
piexlmax(奇淼 458b035a7e 增加字典方法 GetDictionaryList,GetDictionaryListByType,GetDictionaryInfoByValue, GetDictionaryInfoByTypeValue 方便后台直接获取字典属性
前端增加extend属性获取
2024-01-24 15:50:15 +08:00
piexlmax(奇淼 abe85cf6e7 增加字典方法 GetDictionaryList,GetDictionaryListByType,GetDictionaryInfoByValue, GetDictionaryInfoByTypeValue 方便后台直接获取字典属性
前端增加extend属性获取
2024-01-24 15:50:14 +08:00
奇淼(piexlmax 379b63275a 自动化代码可选不使用官方global.Model结构 (#1637)
* 自动化代码可自行选择默认结构

* 调整自动化模板

* 增加自动化模板中对timer的处理
2024-01-22 17:37:03 +08:00
yunshengand01471076 07cde689b1 mongo use auth-source (#1635)
Co-authored-by: 01471076 <yangyunsheng.it@haier.com>
2024-01-20 12:33:27 +08:00
薛定饿了不养喵 26606f138d 修改样式 系统工具 -> 代码生成器 下的 '点这里从现有数据库创建代码' 内容显示不全 (#1632) 2024-01-20 12:33:10 +08:00
haimait 24c4774f7e 代码打包的插件,从后台安装失败,认不到目录的问题 (#1634)
https://github.com/flipped-aurora/gin-vue-admin/issues/1633
2024-01-20 12:32:59 +08:00
xuedinge 6bbb4f577e 修改样式 系统工具 -> 代码生成器 下的 '点这里从现有数据库创建代码' 内容显示不全 2024-01-18 18:48:47 +08:00
piexlMax(奇淼 4890de5052 Merge remote-tracking branch 'upstream/main' 2024-01-18 13:16:52 +08:00
haimait 746af37899 解决打包插件解压报错的问题 (#1630)
https://github.com/flipped-aurora/gin-vue-admin/issues/1628
2024-01-18 13:16:39 +08:00
haimait 0136ce7034 解决打包插件解压报错的问题 (#1630)
https://github.com/flipped-aurora/gin-vue-admin/issues/1628
2024-01-18 13:11:54 +08:00
piexlMax(奇淼 5ca47a91a6 开发环境允许设置cookie 2024-01-18 13:08:14 +08:00
piexlMax(奇淼 d849df41be 代码定位功能默认关闭。 2024-01-17 16:05:32 +08:00
奇淼(piexlmax a2269bcdd5 优化自定义图标功能,修复上线后无法展示自定义图标的问题。 (#1625)
* 修改自定义图标使用方式

* 优化自定义icon功能
2024-01-16 22:07:59 +08:00
ipanghu d41394c70a fix:修复首页 dashboard echarts 页面变化导致的变性, 修复 vite.config.js 中 proxy 代理 https 时的 bug (#1623)
add : 添加 “@vueuse/core” 的依赖,添加全局 hooks (use-windows-resize)使用方法查看 dashboard 页面
2024-01-15 13:10:42 +08:00
haimait 756f73bbd2 修复代码生成器 列表中数据库字段描述回显错误 (#1622) 2024-01-15 13:10:24 +08:00
piexlMax 95eb17b6d1 [fixed]:默认注释静态资源 2024-01-13 12:38:07 +08:00
piexlMax 773fd1f221 Merge remote-tracking branch 'origin/main' 2024-01-13 12:09:49 +08:00
piexlMax c95b436680 [fixed]:静态资源基础path修复 2024-01-13 12:08:37 +08:00
piexlmax(奇淼 3f47151678 默认增加 gorm.io/datatypes 2024-01-11 15:57:20 +08:00
piexlmax(奇淼 dbf1e7136c 调整更换绑定后的自动化代码结构 2024-01-11 15:56:38 +08:00
piexlMax 84b44eef91 [fixed]:调整过期token更换new-token时间,防止多机操作业务延迟带来的token失效的bug 2024-01-08 21:50:25 +08:00
piexlMax 686ada1e49 [fixed]:调整自动化表格TemplateInfo字段类型为text防止超长 2024-01-08 19:55:21 +08:00
piexlmax(奇淼 d9f6bc058a 调整自动化验证为gin自带binding tag 2024-01-08 16:45:19 +08:00
piexlMax 6f531793f0 清理错误添加的测试代码 2024-01-06 17:26:39 +08:00
piexlMax f8794bef5f 导入导出功能性bug修复 2024-01-06 16:16:50 +08:00
piexlMax 9daf103669 增加导入成功回调 2024-01-05 23:27:59 +08:00
piexlMax 26fa047fe4 基于cookie模式下,剔除所有的上传文件的x-token头 2024-01-05 23:13:04 +08:00
piexlMax 1a04bb535d 增加表格导入,增加导入模板下载,修复日志中间件的截断bug。 2024-01-05 23:09:07 +08:00
piexlMax ad41b7b434 [fixed]:初始化添加自动导出功能表 2024-01-05 21:28:57 +08:00
piexlMax 6791b1dbdc [fixed]:修复切换角色不生效的bug 2024-01-05 20:11:16 +08:00
piexlMax dc1b84130c 完善cookie模式 2024-01-04 22:25:13 +08:00
piexlMax e70a933090 完善cookie模式 2024-01-04 22:21:37 +08:00
piexlMax 08617f2fd4 完善cookie模式 2024-01-04 22:15:54 +08:00
thy 8aefb5db8e feat: 开启recovery (#1615) 2024-01-04 17:06:52 +08:00
piexlMax(奇淼 e1d214b91a 剔除GPT相关功能,后续独立新开源项目制作。 2024-01-03 14:49:28 +08:00
奇淼(piexlmax 0285de50e5 修复#1611提及的反引号导致pgsql搜索不支持的bug (#1612) 2024-01-03 11:21:08 +08:00
piexlmax(奇淼 5f7caa0535 降低自定义button圆角权重 2024-01-02 17:23:34 +08:00
piexlMax df9d2bc472 消除误提交的测试代码 2023-12-31 20:22:47 +08:00
piexlMax a923b6beca 更新版本号2.5.9 2023-12-31 11:09:00 +08:00
piexlMax 760ef77593 消除误提交的测试代码 2023-12-30 20:49:24 +08:00
piexlMax 64f703856e 调整初始化信息 2023-12-30 20:42:24 +08:00
piexlMax 36eba36bf2 调整建表结构 2023-12-30 20:32:05 +08:00
piexlMax 332176a619 增加新功能初始化数据 2023-12-30 20:29:49 +08:00
piexlMax cd5b60c8cc 增加excel模板配置,增加前端导出工具。token迁移至cookie x-token且保留header x-token 两者兼容。 2023-12-30 20:29:47 +08:00
thy 5ea8947fc9 feat: 将placeholder替换为tooltip (#1606) 2023-12-28 09:55:32 +08:00
piexlmax(奇淼 474a5c8e42 清理RemoveTaskByName的重复锁导致系统卡死的问题 2023-12-26 09:53:26 +08:00
piexlMax 952062d5be 调整弹出气泡无法取消的bug 2023-12-25 22:04:27 +08:00
奇淼(piexlmax c071564de4 Update ci.yaml 2023-12-25 10:26:50 +08:00
huoxiao b2fa7563d3 web/src/view/routerHolder.vue:Fix Vue warn Component inside <Transition> renders non-element root node that cannot be animated (#1603) 2023-12-25 09:53:45 +08:00
piexlmax(奇淼 22f68fedcb swag文档默认属性调整 2023-12-22 10:27:51 +08:00
奇淼(piexlmax 0a4cda26cb Update README.md 2023-12-22 10:19:21 +08:00
piexlmax(奇淼 54eb84e690 将task拆分为cron与task两部分,使其呈现父子结构,切单独可控。 2023-12-22 10:08:54 +08:00
piexlmax(奇淼 5cd33814fc 将task拆分为cron与task两部分,使其呈现父子结构,切单独可控。 2023-12-22 09:55:57 +08:00
奇淼(piexlmax 90f19679e7 Update README.md 2023-12-19 17:26:43 +08:00
奇淼(piexlmax 38ade9e498 Update go.mod 2023-12-19 17:26:07 +08:00
faker-wang 4c77831001 zapcore.WarnLevel修改成zapcore.ErrorLevel (#1602) 2023-12-19 17:17:02 +08:00
piexlMax 722fe556e3 增加初始字典内容,兼容自动化使用pgsql读取表的数据格式 2023-12-17 17:40:00 +08:00
xinyan818 98b83c0078 fix: typo (#1591) 2023-12-13 15:01:35 +08:00
yang hao 85646b5ffa sys_auto_code fix: log文字提示错误 (#1592) 2023-12-13 15:01:19 +08:00
Zmzblink d3f5ed7d60 修改el-tag中type属性的默认值, type属性枚举不包含primary (#1593) 2023-12-13 15:01:02 +08:00
piexlmax(奇淼 e0a8e93704 定位功能调整为 shift+alt+左键 2023-12-12 10:50:23 +08:00
piexlmax(奇淼 3aab5e9eb7 路由增加meta.client 属性,添加本属性为true则跳过前端路由拦截器 2023-12-11 16:28:40 +08:00
piexlMax 2307ac88cb 对不合法名称icon做检测停止加入图标库 2023-12-10 23:47:30 +08:00
piexlMax 0f2018d913 增加自动icon功能,所有添加到web/assets/icons下的svg会自动被注册为icon组件使用【可用于menu和直接用标签加文件名使用】 2023-12-10 23:30:39 +08:00
piexlMax 8b9a75ba5a 清除ast中无用的测试用例 2023-12-06 23:06:43 +08:00
SliverHorn 7872e0ce38 Update: 修复mongodb index默认name太长而导致创建索引失败, 在组装keys数据进行排序以便符合bson.M的构造 (#1580) 2023-12-05 23:04:23 +08:00
xinyan818 d28ac73987 fix: use db list (#1588) 2023-12-05 23:03:54 +08:00
ning2510 2c8c7a8b51 Update ast_gorm_test.go (#1587) 2023-12-05 23:01:50 +08:00
奇淼(piexlmaxandyang hao f98fc6bf3c swag中id错误问题的修复 (#1589)
* model.go: fix swagger请求的id问题

* 验证码逻辑修回

---------

Co-authored-by: yang hao <1013055366@qq.com>
2023-12-05 23:01:27 +08:00
奇淼(piexlmax d42958734f 清理掉定时任务config配置,修改为代码内书写 (#1584) 2023-12-04 22:12:01 +08:00
piexlMax 6f2c785713 调整为新的timer模式 增加每个task内具体方法的描述方便对接后续的页面控制 2023-12-04 22:12:01 +08:00
奇淼(piexlmax 05a1ce51f0 清理掉定时任务config配置,修改为代码内书写 (#1584) 2023-12-04 22:05:19 +08:00
piexlMax(奇淼 58b063770d 调整swag 2023-12-01 14:42:54 +08:00
Sun Dadiand奇淼(piexlmax 6f9a83709d [selectImage.vue]: 增加selectImage组件,最多上传图片的功能 (#1568)
* 增加selectImage组件,最多上传图片的功能

* 增加selectImage组件,最多上传图片的功能

* Update config.yaml

* Update config.yaml

---------

Co-authored-by: 奇淼(piexlmax <qimiaojiangjizhao@gmail.com>
2023-11-21 22:54:39 +08:00
奇淼(piexlmax bd2a3ddfba 清理掉定时任务config配置,修改为代码内书写 (#1578) 2023-11-20 23:38:15 +08:00
SliverHorn 4433b6623e Merge pull request #1577 from flipped-aurora/transaction
[feature]:调整角色的创建,删除操作为事务模式
2023-11-19 14:17:30 +08:00
piexlMax e1ca17637f casbin相关操作修改为事务 2023-11-19 11:50:30 +08:00
ZongQiangandzongqiang 5ef0e43312 缺少事务可能出现数据不一致风险 (#1575)
Co-authored-by: zongqiang <zongq@rp-pet.cn>
2023-11-18 22:20:26 +08:00
aa6ca95f13 初始化失败panic (#1573)
* 初始化失败panic

* Update gorm_mssql.go

* Update gorm_pgsql.go

* Update gorm_mysql.go

---------

Co-authored-by: zongqiang <zongq@rp-pet.cn>
Co-authored-by: 奇淼(piexlmax <qimiaojiangjizhao@gmail.com>
2023-11-18 21:01:44 +08:00
奇淼(piexlmax 2523467c97 Update LICENSE 2023-11-15 16:31:51 +08:00
奇淼(piexlmax b38eb6709e Update README.md 2023-11-14 10:38:25 +08:00
piexlMax(奇淼 f6dacdb046 优化自动化模板,防止按钮被折叠 2023-11-13 11:03:51 +08:00
piexlMax(奇淼 cc0903f74d 调整表格的适配性 2023-11-13 10:53:30 +08:00
piexlMax(奇淼 72936fc0d1 版权信息不再和appName绑定 2023-11-07 14:48:22 +08:00
SliverHorn 4b7f552885 Merge pull request #1569 from 729343861/main
web/src/view/systemTools/system/system.vue : fix 图形验证码配置 bug
2023-11-06 11:25:17 +08:00
729343861 9b2fc60d79 web/src/view/systemTools/system/system.vue : fix 图形验证码配置 bug 2023-11-06 11:09:12 +08:00
piexlMax 3e5a26b95a 修改开发环境的中间件 2023-11-04 21:48:01 +08:00
SliverHorn a5f3139784 fixed: deploy/docker/Dockerfile #1518 (#1567) 2023-10-31 17:52:38 +08:00
piexlMax 9ca9fcdb09 SelectFile组件建议添加limit和accept属性,控制文件的上传数量和类型 2023-10-26 22:41:37 +08:00
piexlMax 913db35b23 添加分配菜单和分配api的滚动条 2023-10-26 22:26:04 +08:00
piexlMax(奇淼 8eba3ba4f7 修复字典展示bug
修复自动化代码字典类型渲染bug
2023-10-25 17:14:09 +08:00
piexlMax(奇淼 5bd0f24a84 增加package为空判断 #1564
Co-authored-by: @saikey0379
2023-10-24 18:42:50 +08:00
piexlMax e8fb3180db 字典使用模式调整 2023-10-22 20:59:47 +08:00
SliverHorn 232aaad090 feature: mongoDB 支持 (#1565)
* feature: mongoDB 支持

* update: 修改错误mongo索引示例

* update: 在system添加use-mongo 开关开启或者关闭mongo
2023-10-14 13:59:30 +08:00
piexlMax(奇淼 b3dbb8d4be 解决打包错误的bug 2023-10-10 18:57:46 +08:00
piexlMax(奇淼 3caf070056 优化打包 2023-10-10 18:52:39 +08:00
piexlMax(奇淼 1e24bbc3e2 修复UI BUG #1562 2023-10-10 16:46:08 +08:00
18694fd24a 修复富文本bug,调整日志输出,修复已知bug (#1563)
* operation.go: fix 调用respPool.Put归还对象前清空对象会造成下次调用无法正常copy
redis.go: fix NewDefaultRedisStore方法实例化的对象直接使用会造成空指针异常

* 设置为发布模式时gin不再输出路由信息log

* 调整基础配置文件

* 修复富文本不回显的bug

---------

Co-authored-by: liuyahui <liuyahui@wjacloud.com>
Co-authored-by: Alan <alan.cd@qq.com>
Co-authored-by: wuqianang <wuqianang@163.com>
Co-authored-by: task <ms.yangdan@gmail.com>
2023-10-10 16:41:55 +08:00
piexlMax(奇淼 10dc003f20 修复富文本未创建前端输入字段的bug 2023-10-10 16:04:23 +08:00
809e2496c0 增加了自动化视频以及修复了一些已知漏洞 (#1554)
* 解决bug:为角色添加权限时,如果有重复api权限,该角色所有权限均添加失败(包括登录)

* 支持视频上传和选用。视频首帧作为封面预览。

* 增加自动化代码视频选项

* 媒体库可上传视频
SelectImage组件增加参数file-type="image|video" 方便用户对媒体库可选内容做限制

* 自动化代码bug修复

---------

Co-authored-by: liuyahui <liuyahui@wjacloud.com>
Co-authored-by: Alan <alan.cd@qq.com>
2023-09-24 15:49:58 +08:00
奇淼(piexlmax c1c37901b5 Merge pull request #1550 from Suixinee/main
初步构建了文件预览组件
2023-09-24 14:50:57 +08:00
SliverHorn 44e115f211 update: 去掉 github.com/lestrrat-go/file-rotatelogs 库的依赖, 实现zap.String("business", "xx")自定义业务日志数据路径, 输出文件路径为./global.GVA_CONFIG.Zap.Director/2006-01-02/xx/level(debug, info, warn, error, dpanic, panic, fatal).log (#1551) 2023-09-24 14:35:54 +08:00
ipanghu 217cc338a8 fix:修复自动代码的详情页面的bug,选择器,输入框添加 中文名称 (#1552) 2023-09-24 14:35:34 +08:00
suixinee 81eccc177d 初步文件预览组件构建 2023-09-22 10:47:16 +08:00
碎心Eand奇淼(piexlmax 4ea00b7e7b 调整了文件上传无法异步赋值的bug (#1547)
* watch了immediate参数,防止组件异步调用获取数据失败的问题

* watch添加了immediate参数,防止组件异步调用获取不到数据

* Update selectFile.vue

---------

Co-authored-by: 奇淼(piexlmax <qimiaojiangjizhao@gmail.com>
2023-09-19 16:08:35 +08:00
奇淼(piexlmax 844699263d Update selectFile.vue 2023-09-19 16:08:14 +08:00
suixinee d72a548852 watch添加了immediate参数,防止组件异步调用获取不到数据 2023-09-19 12:05:21 +08:00
suixinee 722ed9bece watch了immediate参数,防止组件异步调用获取数据失败的问题 2023-09-19 11:57:41 +08:00
SummerBytes 8852367837 codeServer: fix 删除无用代码 (#1541) 2023-09-15 11:50:10 +08:00
piexlMax 5559f9b9af 调整模板代码中的中文解释 2023-09-15 11:44:16 +08:00
piexlMax 39526edafd 代码模板调整name挂载位置 2023-09-14 18:49:59 +08:00
piexlMax a4f86354d3 前端eslint调整 2023-09-14 18:47:47 +08:00
piexlMax 636204bbaf 修复eslint问题 2023-09-14 18:06:26 +08:00
piexlMax 08494834c2 字典增加扩展值字段,优化自动化生成搜索条件默认语句。 2023-09-13 21:33:36 +08:00
piexlMax 2247f34b89 修改富文本组件默认高度 2023-09-13 11:42:25 +08:00
tomoyo233 5c84412238 Update sys_user.go (#1540)
验证码bug修复
2023-09-10 23:03:14 +08:00
piexlMax 13112aa4d8 调整table模板让详情功能适配多种数据类型 2023-09-10 00:27:46 +08:00
zyw0605688 836a165ff2 bugfix:'升级gin-swagger到最新版,解决swagger-ui界面上的Cannot read properties of undefined (reading '1')报错' (#1538) 2023-09-09 13:17:17 +08:00
piexlMax f36e0b39ed 修复#1537 环境变量不生效的问题 2023-09-09 11:25:55 +08:00
Jamieandmazhenming 74e2ec74e0 resource/autocode_template/server/model.go.tpl: swag文档添加中文信息 (#1535)
Co-authored-by: mazhenming <zhenmingma@qq.com>
2023-09-09 11:03:04 +08:00
zyw0605688 bcb6243f3b 批量删除按钮,未选中内容时不应该弹出确定提醒 (#1536)
table的批量删除按钮,未选中内容时候,悬浮提醒不应该显示。增加以下代码
:disabled="!multipleSelection.length"
2023-09-09 11:02:26 +08:00
piexlMax c00b628fb4 [fixed]修复业务库生成代码回滚时候删表位置错误的bug。 2023-09-08 16:54:41 +08:00
piexlMax 2fbed17ebc [fixed]修复业务库生成代码gorm自动迁移数据库name错误的问题。 2023-09-08 16:37:58 +08:00
Felixs 7bfea23958 补充form.vue里遗漏的SelectFile自动化组件 2023-09-06 11:40:30 +08:00
Felixs 91c567779b 恢复 btnAuth 2023-09-05 11:00:36 +08:00
piexlMax c4aeeb419e [update] 清理了一些无用文件 2023-08-31 18:17:06 +08:00
piexlMax 7808fbb852 [fixed] 修复富文本未引入watch的问题 #1528 2023-08-31 12:27:18 +08:00
wangzmgitandwangziming 9e64bd474b fix: 修复菜单折叠后再次展开右侧出现遮罩的问题 (#1529)
Co-authored-by: wangziming <wangziming@emsys.cn>
2023-08-31 11:18:19 +08:00
lubinandlubin 25a6aef472 修复接口实现问题 (#1524)
Co-authored-by: lubin <lubin@xiaoduotech.com>
2023-08-30 14:33:52 +08:00
zyw0605688 203ba521b0 分页列表接口,兼容不分页获取全部数据 (#1526)
* feat:'分页列表接口,兼容不分页获取全部数据'
2023-08-29 20:08:22 +08:00
piexlMax 287685420a [fixed]: 枚举类型条件查询的错误 #1525 2023-08-29 16:17:56 +08:00
piexlMax a6ae0ba4b0 富文本组件增加watch防止富文本无法加载的情况发生。 2023-08-23 18:12:03 +08:00
andywu1998 208346a480 优化config字段排列,使得内存对齐 (#1521)
* 调整字段顺序,解决config包内存对齐问题

* fix(config):修复内存对齐
2023-08-21 18:14:44 +08:00
DaMingandCodeLucifer 0d5c55a3b5 修复上次提交忘记把文件类型下载按钮描述的{{}}设置为字符串 (#1520)
* 修复上次提交忘记把文件类型下载按钮描述的{{}}设置为字符串
---------

Co-authored-by: CodeLucifer <tender_zhu@foxamil.com>
2023-08-19 22:49:29 +08:00
piexlMax 4fcd2bf14c 修改静态目录打包的配置 2023-08-19 11:29:44 +08:00
SDProgrammerandShi Dapeng deea1aba7f fix:修复不同系统环境下创建db文件路径错误的问题 (#1512)
Co-authored-by: Shi Dapeng <shidapeng@cmdi.chinamobile.com>
2023-08-17 17:23:14 +08:00
zhanghaixin246 3e31666cd6 feat:抛出上传文件错误信息 (#1515) 2023-08-17 17:22:50 +08:00
DaMingandCodeLucifer 197c4c46ab 生成代码模版文件新增了查看详情、详情内图片预览、文件下载 (#1516)
* 生成代码模版文件新增了查看详情、详情内图片预览、文件下载
前端工具文件主要修改了utils>format.js

* 替换富文本组建路径

---------

Co-authored-by: CodeLucifer <tender_zhu@foxamil.com>
2023-08-17 17:22:30 +08:00
奇淼(piexlmaxandkrank666 33cb2ed43d Tailwind css personel (#1509)
* css

* 修改persion页面的样式

* 优化persion样式

---------

Co-authored-by: krank666 <emosick@qq.com>
2023-08-11 01:12:51 +08:00
Felixs b56e521c5f 修复组件名称和icon名称重复导致的打包后富文本框被渲染到了不该出现的位置的bug. 2023-08-11 00:35:15 +08:00
SliverHorn 639b930ac9 Merge pull request #1508 from zdreamx/main-2
bugfix: fixed redis.go Set function
2023-08-10 16:59:48 +08:00
zdreamx 607235eb01 bugfix: fixed redis.go Set function 2023-08-10 16:51:58 +08:00
piexlMax dbfeb4b0fa 提升tailwindcss优先级 2023-08-09 17:19:05 +08:00
药要吃 432725b80d 更新 timed_task.go 增加了两个方法 (#1504)
Add:Timer工具增加AddTaskByFuncWithSeconds与AddTaskByJobWithSeconds方法
Fix:解决添加定时任务没有按时运行问题
2023-08-09 16:17:34 +08:00
taskandtask 91c2909c4a README gin版本标记错误 (#1505)
Co-authored-by: task <121913992@qq.com>
2023-08-09 16:16:28 +08:00
piexlMax 699a2f7956 [fixed]:issues #1501 2023-08-09 16:09:46 +08:00
piexlMax 7c2751ad37 提交v2.6.7版本,修复Sort使用的字段bug。 2023-08-09 15:59:58 +08:00
piexlMax 50b524fa7a 通用css 替换为tailwindcss模式,剔除无用css。 2023-08-09 15:51:18 +08:00
piexlMax aee26bc9b2 css 优化 2023-08-08 18:25:23 +08:00
piexlMax 78de254230 替换部分css为tailwindcss 删除某些无用css 2023-08-08 16:05:41 +08:00
piexlMax 22fe4053e9 增加多图片自动生成功能 2023-08-08 13:00:00 +08:00
piexlMax e73f9ac8f2 增加自动化富文本组件 2023-08-08 12:54:36 +08:00
piexlMax 19987234e5 增加部分功能视频教程快速链接 2023-08-06 15:48:02 +08:00
Tscuite 33239f28f8 feat: update ci add CGO_ENABLED=0 (#1497) 2023-08-04 17:30:41 +08:00
350f4572ed 集成tailwindcss 替换新的登陆页面和版权信息组件 (#1499)
* 集成tailwindcss

* fix: 修改登录,init 页面

* Update package.json

* 升级可升级的第三方库到新版本

* 细节调整

---------

Co-authored-by: bypanghu <bypanghu@163.com>
Co-authored-by: task <121913992@qq.com>
2023-08-04 17:03:21 +08:00
YinYongYou ab29267d64 fix: macos和linux下代码定位命令不对 #1495 (#1496) 2023-08-02 19:20:59 +08:00
xiaotianlu b410820868 Rename outer.go to other.go (#1490) 2023-08-02 10:51:58 +08:00
YinYongYou b1268e0001 feat: use description to name apiGroup (#1494) 2023-08-01 19:07:41 +08:00
奇淼(piexlmax 9fe661269d Merge pull request #1483 from ChengDaqi2023/oscs_fix_cis9at8au51vj78hfkt0
fix(sec): upgrade golang.org/x/image to 0.5.0
2023-07-21 16:15:49 +08:00
ChengDaqi2023 a715a77e76 update golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb to 0.5.0 2023-07-20 10:01:32 +08:00
奇淼(piexlmax 20933f77f5 修复marked问题 2023-07-19 15:05:56 +08:00
piexlMax c618fcafaa 增加多图片自动生成功能 2023-07-18 22:19:12 +08:00
piexlMax 350ce2ad35 修复element2.3.8以上i18n的问题 2023-07-18 00:00:26 +08:00
zhengtianbao eef8580e89 use filepath join instead of hardcode separator (#1479) 2023-07-14 21:23:12 +08:00
task 406fc05970 升级highlight.js marked (#1473)
* 升级highlight.js marked

* 升级highlight.js marked到新版本的兼容
2023-07-14 21:22:36 +08:00
Di Sheng 2b6cb775d8 FIX: globally fix typo 'Field' to 'failed' (#1471) 2023-07-14 21:22:10 +08:00
Rhon Joe fe27fd4c86 Fix #1365 (#1469)
* fix(web): 修复默认不存在时跳转问题

* feature(web): 图片组件增加预览
2023-07-14 21:21:25 +08:00
piexlMax 784dca2baa 路由嵌套情况下保证无边框功能可用 2023-07-11 22:24:47 +08:00
piexlMax 6cff6414c2 修复递归级别下无法将外层layout收起的bug 2023-07-11 22:05:58 +08:00
奇淼(piexlmax b84b6c3464 Update README.md 2023-07-02 16:54:51 +08:00
bd3931d62d [feature]:支持Sqlite数据库 (#1467)
* add sqlite3 support

* 修改gorm.io/driver/sqlite 为 github.com/glebarez/sqlite 适配windows用户无cgo环境

---------

Co-authored-by: Kafumio <linzehong1_2020@qq.com>
Co-authored-by: Kafumio <73083337+Kafumio@users.noreply.github.com>
Co-authored-by: sliverhorn <sliver_horn@qq.com>
2023-06-30 19:18:20 +08:00
奇淼(piexlmax 7ababb626b Merge pull request #1463 from zhanghaixin246/feature_modify_mysql_log_zh
feat:解决mysql配置日志等级不生效问题
2023-06-30 19:17:12 +08:00
zhangheng 62b2833c2f feat:解决mysql配置日志等级不生效问题 2023-06-28 19:14:19 +08:00
ipanghu 190c82bbe6 Merge pull request #1459 from bypanghu/main
fix:修复web在vscode打开的时候识别不了@符号的bug
2023-06-26 16:10:34 +08:00
ipanghu b8055d45e7 fix:修复web在vscode打开的时候识别不了@符号 2023-06-26 16:09:18 +08:00
piexlMax fe09bb3c91 修复插件打包丢失标准路径的bug 2023-06-24 18:04:47 +08:00
piexlMax 84d0a91c44 表单校验除string外不再添加whitespace判断 2023-06-23 13:49:57 +08:00
piexlMax 9d95f660e3 修复个人中心头像不居中的问题 2023-06-11 19:21:44 +08:00
piexlMax 2d76d1f50c 自动化代码搜索条件修正 2023-06-11 13:49:44 +08:00
piexlMax df3b921654 前端自动化页面选项修复 2023-06-10 22:31:18 +08:00
piexlMax e98fccdcfd 处理 图片文件同时存在时table下产生的bug 2023-06-10 22:20:03 +08:00
piexlMax 7b9b940b6a 处理 图片文件同时存在时table下产生的bug 2023-06-10 21:50:07 +08:00
piexlMax 3a4b750d93 调整版本号为2.5.6 2023-06-10 17:31:25 +08:00
小马and奇淼(piexlmax 40e3555d13 优化前端页面 (#1439)
* fix: 点击重置按钮时表格未刷新;
修复点击重置按钮时,筛选项被清空,但是下方表格未刷新的问题;

* fix: 未限制输入范围导致的报错;
后端使用了int类型,未限制输入会导致输入过大的数字时报错;

* fix: 未限制输入类型;
使用文本框会导致输入内容的类型未被限制,后端使用了int类型,输入非数字字符时会导致json绑定错误;

* feat: 添加创建时间验证规则;
后端仅在开始时间和结束时间同时有值时才进行搜索,所以前端会出现只选择一项内容时,搜索结果不符合预期的问题。添加验证规则使搜索结果符合预期。

* feat: 优化创建时间搜索项;
选择开始时间后,自动禁用结束时间中早于开始时间的选项;选择结束时间后,自动禁用开始时间中晚于结束时间的选项;增加校验规则,校验开始时间是否早于结束时间;点击搜索按钮时如果未通过校验则不进行搜索;

* fix: 角色id输入非数字字符时点击提交按钮后变为NaN;

* fix: 角色ID输入超大数字时报错;
后端使用int,输入的数字溢出会导致报错,所以限制输入长度;

* feat: 时间类型的选项增加验证规则;
选择开始时间后,自动禁用结束时间中早于开始时间的选项;选择结束时间后,自动禁用开始时间中晚于结束时间的选项;增加校验规则,校验开始时间是否早于结束时间;点击搜索按钮时如果未通过校验则不进行搜索;

* fix: 补全搜索form的ref引用;

* feat: 添加时间类型的搜索范围提示;
时间类型的搜索范围是开始时间(包含)至结束时间(不包含),为避免歧义,增加相关提示;

* feat: 将"时间"修改为"日期"确保字段名称一致性;

* feat: 将列名称从"按钮组"修改为更友好的"操作";

* feat: 将dialog标题修改为更友好的内容;

* fix: 使用了计算值的属性没有进行绑定;

* fix: 必填字段可以只填写空格;

---------

Co-authored-by: 奇淼(piexlmax <303176530@qq.com>
2023-06-10 17:27:52 +08:00
piexlMax 4b6adb3919 增加自动打包插件功能 2023-06-10 17:16:26 +08:00
piexlMax 66aece580f 增加自动化代码文件组件 bugFixed 2023-06-10 14:51:00 +08:00
qk winter 09fc200d55 Update clamis.go (#1450)
添加了GetUserName方法
2023-06-09 22:11:25 +08:00
piexlMax b17b56dba0 增加自动化代码文件组件 2023-06-09 22:10:18 +08:00
piexlMax a9d0531a56 调整代码自动定位无法识别windows的bug 2023-06-09 19:47:50 +08:00
piexlMax a7a2c85f82 增加自动化代码图片功能 修复 2023-06-09 17:51:16 +08:00
piexlMax 83a06fcd2b 增加自动化代码图片功能 2023-06-08 23:17:46 +08:00
piexlMax d2d7b22a8f 增加自动化代码图片功能 2023-06-08 23:17:46 +08:00
奇淼(piexlmax 92b78ab3c8 Update README.md 2023-06-07 14:28:29 +08:00
piexlMax 0bed3bab98 清理掉无用的casbin缓存刷新,增加重新loadPolicy接口。 2023-06-03 15:09:25 +08:00
piexlMax a60637fb79 修复自动引入代码element过于靠前的问题 2023-06-03 13:46:17 +08:00
piexlMax f1218264be 修复自动引入代码element过于靠前的问题 2023-06-03 13:46:17 +08:00
奇淼(piexlmax 18cf63facc Update README.md 2023-05-31 13:20:44 +08:00
奇淼(piexlmax 9f8e1775af AD 2023-05-31 13:15:38 +08:00
piexlMax 0e39f3ad05 调整swag为最新包 2023-05-23 00:08:53 +08:00
WWater 4fc90c0168 Fix go mod (#1421) 2023-05-22 23:50:19 +08:00
SliverHorn 57b4f539f9 去掉base/login 这个没有鉴权的api (#1427) 2023-05-22 16:07:31 +08:00
SliverHorn 8667ce5fb4 Merge pull request #1434 from wZuiShuai/main
修复接口返回未 return 问题
2023-05-18 20:25:13 +08:00
~ 0ed922bb29 修复接口返回未 return 问题 2023-05-18 17:25:17 +08:00
ipanghu 80eff97be3 Update README.md
fix:modify typos "分片长传"to "分片上传"
2023-04-25 16:32:38 +08:00
奇淼(piexlmax e5cfe5cd99 New fixed (#1418)
* fixed:#1416
* vite版本升级
2023-04-24 18:51:24 +08:00
奇淼(piexlmax 1d8b952a6d fixed:#1416 (#1417) 2023-04-24 17:22:10 +08:00
Albort-zand李展旗 c204f7a514 修复并发请求API情况下的读写冲突问题 (#1415)
Co-authored-by: 李展旗 <lizhanqi@inke.cn>
2023-04-24 17:21:38 +08:00
奇淼(piexlmaxandRowen 6e2ef1e29c Fixed (#1412)
* 菜单项如果有参数则携带参数跳转

* 剔除search冗余代码

---------

Co-authored-by: Rowen <wucenglou@qq.com>
2023-04-08 16:07:22 +08:00
奇淼(piexlmaxandkrank 5f0402043a feat: 指令菜单功能 (#1407)
* feat: 指令菜单功能

* 增加快捷指令功能

* 废弃jwt结构StandardClaims替换为RegisteredClaims #1409

* 调整快捷指令登出操作

---------

Co-authored-by: krank <emosick@qq.com>
2023-04-08 15:37:22 +08:00
piexlMax 6ad7ccdd6e 增加chatTable提示 2023-04-01 21:43:57 +08:00
FelixJiang 90a2fd7f19 优化万用表格Prompt 2023-04-01 21:32:28 +08:00
FelixJiang 58c8b11f85 优化万用表格Prompt 2023-04-01 20:16:37 +08:00
FelixJiang 4d700be9ae 优化万用表格Prompt 2023-04-01 20:16:15 +08:00
奇淼(piexlmax da0d02b990 Revert "修复并发请求API情况下的读写冲突问题 (#1395)" (#1404)
This reverts commit 69aa64f800.
2023-04-01 19:59:15 +08:00
小马 854cb59f6b doc: 避免引用行号变更带来的歧义 (#1400) 2023-04-01 19:58:28 +08:00
Albort-zand李展旗 33cbee23d4 修复并发请求API情况下的读写冲突问题 (#1395)
Co-authored-by: 李展旗 <lizhanqi@inke.cn>
2023-03-30 00:49:02 +08:00
奇淼(piexlmax 0497cf384d Revert "[feat]: config for TLS connection in init MySQL (#1388)" (#1392)
This reverts commit a4a240eace.
2023-03-27 11:09:19 +08:00
AONE acd8fa3810 fix: api layer can not get autofill primary key in automatically generated code (#1384) 2023-03-25 20:04:40 +08:00
TPEngineer 9d024bca3b Update sys_authority_btn.go (#1386)
增加 err 错误处理
2023-03-25 20:04:21 +08:00
Albort-z 7434c9db55 修复字典按ID排序而非sort排序问题 (#1387)
直接使用Preload加载的字典值是按ID排序的,在前端展示时并非希望的sort排序
2023-03-25 20:04:05 +08:00
conbanwa a3ab0b3243 [feat]: config for TLS connection in init MySQL (#1388) 2023-03-25 20:02:59 +08:00
64608f6b05 Gpt (#1389)
* fix:优化自动化代码搜索区域 (#1382)

* 增加gpt功能(万用表格)

* feat: chatTable页面
---------

Co-authored-by: ipanghu <bypanghu@163.com>
Co-authored-by: 陶正虎 <zhenghu.tao@jutze.com.cn>
Co-authored-by: krank <emosick@qq.com>
2023-03-25 20:02:14 +08:00
piexlmax a207c982b7 [fixed]: 点击菜单项跳转无效 #1378 2023-03-18 14:21:34 +08:00
piexlmax 072acac399 [fixed]:自动生成代码pkg和结构简称相同导致编译不通过 #1379 2023-03-18 14:21:34 +08:00
piexlmax 8049466dff 清理刷新路由时出现的warning 2023-03-18 14:21:34 +08:00
SliverHorn 80077ba94d Merge pull request #1376 from SliverHorn/fix_middleware_jwt
fixed: middleware jwt
2023-03-13 16:17:27 +08:00
sliverhorn bd4744557f fixed: middleware jwt err == utils.TokenExpired 修改为 errors.Is(err, utils.TokenExpired) 2023-03-13 15:56:40 +08:00
piexlmax d8072634ef 自动化回滚可以回滚gorm.go 和 router.go 2023-03-11 18:26:55 +08:00
piexlmax 27158f7075 路由跳转后自动页面回归顶部 2023-03-09 23:52:54 +08:00
xin053 f06f1fb7f1 fixbug: 修复代码生成器无法自动导入 time 包问题 (#1368)
原本 for 循环下 if 判断只有 HasTimer 判断,加了 break 可以提前跳出循环,但另外新增了 NeedValid 和 NeedSort 判断后,直接跳出循环会导致无法正常设置 HasTimer ,NeedValid 和 NeedSort
2023-03-07 18:22:26 +08:00
奇淼(piexlmax 8bb7b75f05 Update README.md
修复github 表单生成器使用规则
2023-03-06 20:47:42 +08:00
Jankin 0c9e92abb0 华为obs,file.Open后缺少close,uploadFile返回值顺序不对 (#1367) 2023-03-06 20:45:56 +08:00
= 7a8787b1a0 修复分配角色权限底部超出原始应有范围的问题 2023-03-06 10:27:22 +08:00
SliverHorn 78f71c8b13 fixed: #1352 (#1364) 2023-03-02 16:28:42 +08:00
piexlmax a0a35e8253 修复自动化package驼峰问题 2023-03-01 22:05:04 +08:00
a1140314368and奇淼(piexlmax e892e3f9e1 新增权限初始化时适配数据库的出错日志 (#1359)
* 新增权限初始化时适配数据库的出错日志

* 修改报错详情

修改报错详情

---------

Co-authored-by: 奇淼(piexlmax <qimiaojiangjizhao@gmail.com>
2023-02-28 14:43:48 +08:00
= 2dadc98485 调整按需加载下element的国际化为中文 2023-02-27 16:05:56 +08:00
SliverHorn 1bd2b4629e Merge pull request #1357 from Macadamianuts/main
本地文件服务 gin路由报错
2023-02-27 12:52:19 +08:00
WWater ce52cbf6ac Update router.go 2023-02-27 12:44:55 +08:00
奇淼(piexlmax 0abcb5aba1 重构自动化代码,修复皮肤bug (#1355)
* 增加读取ast方法和AddImport 方法来增加引用包功能

* 增加在指定方法中添加头部声明global.DB业务库的方法

* 增加了自动添加AutoMigrate方法。

* 将自动化产生自动迁移功能替换为新ast

* 增加了自动注册router块的功能

* 废除旧的对router和gorm的处理方法,替换为新的自动化方法

* 修复开发模式下皮肤失效的问题
2023-02-25 14:46:02 +08:00
奇淼(piexlmax ca7bdc913e 补充按需加载遗漏的指令加载方式的css (#1351)
Co-authored-by: piexlmax(奇淼 <303176530@qq.com>
2023-02-20 14:48:48 +08:00
piexlmax 2de7d34b4a 区分环境进行按需加载,提升本地开发加载速度。
更改侧边栏活跃色,让其和element-ui皮肤统一。
修复issue https://github.com/flipped-aurora/gin-vue-admin/issues/1347
2023-02-18 14:08:42 +08:00
奇淼(piexlmax 0eea78f796 调整为按需加载,element样式调整为皮肤模式,不再使用全局变量覆盖。 (#1349)
* 调整element为自动按需引入,减少打包体积。

* 调整element样式变更为变量模式不再使用全局css覆盖

* 修改element自动化模板适配element皮肤变量模式

---------

Co-authored-by: piexlmax<303176530@qq.com>
2023-02-16 19:03:51 +08:00
Ackerman 95fa7e8130 fix(operation): 修复操作日志中间件,record.Resp写错的问题 (#1342) 2023-02-11 14:32:56 +08:00
ccfish fd78876dd3 Update system.vue (#1341) 2023-02-08 21:05:00 +08:00
piexlmax eaa3075516 初始化引导着重提示mysql需要使用innoDB 2023-02-08 00:24:15 +08:00
XiaoK29 92338fd219 fix:修复用户管理手机号邮箱无法置空bug (#1339) 2023-02-08 00:20:28 +08:00
ipanghuand陶正虎 26d32c02ea fix: 修复上传图片返回的错误信息,修复登录跳转的转跳函数 (#1340)
* fix : 修改登录转跳是replace

* fix:修复上传图片组件的 报错

---------

Co-authored-by: 陶正虎 <zhenghu.tao@jutze.com.cn>
2023-02-08 00:20:07 +08:00
奇淼(piexlmax e03efc33d7 调整资源管理提示 2023-01-31 15:58:07 +08:00
jerjjj 2d1188af11 update nhooyr.io/websocket v1.8.6 to 1.8.7 (#1338) 2023-01-28 14:53:08 +08:00
奇淼(piexlmax 66666ed5fd 调整eslint,优化oc判断 2023-01-14 10:52:15 +08:00
奇淼(piexlmax dfcb283899 fixed:#1336 (#1337) 2023-01-14 10:27:07 +08:00
znonymous 24215f8b28 feat:backend add router global prefix (#1333)
* feat:backend add router global prefix

* feat: global prefix in plugin router

* feat: remove plugin router prefix and add web router setting
2023-01-14 10:22:46 +08:00
Yexk_M ddc2b4c2ad feat: 监听搜索框部分提供回车键提交搜索 (#1335)
* feat: #1334 按回车键搜索
2023-01-14 10:20:13 +08:00
piexlmax 10cef483f4 Merge branch 'main' of github.com:flipped-aurora/gin-vue-admin 2023-01-07 16:26:51 +08:00
piexlmax 51dde2f71e fixed:issue#1321 2023-01-07 16:26:29 +08:00
5e0117e7c6 Captcha (#1329)
* feat: #807 自定义验证码开关,可以自行配置

* 添加数据库列表支持:SQL SERVER

* [user.vue]: 新增邮箱手机合法性校验,邮箱手机非必填

* [menu.js]: 修复错误的API注释

* 调整配置文件 是其可以支持oracle和mssql

Co-authored-by: Yexk <yexk@yexk.cn>
Co-authored-by: 逆光飞翔 <191180776@qq.com>
Co-authored-by: chenteng <cc17854330572@163.com>
2023-01-01 01:26:57 +08:00
奇淼(piexlmax 3b3535faec 2.5.4升级为2.5.5 2022-12-14 15:39:34 +08:00
mengtiantangandxdefei 3e1067faba web/src/view/layout/aside/historyComponent: fix 浏览器自带返回按钮点击多次才能返回上一页, 多次往路由栈push当前页面路由记录的bug (#1311)
Co-authored-by: xdefei <13523376917@163.com>
2022-12-14 15:31:28 +08:00
奇淼(piexlmax 722382f60e 自动化代码列表可直接进行简单编辑。 2022-12-14 15:23:05 +08:00
奇淼(piexlmax e47a512fc8 取消表格导出功能,修复回滚(删表)功能的painc (#1310)
* [feature]:取消表格导出功能

* 修复回滚(删表)painc的问题

* [feature]:修改初始化
2022-12-12 14:42:47 +08:00
奇淼(piexlmax 0627359b6e [fixed]:解决路径判断的错误 #1304 2022-12-08 19:13:31 +08:00
coke 01d1e4c7f5 fix:service\system\sys_authority.go: (#1295)
DeleteAuthority方法修改没有正确处理err导致返回的err信息不正确
GetAuthorityInfoList方法取消多余的if判断,减少阅读疑惑
2022-12-08 18:15:31 +08:00
TonghuaRoot(童话) 3f564e8179 router.go: 将状态码由 200 调整为 http.StatusOK (#1299) 2022-12-08 18:14:10 +08:00
andywu1998and奇淼(piexlmax b6f3038a73 bugfix: 通过修改配置文件使得跨域白名单正常生效 (#1296)
* bugfix: 通过修改配置文件使得跨域白名单正常生效

Co-authored-by: 奇淼(piexlmax <qimiaojiangjizhao@gmail.com>
2022-11-30 16:52:00 +08:00
Carrot2 e67354f34c fix: go version error (#1297) 2022-11-30 16:49:14 +08:00
Jary a04982425f closeLoading()的时候先判断接口是否开启了loading,解决showLoading()失效问题 (#1287) 2022-11-25 18:34:25 +08:00
cokeandwangxd01 2e6f99edf0 修改获取角色列表没有检查err,优化查询逻辑 (#1238)
Co-authored-by: wangxd01 <wangxd01@mingyuanyun.com>
2022-11-22 11:26:31 +08:00
奇淼(piexlmax 9307d08bb6 增加字典方法 showDictLabel(字典,字典value)返回字典 label 2022-11-18 14:40:53 +08:00
飞龙Test 2cdcd98e08 修复手机端顶部标题栏溢出、分页溢出的问题 (#1284) 2022-11-17 17:51:19 +08:00
奇淼(piexlmax 7540ee942f [fixed]:解决无法深层校验的bug #1283 2022-11-16 11:17:03 +08:00
spartacus 7bfad03b2e k8s部署的配置文件修改为config.docker.yaml (#1277) 2022-11-10 12:11:29 +08:00
奇淼(piexlmaxand吴璟 9dacd7056b Develop init (#1280)
* 修改数据库初始化方式,增加引擎配置、统一表前缀、是否关闭复数表名

* 修改拦截器逻辑,develop模式不走数据库权限验证

* 增加表前缀,复数表,数据库引擎配置。

Co-authored-by: 吴璟 <hypf2008@126.com>
2022-11-10 12:08:13 +08:00
Sakishum 4ebe66a29c @sakishum 去除 json tag 多余的双引号 (#1279)
去除结构体 SysCaptchaResponse 字段CaptchaLength 的 json tag 多余的双引号
2022-11-09 12:03:00 +08:00
Yexk_M 6ebed9eff6 logger.go: fix nil pointer dereference (#1271) 2022-11-04 13:45:44 +08:00
piexlmax cc13685062 修复丢失的key 2022-10-30 21:31:18 +08:00
奇淼(piexlmax 6b28490d7b Update ci.yaml 2022-10-30 21:14:57 +08:00
zyw0605688and奇淼(piexlmax 27ba592434 feat:'左侧菜单item修改左内边距' (#1272)
* feat:'左侧菜单修改边距'

Co-authored-by: 奇淼(piexlmax <qimiaojiangjizhao@gmail.com>
2022-10-30 21:06:50 +08:00
piexlmax cf5daffe69 根据tab决定是否keepalive (动态keepalive) 2022-10-30 21:00:57 +08:00
piexlmax 192c0e529d 增加自动化排序功能 2022-10-30 20:27:22 +08:00
piexlmax c300e16de9 修复无法将子角色重置修改为根角色的bug 2022-10-29 20:26:45 +08:00
奇淼(piexlmax e46eecfc8e Merge pull request #1269 from longzhang83/master
Update email.go
2022-10-27 17:25:22 +08:00
longzhang83 1e2add4b97 Update email.go
EmailTest  修改From 为 To
2022-10-26 17:50:39 +08:00
奇淼(piexlmaxandbypanghu 975f515691 前端细节调整 (#1268)
* fix: 修改 autoCode 引用文件报错,fixed issue 1266

Co-authored-by: bypanghu <bypanghu@163.com>
2022-10-25 17:30:08 +08:00
05f8ae2aae 增加自动化代码选择业务库功能,增加无边框页面功能。 (#1264)
* feat:增加无边框页面路由

* 更改基础页面文字说明

* 修复安装插件路径穿越漏洞

* 添加业务库数据库选择功能

Co-authored-by: dzwvip <dzwvip@qq.com>
Co-authored-by: znonymous <fly1029@yeah.net>
2022-10-23 21:04:17 +08:00
Tscuite 525b3a0da9 feat: CI (#1255)
* feat: 发布release前,自动更新版本号文件
2022-10-23 18:32:47 +08:00
03265e03fc 增加自动化代码匹配进入业务库功能 (#1249)
* Update api.go.tpl

修复不创建资源标识时 批量删除 方法内 deletedBy 未声明的问题

* 可自动创建业务库

* 自动化业务库回滚适配

* 修复断点续传路径穿越漏洞

* 增加指定菜单亮起功能

* 增加菜单高亮功能,调整版本号

* fixed: 用户后台注册没接收手机号和邮箱

Co-authored-by: dzwvip <dzwvip@qq.com>
Co-authored-by: SliverHorn <503551462@qq.com>
2022-10-15 13:55:47 +08:00
奇淼(piexlmaxanddzwvip 28c928890a 修改自动化代码不携带资源标识的created_by错误 (#1247)
* Update api.go.tpl

修复不创建资源标识时 批量删除 方法内 deletedBy 未声明的问题

* 调整配置文件结构

Co-authored-by: dzwvip <dzwvip@qq.com>
2022-10-13 12:15:35 +08:00
tscuite 6f3e8683a0 fix: 数据库默认用户设置为普通用户gva (#1245) 2022-10-13 11:47:09 +08:00
Bin ba7a16250b fix: (#1242)
* feat:perfect

* fix:buffer time

* fix:zap freifx
2022-10-06 21:48:19 +08:00
piexlmax 1cbbce741a 调整字典管理路由监听模式 2022-10-01 17:07:58 +08:00
奇淼(piexlmaxandzyw0605688 9f9f6b7a08 修改前端日志配置页面对应key (#1237)
* Update web/src/view/systemTools/system/system.vue

去掉 系统工具/系统配置/jwt签名有效期缓冲器后面的提示语(秒),现在已改为天,不加为好。
系统工具/系统配置/数据库配置 日志模式字段对应为log-zap

* 调整配置文件结构

Co-authored-by: zyw0605688 <40220158+zyw0605688@users.noreply.github.com>
2022-09-29 12:26:28 +08:00
奇淼(piexlmax 3ec4823533 为菜单添加默认值 2022-09-26 15:57:28 +08:00
SliverHorn 31d316f5b2 Merge pull request #1231 from SliverHorn/fix
fixed: c.ShouldBindXxx 未处理错误 以及注释错误
2022-09-25 16:53:20 +08:00
SliverHorn 8f31d6fcbd fixed: c.ShouldBindXxx 未处理错误 以及注释错误 2022-09-25 16:38:19 +08:00
SliverHorn 7b80ea528c Update sys_user.go
fixed: #1230
2022-09-25 15:50:11 +08:00
piexlmax ee388b01db 升级版本2.5.4 2022-09-25 13:35:11 +08:00
SliverHorn 2d4b16db46 Fixed: c.ShouldBindXXX 未错误处理 #1224 (#1229)
* Fixed: c.ShouldBindXXX 未错误处理 #1224
- api层错误处理以及代码格式统一化
* Update: 代码生成器 api.go ShouldBindXxx 错误处理
2022-09-25 13:23:44 +08:00
SliverHorn a7715648d0 Merge pull request #1226 from freespace8/master
fix: GetUserInfo没有使用正确传参
2022-09-22 14:46:15 +08:00
freespace8 4ebc4e01cd fix: GetUserInfo没有使用正确传参 2022-09-22 12:37:17 +08:00
piexlmax fd0625f2eb 自动化代码样式微调,目录结构调整。 2022-09-21 23:41:29 +08:00
ef35c53712 增加shift+鼠标左键定位代码功能,增加自动创建资源权限标识功能,细节调优。 (#1225)
* fix: 增加索引解决登录太慢的问题

* 增加shift+鼠标左键自动定位到编辑工具代码行的功能

* 过滤功能性标签 防止意外错误

* [utils\validator.go]:修复了当判断字符长度时,当字符串长度为中文,会判断错误。

* 增加资源标识

Co-authored-by: hexiang3000 <91460121+hexiang3000@users.noreply.github.com>
Co-authored-by: fanyibo <29974992@qq.com>
2022-09-21 21:42:10 +08:00
奇淼(piexlmaxandsongzhibin97 b5c79be625 整理配置文件,jwt过期时间和缓冲时间支持1d2h3m4s事件类型 (#1218)
* feat: human duration

* Update config.yaml

* 调整配置文件结构

Co-authored-by: songzhibin97 <718428482@qq.com>
2022-09-13 16:26:02 +08:00
SliverHorn ee7b9b0cff update: 用户默认角色的默认路由如果为空则赋值404, 公共方法抽离并优化 (#1215) 2022-09-09 11:33:58 +08:00
piexlmax 3289405b17 修复回滚bug 2022-09-07 21:30:53 +08:00
ipanghu b9a30b9ffe [Feature] 新增页面切换进度条 (#1213)
新增页面切换进度条
2022-09-06 10:17:05 +08:00
piexlmax f606c7c891 调整casbin为缓存模式 2022-09-03 13:26:36 +08:00
piexl c76eb01b68 Merge branch 'main' of github.com:flipped-aurora/gin-vue-admin 2022-09-02 17:02:33 +08:00
piexl 34b6e5ebae a标签样式恢复便于集成富文本 2022-09-02 17:02:17 +08:00
myface-wang 7d771a56e6 优化,合并update方法 (#1212) 2022-09-01 17:11:20 +08:00
piexl f1017e345b form模板mini调整为small 2022-08-31 17:59:43 +08:00
XiaoK29 091b61bd10 调整ioutil为go1.16推荐语法 (#1209)
* perf:根据go1.16后的提议修改包使用

* perf:根据go1.16后的提议修改包使用以及修改中间件的代码冗余
2022-08-29 15:40:40 +08:00
奇淼(piexlmaxandmngma ed9ca764d4 增加范围搜索自动化,调整了一些已知的bug (#1206)
* 测试build是否成功

* 增加自动化范围搜索,调整字典查询

* 调整默认用户名

* 避免页面加载后立即触发一次验证,页面出现一片红色的警告的情况

* 避免登录接口成功后,push 时间太长但是加载框已经消失,让人误以为登录失败

Co-authored-by: mngma <enmingma@126.com>
2022-08-24 11:36:28 +08:00
奇淼(piexlmax 70c6480ae9 修复某些环境下build失败的bug
修复某些环境下build失败的bug
2022-08-12 12:05:08 +08:00
ZZ a0ebb3ef58 更新api/api.js接口文档 (#1196) 2022-08-11 18:07:51 +08:00
dhb52 1efb68b11f banckend style-fix 2022-08-11 09:58:59 +08:00
dhb52 9c564df350 frontend eslint 2022-08-11 09:58:59 +08:00
SliverHorn 767e7650e0 fix: #1193 (#1194) 2022-08-10 22:35:32 +08:00
piexlmax f32ed3a5c8 调整用户切换角色路由跳转逻辑 2022-08-06 19:47:55 +08:00
piexl 7e7c869fc4 调整html lang 为 zh-cn 2022-08-03 16:12:47 +08:00
songzhibin97 9da64c34ff Feat dependence upgrade (#1190)
* feat: dependence-upgrade
2022-08-01 14:53:27 +08:00
Leonard Wang 23266d12ec 修复插件模板中的提示和代码生成中的问题 (#1186) 2022-07-30 16:31:36 +08:00
piexl 3920d151af 修复参数或者路由中携带-导致关闭左侧和关闭右侧失效的问题 2022-07-29 15:29:28 +08:00
piexl 9551cdf18a fixed:#1185 2022-07-28 17:55:59 +08:00
SliverHorn 1ec90895da Merge pull request #1183 from WangLeonard/bugfix/fix_commit_in_about
修复关于我们中的提交时间
2022-07-27 22:37:55 +08:00
Leonard Wang bd67b8bf7f 修复关于我们中的提交时间 2022-07-27 22:22:22 +08:00
piexl 53c116309e 修改模板列表返回结构 2022-07-26 15:05:09 +08:00
piexl 5a53ae0d34 取消rollupOptions保证build后可用 2022-07-26 11:56:34 +08:00
Yaya Liu 207c0e3708 upload.vue: fix wrong words (#1180) 2022-07-26 09:32:23 +08:00
songzhibin97 7b7d76e977 Merge branch 'main' of github.com:flipped-aurora/gin-vue-admin 2022-07-24 09:02:54 +08:00
songzhibin97 a1d3b5c887 Update zap.go 2022-07-24 09:02:49 +08:00
奇淼(piexlmax 796bcb34ad Update README.md 2022-07-23 23:53:23 +08:00
奇淼(piexlmax 9f274308ca Update build_test.yml 2022-07-23 23:47:04 +08:00
奇淼(piexlmaxandqiang 7feb152b35 前端性能优化,体验优化 (#1178)
* 优化角色管理中菜单和api管理的确定按钮,固定在右上角,更容易操作,每次修改完不需要拉到最上面再确定

* 角色管理中 api和菜单树 增加筛选框

* vite更新至3.0

* 取消sass-loader

* 取消*zoom 的打包报错

Co-authored-by: qiang <1604864658@qq.com>
2022-07-23 23:41:16 +08:00
piexl 4fad8b77bf 修复登录页验证码校验的bug 2022-07-22 12:44:46 +08:00
piexl 2c90c90610 readme数据库引擎提示 2022-07-22 12:18:02 +08:00
tscuite 9ac66f57fa 增加makefile快速打包插件 (#1173)
* 更新插件快捷打包

使用方法:make plugin PLUGIN="这里是插件文件夹名称,默认为email"
2022-07-19 18:47:29 +08:00
奇淼(piexlmax 82fcc196df Update config.yaml 2022-07-16 20:06:59 +08:00
piexlmax c7dbcbf336 修复必填项自动化 2022-07-16 19:40:26 +08:00
piexlmax 5591c60c14 Merge remote-tracking branch 'origin/main' 2022-07-16 19:04:22 +08:00
piexlmax dcdcf0bbbe 调整误提的config 2022-07-16 19:04:07 +08:00
奇淼(piexlmax e899f85101 Update .gitattributes 2022-07-16 13:52:45 +08:00
512 changed files with 35981 additions and 16288 deletions
+2 -1
View File
@@ -1 +1,2 @@
*.sql linguist-language=GO
*.sql linguist-language=GO
*.html linguist-language=GO
-64
View File
@@ -1,64 +0,0 @@
name: gin-vue-admin build test
on:
push:
branches:
- "*"
paths-ignore:
- "./db/**"
- "**.md"
pull_request:
branches:
- "*"
paths-ignore:
- "./db/**"
- "**.md"
jobs:
frontend:
name: Frontend build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.16.0]
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Build test
run: |
npm install
npm run build
working-directory: ./web
backend:
name: Backend build
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.6
uses: actions/setup-go@v1
with:
go-version: 1.16
id: go
- name: Check out branch
uses: actions/checkout@v2
- name: Download dependencies
run: |
go get -v -t -d ./...
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
working-directory: ./server
- name: Test and Build
run: |
go build -v -race
working-directory: ./server
+269
View File
@@ -0,0 +1,269 @@
name: CI
on:
push:
branches: [ '*' ]
pull_request:
release:
types: [ created, edited ]
workflow_dispatch:
inputs:
gva_version:
required: true
type: string
jobs:
init:
if: github.repository_owner == 'flipped-aurora'
runs-on: ubuntu-latest
steps:
- name: init
run: |
echo "flipped-aurora"
frontend:
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'release'
name: Frontend node ${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.16.0]
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Build test
run: |
npm install
npm run build
working-directory: ./web
backend:
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'release'
name: Backend go
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [1.22]
steps:
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
id: go
- name: Check out branch
uses: actions/checkout@v2
- name: Download dependencies
run: |
go get -v -t -d ./...
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
working-directory: ./server
- name: Test and Build
run: |
go build -v -race
working-directory: ./server
devops-test:
if: github.ref == 'refs/heads/test'
name: devops-test
needs:
- init
- backend
- frontend
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.16.0]
go-version: [1.22]
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Sed Config
env:
PROD: ${{ secrets.PROD }}
TESTING: ${{ secrets.TESTING }}
shell: bash
run: |
git branch
ls -l
sed -i "s/${PROD}/${TESTING}/g" web/.env.production
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2.1.2
with:
node-version: ${{ matrix.node-version }}
- name: Build-Node
run: |
cd web/ && yarn install && yarn run build
- name: Use Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
- name: Build-go
run: |
cd server/ && go mod tidy && CGO_ENABLED=0 go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
- name: restart
env:
KEY: ${{ secrets.KEY }}
HOST: ${{ secrets.HOST }}
USER: ${{ secrets.USER }}
PROT: ${{ secrets.PROT }}
MKDIRTEST: ${{ secrets.MKDIRTEST }}
run: |
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIRTEST}dist/
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIRTEST}
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST}resource/ && rm -rf ${MKDIRTEST}resource/*"
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIRTEST}resource/
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST} && bash restart.sh > /dev/null 2>&1 &"
release-pr:
if: ${{ github.event_name == 'workflow_dispatch' && github.repository_owner == 'flipped-aurora'}}
runs-on: ubuntu-latest
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Sed Config
env:
GVA_VERSION: ${{ inputs.gva_version }}
shell: bash
run: |
sed -i 's/当前版本.*`$/当前版本:v'${GVA_VERSION##v}'`/' web/src/core/config.js
sed -i 's/当前版本.*$/当前版本:v'${GVA_VERSION##v}'/' server/core/server.go
sed -i 's/当前版本.*$/当前版本:v'${GVA_VERSION##v}'/' web/src/core/gin-vue-admin.js
sed -i 's/"version": ".*",$/"version": "'${GVA_VERSION##v}'",/' web/package.json
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add . && git commit -m "release: v${GVA_VERSION##v}"
- name: Push
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
- uses: google-github-actions/release-please-action@v3
with:
command: release-pr
release-type: simple
changelog-path: docs/CHANGELOG.md
release-as: ${{ inputs.gva_version }}
package-name: gin-vue-admin
changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"chore","section":"Miscellaneous","hidden":false}]'
release-please:
if: github.ref == 'refs/heads/main' || github.event_name == 'release'
runs-on: ubuntu-latest
needs:
- init
- backend
- frontend
outputs:
release_created: ${{ steps.release_please.outputs.release_created }}
tag_name: ${{ steps.release_please.outputs.tag_name }}
steps:
- uses: google-github-actions/release-please-action@v3
id: release_please
with:
#token: ${{ secrets.GAV_TOKEN }}
command: github-release
#signoff: "github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
release-type: simple
changelog-path: docs/CHANGELOG.md
#release-as: ${{ inputs.deploy_target }}
package-name: gin-vue-admin
#extra-files: |
# x-release-please-version.json
changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"chore","section":"Miscellaneous","hidden":false}]'
devops-prod:
if: needs.release-please.outputs.release_created || github.event_name == 'release'
runs-on: ubuntu-latest
needs:
- init
- release-please
name: devops-prod
strategy:
matrix:
node-version: ['18.x']
go-version: ['1.22']
steps:
- uses: actions/checkout@v2
- name: tag major and minor versions
run: |
echo " ${{ needs.release-please.outputs.tag_name }}"
- name: Sed Config
shell: bash
run: |
git branch
ls -l
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2.1.2
with:
node-version: ${{ matrix.node-version }}
- name: Build-Node
run: |
cd web/ && yarn install && yarn run build
- name: Use Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
- name: Build-go
run: |
cd server/ && go mod tidy && CGO_ENABLED=0 go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
- name: restart
env:
KEY: ${{ secrets.KEY }}
HOST: ${{ secrets.HOST }}
USER: ${{ secrets.USER }}
PROT: ${{ secrets.PROT }}
MKDIR: ${{ secrets.MKDIR }}
run: |
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIR}dist/
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIR}
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR}resource/ && rm -rf ${MKDIR}resource/*"
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIR}resource/
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR} && bash restart.sh > /dev/null 2>&1 &"
docker:
name: docker
if: github.ref == 'refs/heads/stop-stop-stop'
runs-on: ubuntu-latest
needs:
- init
- release-please
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Login to Aliyun Registry
uses: docker/login-action@v1
with:
registry: ${{ secrets.ALIYUN_REGISTRY }}
username: ${{ secrets.ALIYUN_DOCKERHUB_USER }}
password: ${{ secrets.ALIYUN_DOCKERHUB_PASSWORD }}
- name: Sed Config
shell: bash
run: |
sed -i 56c"\ && yarn install && yarn build" Makefile
make image TAGS_OPT="latest"
sed -i 's#./entrypoint.sh"#./entrypoint.sh","actions"#g' deploy/docker/Dockerfile
sed -i "s#COPY build/ /usr/share/nginx/html/#COPY . /opt/gva#g" deploy/docker/Dockerfile
sed -i 16c"\ && cd /opt/gva/server/ && go mod tidy && cd /opt/gva/web/ && yarn" deploy/docker/Dockerfile
sed -i "s#open: true#open: false#g" web/vite.config.js
make images TAGS_OPT="latest"
docker push registry.cn-hangzhou.aliyuncs.com/gva/gin-vue-admin:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/web:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/server:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/all:latest
-55
View File
@@ -1,55 +0,0 @@
name: devops-test
on:
push:
branches: [test]
workflow_dispatch:
jobs:
build:
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['16.x']
go-version: ['1.16']
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Sed Config
env:
PROD: ${{ secrets.PROD }}
TESTING: ${{ secrets.TESTING }}
shell: bash
run: |
git branch
ls -l
sed -i "s/${PROD}/${TESTING}/g" web/.env.production
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2.1.2
with:
node-version: ${{ matrix.node-version }}
- name: Build-Node
run: |
cd web/ && yarn install && yarn run build
- name: Use Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
- name: Build-go
run: |
cd server/ && go mod tidy && go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
- name: restart
env:
KEY: ${{ secrets.KEY }}
HOST: ${{ secrets.HOST }}
USER: ${{ secrets.USER }}
PROT: ${{ secrets.PROT }}
MKDIRTEST: ${{ secrets.MKDIRTEST }}
run: |
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIRTEST}dist/
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIRTEST}
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST}resource/ && rm -rf ${MKDIRTEST}resource/*"
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIRTEST}resource/
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST} && bash restart.sh > /dev/null 2>&1 &"
-52
View File
@@ -1,52 +0,0 @@
name: devops
on:
push:
tags:
- v*
workflow_dispatch:
jobs:
build:
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['16.x']
go-version: ['1.16']
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Sed Config
shell: bash
run: |
git branch
ls -l
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2.1.2
with:
node-version: ${{ matrix.node-version }}
- name: Build-Node
run: |
cd web/ && yarn install && yarn run build
- name: Use Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
- name: Build-go
run: |
cd server/ && go mod tidy && go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
- name: restart
env:
KEY: ${{ secrets.KEY }}
HOST: ${{ secrets.HOST }}
USER: ${{ secrets.USER }}
PROT: ${{ secrets.PROT }}
MKDIR: ${{ secrets.MKDIR }}
run: |
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIR}dist/
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIR}
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR}resource/ && rm -rf ${MKDIR}resource/*"
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIR}resource/
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR} && bash restart.sh > /dev/null 2>&1 &"
-32
View File
@@ -1,32 +0,0 @@
name: Docker-CICD
on:
push:
branches: [main]
workflow_dispatch:
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Login to Aliyun Registry
uses: docker/login-action@v1
with:
registry: ${{ secrets.ALIYUN_REGISTRY }}
username: ${{ secrets.ALIYUN_DOCKERHUB_USER }}
password: ${{ secrets.ALIYUN_DOCKERHUB_PASSWORD }}
- name: Sed Config
shell: bash
run: |
sed -i 51c"\ && yarn install && yarn build" Makefile
make image TAGS_OPT="latest"
sed -i 's#./entrypoint.sh"#./entrypoint.sh","actions"#g' deploy/docker/Dockerfile
sed -i "s#COPY build/ /usr/share/nginx/html/#COPY . /opt/gva#g" deploy/docker/Dockerfile
sed -i 16c"\ && cd /opt/gva/server/ && go mod tidy && cd /opt/gva/web/ && yarn" deploy/docker/Dockerfile
sed -i "s#open: true#open: false#g" web/vite.config.js
make images TAGS_OPT="latest"
docker push registry.cn-hangzhou.aliyuncs.com/gva/gin-vue-admin:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/web:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/server:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/all:latest
-114
View File
@@ -1,114 +0,0 @@
name: GIN-VUE-ADMIN Docker Build
on:
push:
branches: [stopstopstop]
#workflow_dispatch:
# inputs:
# webtag:
# description: 'Set web tag, Default latest'
# required: true
# default: "latest"
# servertag:
# description: 'Set server tag, Default latest'
# required: true
# default: "latest"
jobs:
GIN_VUE_ADMIN_WEB:
name: GIN VUE ADMIN WEB
runs-on: ubuntu-latest
steps:
- name: Private Actions Checkout
uses: actions/checkout@v2.3.4
- name: Docker Setup QEMU
uses: docker/setup-qemu-action@v1.2.0
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v1.6.0
- name: Docker Login
uses: docker/login-action@v1.10.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker Login in Aliyun
uses: docker/login-action@v1.10.0
with:
registry: ${{ secrets.DOCKERHUB_REGISTRY_ALIYUN }}
username: ${{ secrets.DOCKERHUB_ACCOUNT_ALIYUN }}
password: ${{ secrets.DOCKERHUB_PASSWORD_ALIYUN }}
- name: Build and push Docker images
uses: docker/build-push-action@v2.7.0
with:
context: .
# 这里是适配 arm64 ,主要看你们的程序是否支持 arm64
platforms: linux/amd64,linux/arm64
file: web/Dockerfile
push: true
# 这里是给docker 打标签,默认不上传 latest
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/web:${{ github.event.inputs.webtag }}
${{ secrets.DOCKERHUB_REGISTRY_ALIYUN }}/${{ secrets.DOCKERHUB_USERNAME_ALIYUN }}web:${{ github.event.inputs.webtag }}
cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/web:${{ github.event.inputs.webtag }}.cache
cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/web:${{ github.event.inputs.webtag }}.cache,mode=max
# 漏洞扫描
- name: Scan for vulnerabilities
uses: crazy-max/ghaction-container-scan@v1
with:
image: ${{ secrets.DOCKERHUB_USERNAME }}/web:${{ github.event.inputs.webtag }}
dockerfile: web/Dockerfile
# 更新 docker 描述页面
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
repository: ${{ secrets.DOCKERHUB_USERNAME }}/web
GIN_VUE_ADMIN_SERVER:
name: GIN VUE ADMIN SERVER
runs-on: ubuntu-latest
steps:
- name: Private Actions Checkout
uses: actions/checkout@v2.3.4
- name: Docker Setup QEMU
uses: docker/setup-qemu-action@v1.2.0
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v1.6.0
- name: Docker Login
uses: docker/login-action@v1.10.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker Login in Aliyun
uses: docker/login-action@v1.10.0
with:
registry: ${{ secrets.DOCKERHUB_REGISTRY_ALIYUN }}
username: ${{ secrets.DOCKERHUB_ACCOUNT_ALIYUN }}
password: ${{ secrets.DOCKERHUB_PASSWORD_ALIYUN }}
- name: Build and push Docker images
uses: docker/build-push-action@v2.7.0
with:
context: .
# 这里是适配 arm64 ,主要看你们的程序是否支持 arm64
platforms: linux/amd64,linux/arm64
file: server/Dockerfile
push: true
# 这里是给docker 打标签,默认不上传 latest
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/server:${{ github.event.inputs.servertag }}
${{ secrets.DOCKERHUB_REGISTRY_ALIYUN }}/${{ secrets.DOCKERHUB_USERNAME_ALIYUN }}server:${{ github.event.inputs.servertag }}
cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/server:${{ github.event.inputs.servertag }}.cache
cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/server:${{ github.event.inputs.servertag }}.cache,mode=max
# 漏洞扫描
- name: Scan for vulnerabilities
uses: crazy-max/ghaction-container-scan@v1
with:
image: ${{ secrets.DOCKERHUB_USERNAME }}/server:${{ github.event.inputs.servertag }}
dockerfile: server/Dockerfile
# 更新 docker 描述页面
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
repository: ${{ secrets.DOCKERHUB_USERNAME }}/server
+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
+1 -1
View File
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2019 JiZhao Jiang
Copyright 2019 北京翻转极光科技有限责任公司
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+15 -3
View File
@@ -2,9 +2,9 @@ SHELL = /bin/bash
#SCRIPT_DIR = $(shell pwd)/etc/script
#请选择golang版本
BUILD_IMAGE_SERVER = golang:1.16
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
#配置文件目录
@@ -19,6 +19,11 @@ TAGS_OPT = latest
else
endif
ifeq ($(PLUGIN),)
PLUGIN = email
else
endif
#容器环境前后端共同打包
build: build-web build-server
docker run --name build-local --rm -v $(shell pwd):/go/src/${PROJECT_NAME} -w /go/src/${PROJECT_NAME} ${BUILD_IMAGE_SERVER} make build-local
@@ -63,4 +68,11 @@ image: build
#尝鲜版
images: build build-image-web build-image-server
docker build -t ${REPOSITORY}/all:${TAGS_OPT} -f deploy/docker/Dockerfile .
docker build -t ${REPOSITORY}/all:${TAGS_OPT} -f deploy/docker/Dockerfile .
#插件快捷打包: make plugin PLUGIN="这里是插件文件夹名称,默认为email"
plugin:
if [ -d ".plugin" ];then rm -rf .plugin ; else echo "OK!"; fi && mkdir -p .plugin/${PLUGIN}/{server/plugin,web/plugin} \
&& if [ -d "server/plugin/${PLUGIN}" ];then cp -r server/plugin/${PLUGIN} .plugin/${PLUGIN}/server/plugin/ ; else echo "OK!"; fi \
&& if [ -d "web/src/plugin/${PLUGIN}" ];then cp -r web/src/plugin/${PLUGIN} .plugin/${PLUGIN}/web/plugin/ ; else echo "OK!"; fi \
&& cd .plugin && zip -r ${PLUGIN}.zip ${PLUGIN} && mv ${PLUGIN}.zip ../ && cd ..
+9 -13
View File
@@ -1,13 +1,13 @@
<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.16-blue"/>
<img src="https://img.shields.io/badge/gin-1.7.0-lightBlue"/>
<img src="https://img.shields.io/badge/vue-3.2.25-brightgreen"/>
<img src="https://img.shields.io/badge/element--plus-2.0.1-green"/>
<img src="https://img.shields.io/badge/gorm-1.22.5-red"/>
<img src="https://img.shields.io/badge/golang-1.18-blue"/>
<img src="https://img.shields.io/badge/gin-1.9.1-lightBlue"/>
<img src="https://img.shields.io/badge/vue-3.3.4-brightgreen"/>
<img src="https://img.shields.io/badge/element--plus-2.3.8-green"/>
<img src="https://img.shields.io/badge/gorm-1.25.2-red"/>
</div>
English | [简体中文](./README.md)
@@ -16,16 +16,12 @@ 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/
[From the environment to the deployment of teaching videos](https://www.bilibili.com/video/BV1fV411y7dT)
[Development Steps](https://www.gin-vue-admin.com/docs/help) (Contributor: <a href="https://github.com/LLemonGreen">LLemonGreen</a> And <a href="https://github.com/fkk0509">Fann</a>)
[Development Steps](https://www.gin-vue-admin.com/guide/start-quickly/env.html) (Contributor: <a href="https://github.com/LLemonGreen">LLemonGreen</a> And <a href="https://github.com/fkk0509">Fann</a>)
## 1. Basic Introduction
@@ -297,7 +293,7 @@ swag init
| :---: |
| <img width="150" src="http://qmplusimg.henrongyi.top/qrjjz.png">
#### [About Us](https://www.gin-vue-admin.com/about/)
#### [About Us](https://www.gin-vue-admin.com/about/join.html)
## 8. Contributors
@@ -309,7 +305,7 @@ Thank you for considering your contribution to gin-vue-admin!
## 9. Donate
If you find this project useful, you can buy author a glass of juice :tropical_drink: [here](https://www.gin-vue-admin.com/docs/coffee)
If you find this project useful, you can buy author a glass of juice :tropical_drink: [here](https://www.gin-vue-admin.com/coffee/index.html)
## 10. Commercial considerations
+33 -72
View File
@@ -1,26 +1,17 @@
<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.16-blue"/>
<img src="https://img.shields.io/badge/gin-1.7.0-lightBlue"/>
<img src="https://img.shields.io/badge/vue-3.2.25-brightgreen"/>
<img src="https://img.shields.io/badge/element--plus-2.0.1-green"/>
<img src="https://img.shields.io/badge/gorm-1.22.5-red"/>
<img src="https://img.shields.io/badge/golang-1.20-blue"/>
<img src="https://img.shields.io/badge/gin-1.9.1-lightBlue"/>
<img src="https://img.shields.io/badge/vue-3.3.4-brightgreen"/>
<img src="https://img.shields.io/badge/element--plus-2.3.8-green"/>
<img src="https://img.shields.io/badge/gorm-1.25.2-red"/>
</div>
[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,13 +33,11 @@
3.您完全可以通过我们的教程和文档完成一切操作,因此我们不再提供免费的技术服务,如需服务请进行[付费支持](https://www.gin-vue-admin.com/coffee/payment.html)
4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,其余信息功能不做任何限制。如需剔除请联系微信:shouzi_1994
4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,以及日志和代码中所包含的版权声明信息。所需保留信息均为文案性质,不会影响任何业务内容,如决定商用且必须剔除请[购买授权](https://www.gin-vue-admin.com/empower/index.html)
<img src="https://qmplusimg.henrongyi.top/%E6%8E%88%E6%9D%83.png" width="1000">
<img src="https://qmplusimg.henrongyi.top/openSource/login.jpg" width="1000">
5.如果您需要服务器的话 2核2G腾讯云服务器45元/年 在这里购买:https://cloud.tencent.com/act/new?fromSource=gwzcw.4325959.4325959.4325959&utm_medium=cps&utm_id=gwzcw.4325959.4325959.4325959&cps_key=962a7fdaa930cda1c06e36a7608e95cc
阿里云服务器 1c2g1m 38一年 在这里购买:https://www.aliyun.com/minisite/goods?userCode=xqe01uob
<img src="https://qmplusimg.henrongyi.top/openSource/dashboard.jpg" width="1000">
## 1. 基本介绍
@@ -70,8 +59,8 @@ Gin-vue-admin 是一套为快速研发准备的一整套前后端分离架构式
Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-admin 贡献代码或提供建议,请阅读以下内容。
#### 1.2.1 Issue 规范
- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。如果你在使用时产生了疑问,请到 Slack 或 [Gitter](https://gitter.im/ElemeFE/element) 里咨询。
- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。
- 在提交 issue 之前,请搜索相关内容是否已被提出。
#### 1.2.2 Pull Request 规范
@@ -86,11 +75,9 @@ Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-adm
## 2. 使用说明
```
- node版本 > v12.18.3
- golang版本 >= v1.16
- node版本 > v16.8.3
- golang版本 >= v1.22
- IDE推荐:Goland
- 初始化项目: 不同版本数据库初始化不通 参见 https://www.gin-vue-admin.com/docs/first_master
- 替换掉项目中的七牛云公钥,私钥,仓名和默认url地址,以免发生测试文件数据错乱
```
### 2.1 server项目
@@ -107,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项目
@@ -121,7 +106,7 @@ go build -o server main.go (windows编译命令为go build -o server.exe main.go
cd web
# 安装依赖
cnpm install || npm install
npm install
# 启动web项目
npm run serve
@@ -131,29 +116,8 @@ npm run serve
#### 2.3.1 安装 swagger
##### (1)可以访问外国网站
````
go get -u github.com/swaggo/swag/cmd/swag
````
##### (2)无法访问外国网站
由于国内没法安装 go.org/x 包下面的东西,推荐使用 [goproxy.cn](https://goproxy.cn) 或者 [goproxy.io](https://goproxy.io/zh/)
```bash
# 如果您使用的 Go 版本是 1.13 - 1.15 需要手动设置GO111MODULE=on, 开启方式如下命令, 如果你的 Go 版本 是 1.16 ~ 最新版 可以忽略以下步骤一
# 步骤一、启用 Go Modules 功能
go env -w GO111MODULE=on
# 步骤二、配置 GOPROXY 环境变量
go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct
# 如果嫌弃麻烦,可以使用go generate 编译前自动执行代码, 不过这个不能使用 `Goland` 或者 `Vscode` 的 命令行终端
cd server
go generate -run "go env -w .*?"
# 使用如下命令下载swag
go get -u github.com/swaggo/swag/cmd/swag
``` shell
go install github.com/swaggo/swag/cmd/swag@latest
```
#### 2.3.2 生成API文档
@@ -188,7 +152,7 @@ swag init
- 前端:用基于 [Vue](https://vuejs.org) 的 [Element](https://github.com/ElemeFE/element) 构建基础页面。
- 后端:用 [Gin](https://gin-gonic.com/) 快速搭建基础restful风格API,[Gin](https://gin-gonic.com/) 是一个go语言编写的Web框架。
- 数据库:采用`MySql`(5.6.44)版本,使用 [gorm](http://gorm.cn) 实现对数据库的基本操作。
- 数据库:采用`MySql` > (5.7) 版本 数据库引擎 InnoDB,使用 [gorm](http://gorm.cn) 实现对数据库的基本操作。
- 缓存:使用`Redis`实现记录当前活跃用户的`jwt`令牌并实现多点登录限制。
- API文档:使用`Swagger`构建自动化文档。
- 配置文件:使用 [fsnotify](https://github.com/fsnotify/fsnotify) 和 [viper](https://github.com/spf13/viper) 实现`yaml`格式的配置文件。
@@ -320,8 +284,8 @@ swag init
- 前端文件参考: [web/src/view/superAdmin/api/api.vue](https://github.com/flipped-aurora/gin-vue-admin/blob/master/web/src/view/superAdmin/api/api.vue)
- 后台文件参考: [server/router/sys_api.go](https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/router/sys_api.go)
- 多点登录限制:需要在`config.yaml`中把`system`中的`use-multipoint`修改为true(需要自行配置Redis和Config中的Redis参数,测试阶段,有bug请及时反馈)。
- 分片长传:提供文件分片上传和大文件分片上传功能示例。
- 表单生成器:表单生成器借助 [@form-generator](https://github.com/JakHuang/form-generator) 。
- 分片上传:提供文件分片上传和大文件分片上传功能示例。
- 表单生成器:表单生成器借助 [@Variant Form](https://github.com/vform666/variant-form) 。
- 代码生成器:后台基础逻辑以及简单curd的代码生成器。
## 6. 知识库
@@ -352,25 +316,28 @@ swag init
(5)gin-vue-admin 版本更新介绍视频
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=126418&ctype=0
> bilibili:https://www.bilibili.com/video/BV1kv4y1g7nT
## 7. 联系方式
### 7.1 技术群
### QQ交流群:622360840
| QQ 群 |
| :---: |
| <img src="http://qmplusimg.henrongyi.top/qq.jpg" width="180"/> |
### QQ交流群:470239250
### 微信交流群
| 微信 |
| :---: |
| <img width="150" src="http://qmplusimg.henrongyi.top/qrjjz.png">
添加微信,备注"加入gin-vue-admin交流群"
防止广告进群,添加微信,输入以下代码执行结果(请勿转码为string)
### [关于我们](https://www.gin-vue-admin.com/about/)
```
str := "5Yqg5YWlR1ZB5Lqk5rWB576k"
decodeBytes, err := base64.StdEncoding.DecodeString(str)
fmt.Println(decodeBytes, err)
```
### [关于我们](https://www.gin-vue-admin.com/about/join.html)
## 8. 贡献者
@@ -382,14 +349,8 @@ swag init
## 9. 捐赠
如果你觉得这个项目对你有帮助,你可以请作者喝饮料 :tropical_drink: [点我](https://www.gin-vue-admin.com/docs/coffee)
如果你觉得这个项目对你有帮助,你可以请作者喝饮料 :tropical_drink: [点我](https://www.gin-vue-admin.com/coffee/index.html)
## 10. 友情链接
[H5-Dooring | H5页面制作神器](https://github.com/MrXujiang/h5-Dooring)
[go-zero 微服务框架|缩短从需求到上线的距离](https://github.com/zeromicro/go-zero)
## 11. 商用注意事项
## 10. 商用注意事项
如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。
+22 -8
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,26 +25,28 @@ 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
- ../../web:/web
networks:
network:
ipv4_address: 177.7.0.11
server:
image: golang:1.16
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
- ../../server:/server
working_dir: /server # 如果docker 设置了workdir 则此处不需要设置
command: bash -c "go env -w GOPROXY=https://goproxy.cn,direct && go mod tidy && go run main.go"
links:
@@ -63,8 +65,15 @@ services:
ports:
- "13306:3306" # host物理直接映射端口为13306
environment:
#MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
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:
@@ -78,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:
+19 -5
View File
@@ -16,7 +16,7 @@ volumes:
services:
web:
build:
context: ./web
context: ../../web
dockerfile: ./Dockerfile
container_name: gva-web
restart: always
@@ -31,15 +31,17 @@ services:
server:
build:
context: ./server
context: ../../server
dockerfile: ./Dockerfile
container_name: gva-server
restart: always
ports:
- '8888:8888'
depends_on:
- mysql
- redis
mysql:
condition: service_healthy
redis:
condition: service_healthy
links:
- mysql
- redis
@@ -55,8 +57,15 @@ services:
ports:
- "13306:3306" # host物理直接映射端口为13306
environment:
#MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
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:
@@ -69,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:
+1 -1
View File
@@ -9,7 +9,7 @@ RUN set -ex \
&& echo "LANG=en_US.utf8" > /etc/locale.conf \
&& echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf \
&& echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf \
&& yum -y install yum -y install *epel* \
&& yum -y install epel-release \
&& yum -y localinstall http://mirrors.ustc.edu.cn/mysql-repo/mysql57-community-release-el7.rpm \
&& yum -y install mysql-community-server git redis nginx go npm --nogpgcheck && chmod +x ./entrypoint.sh \
&& npm install -g yarn && go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct \
@@ -29,7 +29,7 @@ spec:
- containerPort: 8888
name: http
volumeMounts:
- mountPath: /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.yaml
- mountPath: /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.docker.yaml
name: config
subPath: config.yaml
- mountPath: /etc/localtime
+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
+5 -5
View File
@@ -5,9 +5,9 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/api/v1/system"
)
type ApiGroup struct {
SystemApiGroup system.ApiGroup
ExampleApiGroup example.ApiGroup
}
var ApiGroupApp = new(ApiGroup)
type ApiGroup struct {
SystemApiGroup system.ApiGroup
ExampleApiGroup example.ApiGroup
}
-2
View File
@@ -3,13 +3,11 @@ package example
import "github.com/flipped-aurora/gin-vue-admin/server/service"
type ApiGroup struct {
ExcelApi
CustomerApi
FileUploadAndDownloadApi
}
var (
excelService = service.ServiceGroupApp.ExampleServiceGroup.ExcelService
customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService
fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService
)
@@ -2,7 +2,7 @@ package example
import (
"fmt"
"io/ioutil"
"io"
"mime/multipart"
"strconv"
@@ -16,14 +16,15 @@ import (
"go.uber.org/zap"
)
// @Tags ExaFileUploadAndDownload
// @Summary 断点续传到服务器
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "an example for breakpoint resume, 断点续传示例"
// @Success 200 {object} response.Response{msg=string} "断点续传到服务器"
// @Router /fileUploadAndDownload/breakpointContinue [post]
// BreakpointContinue
// @Tags ExaFileUploadAndDownload
// @Summary 断点续传到服务器
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "an example for breakpoint resume, 断点续传示例"
// @Success 200 {object} response.Response{msg=string} "断点续传到服务器"
// @Router /fileUploadAndDownload/breakpointContinue [post]
func (b *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) {
fileMd5 := c.Request.FormValue("fileMd5")
fileName := c.Request.FormValue("fileName")
@@ -48,7 +49,7 @@ func (b *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) {
fmt.Println(err)
}
}(f)
cen, _ := ioutil.ReadAll(f)
cen, _ := io.ReadAll(f)
if !utils.CheckMd5(cen, chunkMd5) {
global.GVA_LOG.Error("检查md5失败!", zap.Error(err))
response.FailWithMessage("检查md5失败", c)
@@ -75,14 +76,15 @@ func (b *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) {
response.OkWithMessage("切片创建成功", c)
}
// @Tags ExaFileUploadAndDownload
// @Summary 查找文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @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]
// FindFile
// @Tags ExaFileUploadAndDownload
// @Summary 查找文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @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]
func (b *FileUploadAndDownloadApi) FindFile(c *gin.Context) {
fileMd5 := c.Query("fileMd5")
fileName := c.Query("fileName")
@@ -96,14 +98,15 @@ func (b *FileUploadAndDownloadApi) FindFile(c *gin.Context) {
}
}
// @Tags ExaFileUploadAndDownload
// @Summary 创建文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "上传文件完成"
// @Success 200 {object} response.Response{data=exampleRes.FilePathResponse,msg=string} "创建文件,返回包括文件路径"
// @Router /fileUploadAndDownload/findFile [post]
// BreakpointContinueFinish
// @Tags ExaFileUploadAndDownload
// @Summary 创建文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "上传文件完成"
// @Success 200 {object} response.Response{data=exampleRes.FilePathResponse,msg=string} "创建文件,返回包括文件路径"
// @Router /fileUploadAndDownload/findFile [post]
func (b *FileUploadAndDownloadApi) BreakpointContinueFinish(c *gin.Context) {
fileMd5 := c.Query("fileMd5")
fileName := c.Query("fileName")
@@ -116,18 +119,23 @@ func (b *FileUploadAndDownloadApi) BreakpointContinueFinish(c *gin.Context) {
}
}
// @Tags ExaFileUploadAndDownload
// @Summary 删除切片
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "删除缓存切片"
// @Success 200 {object} response.Response{msg=string} "删除切片"
// @Router /fileUploadAndDownload/removeChunk [post]
// RemoveChunk
// @Tags ExaFileUploadAndDownload
// @Summary 删除切片
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "删除缓存切片"
// @Success 200 {object} response.Response{msg=string} "删除切片"
// @Router /fileUploadAndDownload/removeChunk [post]
func (b *FileUploadAndDownloadApi) RemoveChunk(c *gin.Context) {
var file example.ExaFile
_ = c.ShouldBindJSON(&file)
err := utils.RemoveChunk(file.FileMd5)
err := c.ShouldBindJSON(&file)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.RemoveChunk(file.FileMd5)
if err != nil {
global.GVA_LOG.Error("缓存切片删除失败!", zap.Error(err))
return
@@ -136,7 +144,7 @@ func (b *FileUploadAndDownloadApi) RemoveChunk(c *gin.Context) {
if err != nil {
global.GVA_LOG.Error(err.Error(), zap.Error(err))
response.FailWithMessage(err.Error(), c)
} else {
response.OkWithMessage("缓存切片删除成功", c)
return
}
response.OkWithMessage("缓存切片删除成功", c)
}
+103 -69
View File
@@ -13,93 +13,121 @@ import (
type CustomerApi struct{}
// @Tags ExaCustomer
// @Summary 创建客户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body example.ExaCustomer true "客户用户名, 客户手机号码"
// @Success 200 {object} response.Response{msg=string} "创建客户"
// @Router /customer/customer [post]
// CreateExaCustomer
// @Tags ExaCustomer
// @Summary 创建客户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body example.ExaCustomer true "客户用户名, 客户手机号码"
// @Success 200 {object} response.Response{msg=string} "创建客户"
// @Router /customer/customer [post]
func (e *CustomerApi) CreateExaCustomer(c *gin.Context) {
var customer example.ExaCustomer
_ = c.ShouldBindJSON(&customer)
if err := utils.Verify(customer, utils.CustomerVerify); err != nil {
err := c.ShouldBindJSON(&customer)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(customer, utils.CustomerVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
customer.SysUserID = utils.GetUserID(c)
customer.SysUserAuthorityID = utils.GetUserAuthorityId(c)
if err := customerService.CreateExaCustomer(customer); err != nil {
err = customerService.CreateExaCustomer(customer)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
} else {
response.OkWithMessage("创建成功", c)
return
}
response.OkWithMessage("创建成功", c)
}
// @Tags ExaCustomer
// @Summary 删除客户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body example.ExaCustomer true "客户ID"
// @Success 200 {object} response.Response{msg=string} "删除客户"
// @Router /customer/customer [delete]
// DeleteExaCustomer
// @Tags ExaCustomer
// @Summary 删除客户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body example.ExaCustomer true "客户ID"
// @Success 200 {object} response.Response{msg=string} "删除客户"
// @Router /customer/customer [delete]
func (e *CustomerApi) DeleteExaCustomer(c *gin.Context) {
var customer example.ExaCustomer
_ = c.ShouldBindJSON(&customer)
if err := utils.Verify(customer.GVA_MODEL, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&customer)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := customerService.DeleteExaCustomer(customer); err != nil {
err = utils.Verify(customer.GVA_MODEL, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = customerService.DeleteExaCustomer(customer)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
return
}
response.OkWithMessage("删除成功", c)
}
// @Tags ExaCustomer
// @Summary 更新客户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body example.ExaCustomer true "客户ID, 客户信息"
// @Success 200 {object} response.Response{msg=string} "更新客户信息"
// @Router /customer/customer [put]
// UpdateExaCustomer
// @Tags ExaCustomer
// @Summary 更新客户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body example.ExaCustomer true "客户ID, 客户信息"
// @Success 200 {object} response.Response{msg=string} "更新客户信息"
// @Router /customer/customer [put]
func (e *CustomerApi) UpdateExaCustomer(c *gin.Context) {
var customer example.ExaCustomer
_ = c.ShouldBindJSON(&customer)
if err := utils.Verify(customer.GVA_MODEL, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&customer)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := utils.Verify(customer, utils.CustomerVerify); err != nil {
err = utils.Verify(customer.GVA_MODEL, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := customerService.UpdateExaCustomer(&customer); err != nil {
err = utils.Verify(customer, utils.CustomerVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = customerService.UpdateExaCustomer(&customer)
if err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
} else {
response.OkWithMessage("更新成功", c)
return
}
response.OkWithMessage("更新成功", c)
}
// @Tags ExaCustomer
// @Summary 获取单一客户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query example.ExaCustomer true "客户ID"
// @Success 200 {object} response.Response{data=exampleRes.ExaCustomerResponse,msg=string} "获取单一客户信息,返回包括客户详情"
// @Router /customer/customer [get]
// GetExaCustomer
// @Tags ExaCustomer
// @Summary 获取单一客户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query example.ExaCustomer true "客户ID"
// @Success 200 {object} response.Response{data=exampleRes.ExaCustomerResponse,msg=string} "获取单一客户信息,返回包括客户详情"
// @Router /customer/customer [get]
func (e *CustomerApi) GetExaCustomer(c *gin.Context) {
var customer example.ExaCustomer
_ = c.ShouldBindQuery(&customer)
if err := utils.Verify(customer.GVA_MODEL, utils.IdVerify); err != nil {
err := c.ShouldBindQuery(&customer)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(customer.GVA_MODEL, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
@@ -107,23 +135,29 @@ func (e *CustomerApi) GetExaCustomer(c *gin.Context) {
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(exampleRes.ExaCustomerResponse{Customer: data}, "获取成功", c)
return
}
response.OkWithDetailed(exampleRes.ExaCustomerResponse{Customer: data}, "获取成功", c)
}
// @Tags ExaCustomer
// @Summary 分页获取权限客户列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query request.PageInfo true "页码, 每页大小"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取权限客户列表,返回包括列表,总数,页码,每页数量"
// @Router /customer/customerList [get]
// GetExaCustomerList
// @Tags ExaCustomer
// @Summary 分页获取权限客户列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query request.PageInfo true "页码, 每页大小"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取权限客户列表,返回包括列表,总数,页码,每页数量"
// @Router /customer/customerList [get]
func (e *CustomerApi) GetExaCustomerList(c *gin.Context) {
var pageInfo request.PageInfo
_ = c.ShouldBindQuery(&pageInfo)
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
err := c.ShouldBindQuery(&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
}
@@ -131,12 +165,12 @@ func (e *CustomerApi) GetExaCustomerList(c *gin.Context) {
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败"+err.Error(), c)
} else {
response.OkWithDetailed(response.PageResult{
List: customerList,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithDetailed(response.PageResult{
List: customerList,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
-111
View File
@@ -1,111 +0,0 @@
package example
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/example"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"os"
"strings"
)
type ExcelApi struct{}
// /excel/importExcel 接口,与upload接口作用类似,只是把文件存到resource/excel目录下,用于导入Excel时存放Excel文件(ExcelImport.xlsx)
// /excel/loadExcel接口,用于读取resource/excel目录下的文件((ExcelImport.xlsx)并加载为[]model.SysBaseMenu类型的示例数据
// /excel/exportExcel 接口,用于读取前端传来的tableData,生成Excel文件并返回
// /excel/downloadTemplate 接口,用于下载resource/excel目录下的 ExcelTemplate.xlsx 文件,作为导入的模板
// @Tags excel
// @Summary 导出Excel
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/octet-stream
// @Param data body example.ExcelInfo true "导出Excel文件信息"
// @Success 200
// @Router /excel/exportExcel [post]
func (e *ExcelApi) ExportExcel(c *gin.Context) {
var excelInfo example.ExcelInfo
_ = c.ShouldBindJSON(&excelInfo)
if strings.Index(excelInfo.FileName, "..") > -1 {
response.FailWithMessage("包含非法字符", c)
return
}
filePath := global.GVA_CONFIG.Excel.Dir + excelInfo.FileName
err := excelService.ParseInfoList2Excel(excelInfo.InfoList, filePath)
if err != nil {
global.GVA_LOG.Error("转换Excel失败!", zap.Error(err))
response.FailWithMessage("转换Excel失败", c)
return
}
c.Writer.Header().Add("success", "true")
c.File(filePath)
}
// @Tags excel
// @Summary 导入Excel文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "导入Excel文件"
// @Success 200 {object} response.Response{msg=string} "导入Excel文件"
// @Router /excel/importExcel [post]
func (e *ExcelApi) ImportExcel(c *gin.Context) {
_, header, err := c.Request.FormFile("file")
if err != nil {
global.GVA_LOG.Error("接收文件失败!", zap.Error(err))
response.FailWithMessage("接收文件失败", c)
return
}
_ = c.SaveUploadedFile(header, global.GVA_CONFIG.Excel.Dir+"ExcelImport.xlsx")
response.OkWithMessage("导入成功", c)
}
// @Tags excel
// @Summary 加载Excel数据
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "加载Excel数据,返回包括列表,总数,页码,每页数量"
// @Router /excel/loadExcel [get]
func (e *ExcelApi) LoadExcel(c *gin.Context) {
menus, err := excelService.ParseExcel2InfoList()
if err != nil {
global.GVA_LOG.Error("加载数据失败!", zap.Error(err))
response.FailWithMessage("加载数据失败", c)
return
}
response.OkWithDetailed(response.PageResult{
List: menus,
Total: int64(len(menus)),
Page: 1,
PageSize: 999,
}, "加载数据成功", c)
}
// @Tags excel
// @Summary 下载模板
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param fileName query string true "模板名称"
// @Success 200
// @Router /excel/downloadTemplate [get]
func (e *ExcelApi) DownloadTemplate(c *gin.Context) {
fileName := c.Query("fileName")
filePath := global.GVA_CONFIG.Excel.Dir + fileName
fi, err := os.Stat(filePath)
if err != nil {
global.GVA_LOG.Error("文件不存在!", zap.Error(err))
response.FailWithMessage("文件不存在", c)
return
}
if fi.IsDir() {
global.GVA_LOG.Error("不支持下载文件夹!", zap.Error(err))
response.FailWithMessage("不支持下载文件夹", c)
return
}
c.Writer.Header().Add("success", "true")
c.File(filePath)
}
@@ -12,14 +12,15 @@ import (
type FileUploadAndDownloadApi struct{}
// @Tags ExaFileUploadAndDownload
// @Summary 上传文件示例
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "上传文件示例"
// @Success 200 {object} response.Response{data=exampleRes.ExaFileResponse,msg=string} "上传文件示例,返回包括文件详情"
// @Router /fileUploadAndDownload/upload [post]
// UploadFile
// @Tags ExaFileUploadAndDownload
// @Summary 上传文件示例
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "上传文件示例"
// @Success 200 {object} response.Response{data=exampleRes.ExaFileResponse,msg=string} "上传文件示例,返回包括文件详情"
// @Router /fileUploadAndDownload/upload [post]
func (b *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
var file example.ExaFileUploadAndDownload
noSave := c.DefaultQuery("noSave", "0")
@@ -41,8 +42,13 @@ func (b *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
// EditFileName 编辑文件名或者备注
func (b *FileUploadAndDownloadApi) EditFileName(c *gin.Context) {
var file example.ExaFileUploadAndDownload
_ = c.ShouldBindJSON(&file)
if err := fileUploadAndDownloadService.EditFileName(file); err != nil {
err := c.ShouldBindJSON(&file)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = fileUploadAndDownloadService.EditFileName(file)
if err != nil {
global.GVA_LOG.Error("编辑失败!", zap.Error(err))
response.FailWithMessage("编辑失败", c)
return
@@ -50,16 +56,21 @@ func (b *FileUploadAndDownloadApi) EditFileName(c *gin.Context) {
response.OkWithMessage("编辑成功", c)
}
// @Tags ExaFileUploadAndDownload
// @Summary 删除文件
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body example.ExaFileUploadAndDownload true "传入文件里面id即可"
// @Success 200 {object} response.Response{msg=string} "删除文件"
// @Router /fileUploadAndDownload/deleteFile [post]
// DeleteFile
// @Tags ExaFileUploadAndDownload
// @Summary 删除文件
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body example.ExaFileUploadAndDownload true "传入文件里面id即可"
// @Success 200 {object} response.Response{msg=string} "删除文件"
// @Router /fileUploadAndDownload/deleteFile [post]
func (b *FileUploadAndDownloadApi) DeleteFile(c *gin.Context) {
var file example.ExaFileUploadAndDownload
_ = c.ShouldBindJSON(&file)
err := c.ShouldBindJSON(&file)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := fileUploadAndDownloadService.DeleteFile(file); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
@@ -68,27 +79,32 @@ func (b *FileUploadAndDownloadApi) DeleteFile(c *gin.Context) {
response.OkWithMessage("删除成功", c)
}
// @Tags ExaFileUploadAndDownload
// @Summary 分页文件列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页文件列表,返回包括列表,总数,页码,每页数量"
// @Router /fileUploadAndDownload/getFileList [post]
// GetFileList
// @Tags ExaFileUploadAndDownload
// @Summary 分页文件列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页文件列表,返回包括列表,总数,页码,每页数量"
// @Router /fileUploadAndDownload/getFileList [post]
func (b *FileUploadAndDownloadApi) GetFileList(c *gin.Context) {
var pageInfo request.PageInfo
_ = c.ShouldBindJSON(&pageInfo)
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := fileUploadAndDownloadService.GetFileRecordInfoList(pageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
+115
View File
@@ -0,0 +1,115 @@
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"
request "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AutoCodeHistoryApi struct{}
// First
// @Tags AutoCode
// @Summary 获取meta信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "请求参数"
// @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 common.GetById
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
data, err := autoCodeHistoryService.First(c.Request.Context(), info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
response.OkWithDetailed(gin.H{"meta": data}, "获取成功", c)
}
// Delete
// @Tags AutoCode
// @Summary 删除回滚记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "请求参数"
// @Success 200 {object} response.Response{msg=string} "删除回滚记录"
// @Router /autoCode/delSysHistory [post]
func (a *AutoCodeHistoryApi) Delete(c *gin.Context) {
var info common.GetById
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = autoCodeHistoryService.Delete(c.Request.Context(), info)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
// RollBack
// @Tags AutoCode
// @Summary 回滚自动生成代码
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @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 request.SysAutoHistoryRollBack
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = autoCodeHistoryService.RollBack(c.Request.Context(), info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
response.OkWithMessage("回滚成功", c)
}
// GetList
// @Tags AutoCode
// @Summary 查询回滚记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @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 info common.PageInfo
err := c.ShouldBindJSON(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := autoCodeHistoryService.GetList(c.Request.Context(), info)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
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)
}
+70
View File
@@ -0,0 +1,70 @@
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/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 [get]
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)
}
+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)
}
}
+11 -4
View File
@@ -14,9 +14,13 @@ type ApiGroup struct {
DictionaryApi
AuthorityMenuApi
OperationRecordApi
AutoCodeHistoryApi
DictionaryDetailApi
AuthorityBtnApi
SysExportTemplateApi
AutoCodePluginApi
AutoCodePackageApi
AutoCodeHistoryApi
AutoCodeTemplateApi
}
var (
@@ -26,13 +30,16 @@ 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
authorityBtnService = service.ServiceGroupApp.SystemServiceGroup.AuthorityBtnService
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
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
)
+253 -103
View File
@@ -15,92 +15,210 @@ import (
type SystemApiApi struct{}
// @Tags SysApi
// @Summary 创建基础api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysApi true "api路径, api中文描述, api组, 方法"
// @Success 200 {object} response.Response{msg=string} "创建基础api"
// @Router /api/createApi [post]
// CreateApi
// @Tags SysApi
// @Summary 创建基础api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysApi true "api路径, api中文描述, api组, 方法"
// @Success 200 {object} response.Response{msg=string} "创建基础api"
// @Router /api/createApi [post]
func (s *SystemApiApi) CreateApi(c *gin.Context) {
var api system.SysApi
_ = c.ShouldBindJSON(&api)
if err := utils.Verify(api, utils.ApiVerify); err != nil {
err := c.ShouldBindJSON(&api)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := apiService.CreateApi(api); err != nil {
err = utils.Verify(api, utils.ApiVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = apiService.CreateApi(api)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// @Tags SysApi
// @Summary 删除api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysApi true "ID"
// @Success 200 {object} response.Response{msg=string} "删除api"
// @Router /api/deleteApi [post]
func (s *SystemApiApi) DeleteApi(c *gin.Context) {
var api system.SysApi
_ = c.ShouldBindJSON(&api)
if err := utils.Verify(api.GVA_MODEL, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := apiService.DeleteApi(api); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
}
response.OkWithMessage("创建成功", c)
}
// @Tags SysApi
// @Summary 分页获取API列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SearchApiParams true "分页获取API列表"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取API列表,返回包括列表,总数,页码,每页数量"
// @Router /api/getApiList [post]
func (s *SystemApiApi) GetApiList(c *gin.Context) {
var pageInfo systemReq.SearchApiParams
_ = c.ShouldBindJSON(&pageInfo)
if err := utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify); err != nil {
response.FailWithMessage(err.Error(), 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
}
if list, total, err := apiService.GetAPIInfoList(pageInfo.SysApi, pageInfo.PageInfo, pageInfo.OrderKey, pageInfo.Desc); err != nil {
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 [post]
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)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithData(gin.H{
"groups": groups,
"apiGroupMap": apiGroupMap,
}, c)
}
// @Tags SysApi
// @Summary 根据id获取api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "根据id获取api"
// @Success 200 {object} response.Response{data=systemRes.SysAPIResponse} "根据id获取api,返回包括api详情"
// @Router /api/getApiById [post]
// 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
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysApi true "ID"
// @Success 200 {object} response.Response{msg=string} "删除api"
// @Router /api/deleteApi [post]
func (s *SystemApiApi) DeleteApi(c *gin.Context) {
var api system.SysApi
err := c.ShouldBindJSON(&api)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(api.GVA_MODEL, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = apiService.DeleteApi(api)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
// GetApiList
// @Tags SysApi
// @Summary 分页获取API列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SearchApiParams true "分页获取API列表"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取API列表,返回包括列表,总数,页码,每页数量"
// @Router /api/getApiList [post]
func (s *SystemApiApi) GetApiList(c *gin.Context) {
var pageInfo systemReq.SearchApiParams
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := apiService.GetAPIInfoList(pageInfo.SysApi, pageInfo.PageInfo, pageInfo.OrderKey, pageInfo.Desc)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
// GetApiById
// @Tags SysApi
// @Summary 根据id获取api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "根据id获取api"
// @Success 200 {object} response.Response{data=systemRes.SysAPIResponse} "根据id获取api,返回包括api详情"
// @Router /api/getApiById [post]
func (s *SystemApiApi) GetApiById(c *gin.Context) {
var idInfo request.GetById
_ = c.ShouldBindJSON(&idInfo)
if err := utils.Verify(idInfo, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&idInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(idInfo, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
@@ -108,65 +226,97 @@ func (s *SystemApiApi) GetApiById(c *gin.Context) {
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(systemRes.SysAPIResponse{Api: api}, "获取成功", c)
return
}
response.OkWithDetailed(systemRes.SysAPIResponse{Api: api}, "获取成功", c)
}
// @Tags SysApi
// @Summary 修改基础api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysApi true "api路径, api中文描述, api组, 方法"
// @Success 200 {object} response.Response{msg=string} "修改基础api"
// @Router /api/updateApi [post]
// UpdateApi
// @Tags SysApi
// @Summary 修改基础api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysApi true "api路径, api中文描述, api组, 方法"
// @Success 200 {object} response.Response{msg=string} "修改基础api"
// @Router /api/updateApi [post]
func (s *SystemApiApi) UpdateApi(c *gin.Context) {
var api system.SysApi
_ = c.ShouldBindJSON(&api)
if err := utils.Verify(api, utils.ApiVerify); err != nil {
err := c.ShouldBindJSON(&api)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := apiService.UpdateApi(api); err != nil {
err = utils.Verify(api, utils.ApiVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = apiService.UpdateApi(api)
if err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage("修改失败", c)
} else {
response.OkWithMessage("修改成功", c)
return
}
response.OkWithMessage("修改成功", c)
}
// @Tags SysApi
// @Summary 获取所有的Api 不分页
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=systemRes.SysAPIListResponse,msg=string} "获取所有的Api 不分页,返回包括api列表"
// @Router /api/getAllApis [post]
// GetAllApis
// @Tags SysApi
// @Summary 获取所有的Api 不分页
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=systemRes.SysAPIListResponse,msg=string} "获取所有的Api 不分页,返回包括api列表"
// @Router /api/getAllApis [post]
func (s *SystemApiApi) GetAllApis(c *gin.Context) {
if apis, err := apiService.GetAllApis(); err != nil {
apis, err := apiService.GetAllApis()
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(systemRes.SysAPIListResponse{Apis: apis}, "获取成功", c)
return
}
response.OkWithDetailed(systemRes.SysAPIListResponse{Apis: apis}, "获取成功", c)
}
// @Tags SysApi
// @Summary 删除选中Api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "ID"
// @Success 200 {object} response.Response{msg=string} "删除选中Api"
// @Router /api/deleteApisByIds [delete]
// DeleteApisByIds
// @Tags SysApi
// @Summary 删除选中Api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "ID"
// @Success 200 {object} response.Response{msg=string} "删除选中Api"
// @Router /api/deleteApisByIds [delete]
func (s *SystemApiApi) DeleteApisByIds(c *gin.Context) {
var ids request.IdsReq
_ = c.ShouldBindJSON(&ids)
if err := apiService.DeleteApisByIds(ids); err != nil {
err := c.ShouldBindJSON(&ids)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = apiService.DeleteApisByIds(ids)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
return
}
response.OkWithMessage("删除成功", c)
}
// FreshCasbin
// @Tags SysApi
// @Summary 刷新casbin缓存
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "刷新成功"
// @Router /api/freshCasbin [get]
func (s *SystemApiApi) FreshCasbin(c *gin.Context) {
err := casbinService.FreshCasbin()
if err != nil {
global.GVA_LOG.Error("刷新失败!", zap.Error(err))
response.FailWithMessage("刷新失败", c)
return
}
response.OkWithMessage("刷新成功", c)
}
+135 -88
View File
@@ -5,7 +5,6 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
@@ -15,151 +14,199 @@ import (
type AuthorityApi struct{}
// @Tags Authority
// @Summary 创建角色
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAuthority true "权限id, 权限名, 父角色id"
// @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "创建角色,返回包括系统角色详情"
// @Router /authority/createAuthority [post]
// CreateAuthority
// @Tags Authority
// @Summary 创建角色
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAuthority true "权限id, 权限名, 父角色id"
// @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "创建角色,返回包括系统角色详情"
// @Router /authority/createAuthority [post]
func (a *AuthorityApi) CreateAuthority(c *gin.Context) {
var authority system.SysAuthority
_ = c.ShouldBindJSON(&authority)
if err := utils.Verify(authority, utils.AuthorityVerify); err != nil {
var authority, authBack system.SysAuthority
var err error
if err = c.ShouldBindJSON(&authority); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if authBack, err := authorityService.CreateAuthority(authority); err != nil {
if err = utils.Verify(authority, utils.AuthorityVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if authBack, err = authorityService.CreateAuthority(authority); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败"+err.Error(), c)
} else {
_ = menuService.AddMenuAuthority(systemReq.DefaultMenu(), authority.AuthorityId)
_ = casbinService.UpdateCasbin(authority.AuthorityId, systemReq.DefaultCasbin())
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "创建成功", c)
return
}
err = casbinService.FreshCasbin()
if err != nil {
global.GVA_LOG.Error("创建成功,权限刷新失败。", zap.Error(err))
response.FailWithMessage("创建成功,权限刷新失败。"+err.Error(), c)
return
}
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "创建成功", c)
}
// @Tags Authority
// @Summary 拷贝角色
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body response.SysAuthorityCopyResponse true "旧角色id, 新权限id, 新权限名, 新父角色id"
// @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "拷贝角色,返回包括系统角色详情"
// @Router /authority/copyAuthority [post]
// CopyAuthority
// @Tags Authority
// @Summary 拷贝角色
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body response.SysAuthorityCopyResponse true "旧角色id, 新权限id, 新权限名, 新父角色id"
// @Success 200 {object} response.Response{data=systemRes.SysAuthorityResponse,msg=string} "拷贝角色,返回包括系统角色详情"
// @Router /authority/copyAuthority [post]
func (a *AuthorityApi) CopyAuthority(c *gin.Context) {
var copyInfo systemRes.SysAuthorityCopyResponse
_ = c.ShouldBindJSON(&copyInfo)
if err := utils.Verify(copyInfo, utils.OldAuthorityVerify); err != nil {
err := c.ShouldBindJSON(&copyInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := utils.Verify(copyInfo.Authority, utils.AuthorityVerify); err != nil {
err = utils.Verify(copyInfo, utils.OldAuthorityVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if authBack, err := authorityService.CopyAuthority(copyInfo); err != nil {
err = utils.Verify(copyInfo.Authority, utils.AuthorityVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
authBack, err := authorityService.CopyAuthority(copyInfo)
if err != nil {
global.GVA_LOG.Error("拷贝失败!", zap.Error(err))
response.FailWithMessage("拷贝失败"+err.Error(), c)
} else {
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "拷贝成功", c)
return
}
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "拷贝成功", c)
}
// @Tags Authority
// @Summary 删除角色
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAuthority true "删除角色"
// @Success 200 {object} response.Response{msg=string} "删除角色"
// @Router /authority/deleteAuthority [post]
// DeleteAuthority
// @Tags Authority
// @Summary 删除角色
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAuthority true "删除角色"
// @Success 200 {object} response.Response{msg=string} "删除角色"
// @Router /authority/deleteAuthority [post]
func (a *AuthorityApi) DeleteAuthority(c *gin.Context) {
var authority system.SysAuthority
_ = c.ShouldBindJSON(&authority)
if err := utils.Verify(authority, utils.AuthorityIdVerify); err != nil {
var err error
if err = c.ShouldBindJSON(&authority); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := authorityService.DeleteAuthority(&authority); err != nil { // 删除角色之前需要判断是否有用户正在使用此角色
if err = utils.Verify(authority, utils.AuthorityIdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// 删除角色之前需要判断是否有用户正在使用此角色
if err = authorityService.DeleteAuthority(&authority); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败"+err.Error(), c)
} else {
response.OkWithMessage("删除成功", c)
return
}
_ = casbinService.FreshCasbin()
response.OkWithMessage("删除成功", c)
}
// @Tags Authority
// @Summary 更新角色信息
// @Security ApiKeyAuth
// @accept application/json
// @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]
// UpdateAuthority
// @Tags Authority
// @Summary 更新角色信息
// @Security ApiKeyAuth
// @accept application/json
// @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]
func (a *AuthorityApi) UpdateAuthority(c *gin.Context) {
var auth system.SysAuthority
_ = c.ShouldBindJSON(&auth)
if err := utils.Verify(auth, utils.AuthorityVerify); err != nil {
err := c.ShouldBindJSON(&auth)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if authority, err := authorityService.UpdateAuthority(auth); err != nil {
err = utils.Verify(auth, utils.AuthorityVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
authority, err := authorityService.UpdateAuthority(auth)
if err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败"+err.Error(), c)
} else {
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authority}, "更新成功", c)
return
}
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authority}, "更新成功", c)
}
// @Tags Authority
// @Summary 分页获取角色列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取角色列表,返回包括列表,总数,页码,每页数量"
// @Router /authority/getAuthorityList [post]
// GetAuthorityList
// @Tags Authority
// @Summary 分页获取角色列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @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
_ = c.ShouldBindJSON(&pageInfo)
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if list, total, err := authorityService.GetAuthorityInfoList(pageInfo); err != nil {
err = utils.Verify(pageInfo, utils.PageInfoVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := authorityService.GetAuthorityInfoList(pageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败"+err.Error(), c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
// @Tags Authority
// @Summary 设置角色资源权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAuthority true "设置角色资源权限"
// @Success 200 {object} response.Response{msg=string} "设置角色资源权限"
// @Router /authority/setDataAuthority [post]
// SetDataAuthority
// @Tags Authority
// @Summary 设置角色资源权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAuthority true "设置角色资源权限"
// @Success 200 {object} response.Response{msg=string} "设置角色资源权限"
// @Router /authority/setDataAuthority [post]
func (a *AuthorityApi) SetDataAuthority(c *gin.Context) {
var auth system.SysAuthority
_ = c.ShouldBindJSON(&auth)
if err := utils.Verify(auth, utils.AuthorityIdVerify); err != nil {
err := c.ShouldBindJSON(&auth)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := authorityService.SetDataAuthority(auth); err != nil {
err = utils.Verify(auth, utils.AuthorityIdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = authorityService.SetDataAuthority(auth)
if err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败"+err.Error(), c)
} else {
response.OkWithMessage("设置成功", c)
return
}
response.OkWithMessage("设置成功", c)
}
+48 -34
View File
@@ -10,57 +10,71 @@ import (
type AuthorityBtnApi struct{}
// @Tags AuthorityBtn
// @Summary 获取权限按钮
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SysAuthorityBtnReq true "菜单id, 角色id, 选中的按钮id"
// @Success 200 {object} response.Response{data=response.SysAuthorityBtnRes,msg=string} "返回列表成功"
// @Router /authorityBtn/getAuthorityBtn [post]
// GetAuthorityBtn
// @Tags AuthorityBtn
// @Summary 获取权限按钮
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SysAuthorityBtnReq true "菜单id, 角色id, 选中的按钮id"
// @Success 200 {object} response.Response{data=response.SysAuthorityBtnRes,msg=string} "返回列表成功"
// @Router /authorityBtn/getAuthorityBtn [post]
func (a *AuthorityBtnApi) GetAuthorityBtn(c *gin.Context) {
var req request.SysAuthorityBtnReq
_ = c.ShouldBindJSON(&req)
if res, err := authorityBtnService.GetAuthorityBtn(req); err != nil {
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
res, err := authorityBtnService.GetAuthorityBtn(req)
if err != nil {
global.GVA_LOG.Error("查询失败!", zap.Error(err))
response.FailWithMessage("查询失败", c)
} else {
response.OkWithDetailed(res, "查询成功", c)
return
}
response.OkWithDetailed(res, "查询成功", c)
}
// @Tags AuthorityBtn
// @Summary 设置权限按钮
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SysAuthorityBtnReq true "菜单id, 角色id, 选中的按钮id"
// @Success 200 {object} response.Response{msg=string} "返回列表成功"
// @Router /authorityBtn/setAuthorityBtn [post]
// SetAuthorityBtn
// @Tags AuthorityBtn
// @Summary 设置权限按钮
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SysAuthorityBtnReq true "菜单id, 角色id, 选中的按钮id"
// @Success 200 {object} response.Response{msg=string} "返回列表成功"
// @Router /authorityBtn/setAuthorityBtn [post]
func (a *AuthorityBtnApi) SetAuthorityBtn(c *gin.Context) {
var req request.SysAuthorityBtnReq
_ = c.ShouldBindJSON(&req)
if err := authorityBtnService.SetAuthorityBtn(req); err != nil {
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = authorityBtnService.SetAuthorityBtn(req)
if err != nil {
global.GVA_LOG.Error("分配失败!", zap.Error(err))
response.FailWithMessage("分配失败", c)
} else {
response.OkWithMessage("分配成功", c)
return
}
response.OkWithMessage("分配成功", c)
}
// @Tags AuthorityBtn
// @Summary 设置权限按钮
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "删除成功"
// @Router /authorityBtn/canRemoveAuthorityBtn [post]
// CanRemoveAuthorityBtn
// @Tags AuthorityBtn
// @Summary 设置权限按钮
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "删除成功"
// @Router /authorityBtn/canRemoveAuthorityBtn [post]
func (a *AuthorityBtnApi) CanRemoveAuthorityBtn(c *gin.Context) {
id := c.Query("id")
if err := authorityBtnService.CanRemoveAuthorityBtn(id); err != nil {
err := authorityBtnService.CanRemoveAuthorityBtn(id)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage(err.Error(), c)
} else {
response.OkWithMessage("删除成功", c)
return
}
response.OkWithMessage("删除成功", c)
}
+97 -222
View File
@@ -1,130 +1,70 @@
package system
import (
"errors"
"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"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"net/url"
"os"
"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/utils/request"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AutoCodeApi struct{}
var caser = cases.Title(language.English)
// 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 = caser.String(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 = caser.String(a.Package)
err := autoCodeService.CreateTemp(a, apiIds...)
if err != nil {
if errors.Is(err, system.AutoMoveErr) {
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 获取当前所有数据库
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前所有数据库"
// @Router /autoCode/getDatabase [get]
// @Tags AutoCode
// @Summary 获取当前所有数据库
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前所有数据库"
// @Router /autoCode/getDatabase [get]
func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
dbs, err := autoCodeService.Database().GetDB()
businessDB := c.Query("businessDB")
dbs, err := autoCodeService.Database(businessDB).GetDB(businessDB)
var dbList []map[string]interface{}
for _, db := range global.GVA_CONFIG.DBList {
var item = make(map[string]interface{})
item["aliasName"] = db.AliasName
item["dbName"] = db.Dbname
item["disable"] = db.Disable
item["dbtype"] = db.Type
dbList = append(dbList, item)
}
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"dbs": dbs}, "获取成功", c)
response.OkWithDetailed(gin.H{"dbs": dbs, "dbList": dbList}, "获取成功", c)
}
}
// GetTables
// @Tags AutoCode
// @Summary 获取当前数据库所有表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前数据库所有表"
// @Router /autoCode/getTables [get]
// @Tags AutoCode
// @Summary 获取当前数据库所有表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @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)
tables, err := autoCodeService.Database().GetTables(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))
response.FailWithMessage("查询table失败", c)
@@ -134,17 +74,28 @@ func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
}
// GetColumn
// @Tags AutoCode
// @Summary 获取当前表所有字段
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前表所有字段"
// @Router /autoCode/getColumn [get]
// @Tags AutoCode
// @Summary 获取当前表所有字段
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前表所有字段"
// @Router /autoCode/getColumn [get]
func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) {
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
businessDB := c.Query("businessDB")
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().GetColumn(tableName, dbName)
columns, err := autoCodeService.Database(businessDB).GetColumn(businessDB, tableName, dbName)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
@@ -153,120 +104,44 @@ 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)
func (autoApi *AutoCodeApi) LLMAuto(c *gin.Context) {
prompt := c.Query("prompt")
mode := c.Query("mode")
params := make(map[string]string)
params["prompt"] = prompt
params["mode"] = mode
path := strings.ReplaceAll(global.GVA_CONFIG.AutoCode.AiPath, "{FUNC}", "api/chat/ai")
res, err := request.HttpRequest(
path,
"POST",
nil,
params,
nil,
)
if err != nil {
global.GVA_LOG.Error("大模型生成失败!", zap.Error(err))
response.FailWithMessage("大模型生成失败"+err.Error(), c)
return
}
err := autoCodeService.CreateAutoCode(&a)
var resStruct response.Response
b, err := io.ReadAll(res.Body)
defer res.Body.Close()
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
_ = c.ShouldBindJSON(&a)
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)
} else {
response.Ok(c)
}
}
func (autoApi *AutoCodeApi) InstallPlugin(c *gin.Context) {
header, err := c.FormFile("plug")
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端插件未成功安装,请按照文档自行解压安装,如果为纯前端插件请忽略此条提示"
}
err = json.Unmarshal(b, &resStruct)
if err != nil {
response.FailWithMessage(err.Error(), c)
global.GVA_LOG.Error("大模型生成失败!", zap.Error(err))
response.FailWithMessage("大模型生成失败"+err.Error(), c)
return
} else {
response.OkWithData([]interface{}{
gin.H{
"code": web,
"msg": webStr,
},
gin.H{
"code": server,
"msg": serverStr,
}}, c)
}
if resStruct.Code == 7 {
global.GVA_LOG.Error("大模型生成失败!"+resStruct.Msg, zap.Error(err))
response.FailWithMessage("大模型生成失败"+resStruct.Msg, c)
return
}
response.OkWithData(resStruct.Data, c)
}
@@ -1,98 +0,0 @@
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"
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AutoCodeHistoryApi struct{}
// First
// @Tags AutoCode
// @Summary 获取meta信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "请求参数"
// @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
_ = c.ShouldBindJSON(&info)
data, err := autoCodeHistoryService.First(&info)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
response.OkWithDetailed(gin.H{"meta": data}, "获取成功", c)
}
// Delete
// @Tags AutoCode
// @Summary 删除回滚记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "请求参数"
// @Success 200 {object} response.Response{msg=string} "删除回滚记录"
// @Router /autoCode/delSysHistory [post]
func (a *AutoCodeHistoryApi) Delete(c *gin.Context) {
var info request.GetById
_ = c.ShouldBindJSON(&info)
err := autoCodeHistoryService.Delete(&info)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
// RollBack
// @Tags AutoCode
// @Summary 回滚自动生成代码
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.RollBack true "请求参数"
// @Success 200 {object} response.Response{msg=string} "回滚自动生成代码"
// @Router /autoCode/rollback [post]
func (a *AutoCodeHistoryApi) RollBack(c *gin.Context) {
var info systemReq.RollBack
_ = c.ShouldBindJSON(&info)
if err := autoCodeHistoryService.RollBack(&info); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
response.OkWithMessage("回滚成功", c)
}
// GetList
// @Tags AutoCode
// @Summary 查询回滚记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SysAutoHistory 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
_ = c.ShouldBindJSON(&search)
list, total, err := autoCodeHistoryService.GetList(search.PageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: search.Page,
PageSize: search.PageSize,
}, "获取成功", c)
}
+42 -14
View File
@@ -1,6 +1,8 @@
package system
import (
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
@@ -16,27 +18,53 @@ var store = base64Captcha.DefaultMemStore
type BaseApi struct{}
// Captcha
// @Tags Base
// @Summary 生成验证码
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=systemRes.SysCaptchaResponse,msg=string} "生成验证码,返回包括随机数id,base64,验证码长度"
// @Router /base/captcha [post]
// @Tags Base
// @Summary 生成验证码
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=systemRes.SysCaptchaResponse,msg=string} "生成验证码,返回包括随机数id,base64,验证码长度,是否开启验证码"
// @Router /base/captcha [post]
func (b *BaseApi) Captcha(c *gin.Context) {
// 判断验证码是否开启
openCaptcha := global.GVA_CONFIG.Captcha.OpenCaptcha // 是否开启防爆次数
openCaptchaTimeOut := global.GVA_CONFIG.Captcha.OpenCaptchaTimeOut // 缓存超时时间
key := c.ClientIP()
v, ok := global.BlackCache.Get(key)
if !ok {
global.BlackCache.Set(key, 1, time.Second*time.Duration(openCaptchaTimeOut))
}
var oc bool
if openCaptcha == 0 || openCaptcha < interfaceToInt(v) {
oc = true
}
// 字符,公式,验证码配置
// 生成默认数字的driver
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)
if id, b64s, err := cp.Generate(); err != nil {
id, b64s, _, err := cp.Generate()
if err != nil {
global.GVA_LOG.Error("验证码获取失败!", zap.Error(err))
response.FailWithMessage("验证码获取失败", c)
} else {
response.OkWithDetailed(systemRes.SysCaptchaResponse{
CaptchaId: id,
PicPath: b64s,
CaptchaLength: global.GVA_CONFIG.Captcha.KeyLong,
}, "验证码获取成功", c)
return
}
response.OkWithDetailed(systemRes.SysCaptchaResponse{
CaptchaId: id,
PicPath: b64s,
CaptchaLength: global.GVA_CONFIG.Captcha.KeyLong,
OpenCaptcha: oc,
}, "验证码获取成功", c)
}
// 类型转换
func interfaceToInt(v interface{}) (i int) {
switch v := v.(type) {
case int:
i = v
default:
i = 0
}
return
}
+36 -23
View File
@@ -12,41 +12,54 @@ import (
type CasbinApi struct{}
// @Tags Casbin
// @Summary 更新角色api权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CasbinInReceive true "权限id, 权限模型列表"
// @Success 200 {object} response.Response{msg=string} "更新角色api权限"
// @Router /casbin/UpdateCasbin [post]
// UpdateCasbin
// @Tags Casbin
// @Summary 更新角色api权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CasbinInReceive true "权限id, 权限模型列表"
// @Success 200 {object} response.Response{msg=string} "更新角色api权限"
// @Router /casbin/UpdateCasbin [post]
func (cas *CasbinApi) UpdateCasbin(c *gin.Context) {
var cmr request.CasbinInReceive
_ = c.ShouldBindJSON(&cmr)
if err := utils.Verify(cmr, utils.AuthorityIdVerify); err != nil {
err := c.ShouldBindJSON(&cmr)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := casbinService.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos); err != nil {
err = utils.Verify(cmr, utils.AuthorityIdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = casbinService.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos)
if err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
} else {
response.OkWithMessage("更新成功", c)
return
}
response.OkWithMessage("更新成功", c)
}
// @Tags Casbin
// @Summary 获取权限列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CasbinInReceive true "权限id, 权限模型列表"
// @Success 200 {object} response.Response{data=systemRes.PolicyPathResponse,msg=string} "获取权限列表,返回包括casbin详情列表"
// @Router /casbin/getPolicyPathByAuthorityId [post]
// GetPolicyPathByAuthorityId
// @Tags Casbin
// @Summary 获取权限列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CasbinInReceive true "权限id, 权限模型列表"
// @Success 200 {object} response.Response{data=systemRes.PolicyPathResponse,msg=string} "获取权限列表,返回包括casbin详情列表"
// @Router /casbin/getPolicyPathByAuthorityId [post]
func (cas *CasbinApi) GetPolicyPathByAuthorityId(c *gin.Context) {
var casbin request.CasbinInReceive
_ = c.ShouldBindJSON(&casbin)
if err := utils.Verify(casbin, utils.AuthorityIdVerify); err != nil {
err := c.ShouldBindJSON(&casbin)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(casbin, utils.AuthorityIdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
+108 -96
View File
@@ -4,114 +4,126 @@ 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"
"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 DictionaryApi struct{}
// @Tags SysDictionary
// @Summary 创建SysDictionary
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {object} response.Response{msg=string} "创建SysDictionary"
// @Router /sysDictionary/createSysDictionary [post]
// CreateSysDictionary
// @Tags SysDictionary
// @Summary 创建SysDictionary
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {object} response.Response{msg=string} "创建SysDictionary"
// @Router /sysDictionary/createSysDictionary [post]
func (s *DictionaryApi) CreateSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
_ = c.ShouldBindJSON(&dictionary)
if err := dictionaryService.CreateSysDictionary(dictionary); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// @Tags SysDictionary
// @Summary 删除SysDictionary
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {object} response.Response{msg=string} "删除SysDictionary"
// @Router /sysDictionary/deleteSysDictionary [delete]
func (s *DictionaryApi) DeleteSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
_ = c.ShouldBindJSON(&dictionary)
if err := dictionaryService.DeleteSysDictionary(dictionary); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
}
}
// @Tags SysDictionary
// @Summary 更新SysDictionary
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {object} response.Response{msg=string} "更新SysDictionary"
// @Router /sysDictionary/updateSysDictionary [put]
func (s *DictionaryApi) UpdateSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
_ = c.ShouldBindJSON(&dictionary)
if err := dictionaryService.UpdateSysDictionary(&dictionary); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
} else {
response.OkWithMessage("更新成功", c)
}
}
// @Tags SysDictionary
// @Summary 用id查询SysDictionary
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query system.SysDictionary true "ID或字典英名"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysDictionary"
// @Router /sysDictionary/findSysDictionary [get]
func (s *DictionaryApi) FindSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
_ = c.ShouldBindQuery(&dictionary)
if sysDictionary, err := dictionaryService.GetSysDictionary(dictionary.Type, dictionary.ID, dictionary.Status); err != nil {
global.GVA_LOG.Error("字典未创建或未开启!", zap.Error(err))
response.FailWithMessage("字典未创建或未开启", c)
} else {
response.OkWithDetailed(gin.H{"resysDictionary": sysDictionary}, "查询成功", c)
}
}
// @Tags SysDictionary
// @Summary 分页获取SysDictionary列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query request.SysDictionarySearch true "页码, 每页大小, 搜索条件"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量"
// @Router /sysDictionary/getSysDictionaryList [get]
func (s *DictionaryApi) GetSysDictionaryList(c *gin.Context) {
var pageInfo request.SysDictionarySearch
_ = c.ShouldBindQuery(&pageInfo)
if err := utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify); err != nil {
err := c.ShouldBindJSON(&dictionary)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if list, total, err := dictionaryService.GetSysDictionaryInfoList(pageInfo); err != nil {
err = dictionaryService.CreateSysDictionary(dictionary)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
return
}
response.OkWithMessage("创建成功", c)
}
// DeleteSysDictionary
// @Tags SysDictionary
// @Summary 删除SysDictionary
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {object} response.Response{msg=string} "删除SysDictionary"
// @Router /sysDictionary/deleteSysDictionary [delete]
func (s *DictionaryApi) DeleteSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
err := c.ShouldBindJSON(&dictionary)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = dictionaryService.DeleteSysDictionary(dictionary)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
// UpdateSysDictionary
// @Tags SysDictionary
// @Summary 更新SysDictionary
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {object} response.Response{msg=string} "更新SysDictionary"
// @Router /sysDictionary/updateSysDictionary [put]
func (s *DictionaryApi) UpdateSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
err := c.ShouldBindJSON(&dictionary)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = dictionaryService.UpdateSysDictionary(&dictionary)
if err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
return
}
response.OkWithMessage("更新成功", c)
}
// FindSysDictionary
// @Tags SysDictionary
// @Summary 用id查询SysDictionary
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query system.SysDictionary true "ID或字典英名"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysDictionary"
// @Router /sysDictionary/findSysDictionary [get]
func (s *DictionaryApi) FindSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
err := c.ShouldBindQuery(&dictionary)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
sysDictionary, err := dictionaryService.GetSysDictionary(dictionary.Type, dictionary.ID, dictionary.Status)
if err != nil {
global.GVA_LOG.Error("字典未创建或未开启!", zap.Error(err))
response.FailWithMessage("字典未创建或未开启", c)
return
}
response.OkWithDetailed(gin.H{"resysDictionary": sysDictionary}, "查询成功", c)
}
// GetSysDictionaryList
// @Tags SysDictionary
// @Summary 分页获取SysDictionary列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量"
// @Router /sysDictionary/getSysDictionaryList [get]
func (s *DictionaryApi) GetSysDictionaryList(c *gin.Context) {
list, err := dictionaryService.GetSysDictionaryInfoList()
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithDetailed(list, "获取成功", c)
}
+120 -89
View File
@@ -12,106 +12,137 @@ import (
type DictionaryDetailApi struct{}
// @Tags SysDictionaryDetail
// @Summary 创建SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionaryDetail true "SysDictionaryDetail模型"
// @Success 200 {object} response.Response{msg=string} "创建SysDictionaryDetail"
// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
// CreateSysDictionaryDetail
// @Tags SysDictionaryDetail
// @Summary 创建SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionaryDetail true "SysDictionaryDetail模型"
// @Success 200 {object} response.Response{msg=string} "创建SysDictionaryDetail"
// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
func (s *DictionaryDetailApi) CreateSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
_ = c.ShouldBindJSON(&detail)
if err := dictionaryDetailService.CreateSysDictionaryDetail(detail); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// @Tags SysDictionaryDetail
// @Summary 删除SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionaryDetail true "SysDictionaryDetail模型"
// @Success 200 {object} response.Response{msg=string} "删除SysDictionaryDetail"
// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
func (s *DictionaryDetailApi) DeleteSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
_ = c.ShouldBindJSON(&detail)
if err := dictionaryDetailService.DeleteSysDictionaryDetail(detail); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
}
}
// @Tags SysDictionaryDetail
// @Summary 更新SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionaryDetail true "更新SysDictionaryDetail"
// @Success 200 {object} response.Response{msg=string} "更新SysDictionaryDetail"
// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
func (s *DictionaryDetailApi) UpdateSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
_ = c.ShouldBindJSON(&detail)
if err := dictionaryDetailService.UpdateSysDictionaryDetail(&detail); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
} else {
response.OkWithMessage("更新成功", c)
}
}
// @Tags SysDictionaryDetail
// @Summary 用id查询SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query system.SysDictionaryDetail true "用id查询SysDictionaryDetail"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysDictionaryDetail"
// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
func (s *DictionaryDetailApi) FindSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
_ = c.ShouldBindQuery(&detail)
if err := utils.Verify(detail, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&detail)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if reSysDictionaryDetail, err := dictionaryDetailService.GetSysDictionaryDetail(detail.ID); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Error(err))
response.FailWithMessage("查询失败", c)
} else {
response.OkWithDetailed(gin.H{"reSysDictionaryDetail": reSysDictionaryDetail}, "查询成功", c)
err = dictionaryDetailService.CreateSysDictionaryDetail(detail)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
return
}
response.OkWithMessage("创建成功", c)
}
// @Tags SysDictionaryDetail
// @Summary 分页获取SysDictionaryDetail列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query request.SysDictionaryDetailSearch true "页码, 每页大小, 搜索条件"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysDictionaryDetail列表,返回包括列表,总数,页码,每页数量"
// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
// DeleteSysDictionaryDetail
// @Tags SysDictionaryDetail
// @Summary 删除SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionaryDetail true "SysDictionaryDetail模型"
// @Success 200 {object} response.Response{msg=string} "删除SysDictionaryDetail"
// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
func (s *DictionaryDetailApi) DeleteSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
err := c.ShouldBindJSON(&detail)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = dictionaryDetailService.DeleteSysDictionaryDetail(detail)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
// UpdateSysDictionaryDetail
// @Tags SysDictionaryDetail
// @Summary 更新SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysDictionaryDetail true "更新SysDictionaryDetail"
// @Success 200 {object} response.Response{msg=string} "更新SysDictionaryDetail"
// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
func (s *DictionaryDetailApi) UpdateSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
err := c.ShouldBindJSON(&detail)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = dictionaryDetailService.UpdateSysDictionaryDetail(&detail)
if err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
return
}
response.OkWithMessage("更新成功", c)
}
// FindSysDictionaryDetail
// @Tags SysDictionaryDetail
// @Summary 用id查询SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query system.SysDictionaryDetail true "用id查询SysDictionaryDetail"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysDictionaryDetail"
// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
func (s *DictionaryDetailApi) FindSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
err := c.ShouldBindQuery(&detail)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(detail, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
reSysDictionaryDetail, err := dictionaryDetailService.GetSysDictionaryDetail(detail.ID)
if err != nil {
global.GVA_LOG.Error("查询失败!", zap.Error(err))
response.FailWithMessage("查询失败", c)
return
}
response.OkWithDetailed(gin.H{"reSysDictionaryDetail": reSysDictionaryDetail}, "查询成功", c)
}
// GetSysDictionaryDetailList
// @Tags SysDictionaryDetail
// @Summary 分页获取SysDictionaryDetail列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query request.SysDictionaryDetailSearch true "页码, 每页大小, 搜索条件"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysDictionaryDetail列表,返回包括列表,总数,页码,每页数量"
// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
func (s *DictionaryDetailApi) GetSysDictionaryDetailList(c *gin.Context) {
var pageInfo request.SysDictionaryDetailSearch
_ = c.ShouldBindQuery(&pageInfo)
if list, total, err := dictionaryDetailService.GetSysDictionaryDetailInfoList(pageInfo); err != nil {
err := c.ShouldBindQuery(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := dictionaryDetailService.GetSysDictionaryDetailInfoList(pageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
+258
View File
@@ -0,0 +1,258 @@
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"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/flipped-aurora/gin-vue-admin/server/service"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type SysExportTemplateApi struct {
}
var sysExportTemplateService = service.ServiceGroupApp.SystemServiceGroup.SysExportTemplateService
// CreateSysExportTemplate 创建导出模板
// @Tags SysExportTemplate
// @Summary 创建导出模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysExportTemplate true "创建导出模板"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /sysExportTemplate/createSysExportTemplate [post]
func (sysExportTemplateApi *SysExportTemplateApi) CreateSysExportTemplate(c *gin.Context) {
var sysExportTemplate system.SysExportTemplate
err := c.ShouldBindJSON(&sysExportTemplate)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
verify := utils.Rules{
"Name": {utils.NotEmpty()},
}
if err := utils.Verify(sysExportTemplate, verify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := sysExportTemplateService.CreateSysExportTemplate(&sysExportTemplate); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// DeleteSysExportTemplate 删除导出模板
// @Tags SysExportTemplate
// @Summary 删除导出模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysExportTemplate true "删除导出模板"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysExportTemplate/deleteSysExportTemplate [delete]
func (sysExportTemplateApi *SysExportTemplateApi) DeleteSysExportTemplate(c *gin.Context) {
var sysExportTemplate system.SysExportTemplate
err := c.ShouldBindJSON(&sysExportTemplate)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := sysExportTemplateService.DeleteSysExportTemplate(sysExportTemplate); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
}
}
// DeleteSysExportTemplateByIds 批量删除导出模板
// @Tags SysExportTemplate
// @Summary 批量删除导出模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除导出模板"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /sysExportTemplate/deleteSysExportTemplateByIds [delete]
func (sysExportTemplateApi *SysExportTemplateApi) DeleteSysExportTemplateByIds(c *gin.Context) {
var IDS request.IdsReq
err := c.ShouldBindJSON(&IDS)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := sysExportTemplateService.DeleteSysExportTemplateByIds(IDS); err != nil {
global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
response.FailWithMessage("批量删除失败", c)
} else {
response.OkWithMessage("批量删除成功", c)
}
}
// UpdateSysExportTemplate 更新导出模板
// @Tags SysExportTemplate
// @Summary 更新导出模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysExportTemplate true "更新导出模板"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /sysExportTemplate/updateSysExportTemplate [put]
func (sysExportTemplateApi *SysExportTemplateApi) UpdateSysExportTemplate(c *gin.Context) {
var sysExportTemplate system.SysExportTemplate
err := c.ShouldBindJSON(&sysExportTemplate)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
verify := utils.Rules{
"Name": {utils.NotEmpty()},
}
if err := utils.Verify(sysExportTemplate, verify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := sysExportTemplateService.UpdateSysExportTemplate(sysExportTemplate); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
} else {
response.OkWithMessage("更新成功", c)
}
}
// FindSysExportTemplate 用id查询导出模板
// @Tags SysExportTemplate
// @Summary 用id查询导出模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query system.SysExportTemplate true "用id查询导出模板"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /sysExportTemplate/findSysExportTemplate [get]
func (sysExportTemplateApi *SysExportTemplateApi) FindSysExportTemplate(c *gin.Context) {
var sysExportTemplate system.SysExportTemplate
err := c.ShouldBindQuery(&sysExportTemplate)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if resysExportTemplate, err := sysExportTemplateService.GetSysExportTemplate(sysExportTemplate.ID); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Error(err))
response.FailWithMessage("查询失败", c)
} else {
response.OkWithData(gin.H{"resysExportTemplate": resysExportTemplate}, c)
}
}
// GetSysExportTemplateList 分页获取导出模板列表
// @Tags SysExportTemplate
// @Summary 分页获取导出模板列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query systemReq.SysExportTemplateSearch true "分页获取导出模板列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysExportTemplate/getSysExportTemplateList [get]
func (sysExportTemplateApi *SysExportTemplateApi) GetSysExportTemplateList(c *gin.Context) {
var pageInfo systemReq.SysExportTemplateSearch
err := c.ShouldBindQuery(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if list, total, err := sysExportTemplateService.GetSysExportTemplateInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
}
// ExportExcel 导出表格
// @Tags SysExportTemplate
// @Summary 导出表格
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @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, queryParams); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+utils.RandomString(6)+".xlsx")) // 对下载的文件重命名
c.Header("success", "true")
c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file.Bytes())
}
}
// ExportTemplate 导出表格模板
// @Tags SysExportTemplate
// @Summary 导出表格模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Router /sysExportTemplate/exportExcel [get]
func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplate(c *gin.Context) {
templateID := c.Query("templateID")
if templateID == "" {
response.FailWithMessage("模板ID不能为空", c)
return
}
if file, name, err := sysExportTemplateService.ExportTemplate(templateID); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", name+"模板.xlsx")) // 对下载的文件重命名
c.Header("success", "true")
c.Data(http.StatusOK, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file.Bytes())
}
}
// ImportExcel 导入表格
// @Tags SysImportTemplate
// @Summary 导入表格
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Router /sysExportTemplate/importExcel [post]
func (sysExportTemplateApi *SysExportTemplateApi) ImportExcel(c *gin.Context) {
templateID := c.Query("templateID")
if templateID == "" {
response.FailWithMessage("模板ID不能为空", c)
return
}
file, err := c.FormFile("file")
if err != nil {
global.GVA_LOG.Error("文件获取失败!", zap.Error(err))
response.FailWithMessage("文件获取失败", c)
return
}
if err := sysExportTemplateService.ImportExcel(templateID, file); err != nil {
global.GVA_LOG.Error(err.Error(), zap.Error(err))
response.FailWithMessage(err.Error(), c)
} else {
response.OkWithMessage("导入成功", c)
}
}
+9 -10
View File
@@ -12,12 +12,12 @@ import (
type DBApi struct{}
// InitDB
// @Tags InitDB
// @Summary 初始化用户数据库
// @Tags InitDB
// @Summary 初始化用户数据库
// @Produce application/json
// @Param data body request.InitDB true "初始化数据库参数"
// @Success 200 {object} response.Response{data=string} "初始化用户数据库"
// @Router /init/initdb [post]
// @Param data body request.InitDB true "初始化数据库参数"
// @Success 200 {object} response.Response{data=string} "初始化用户数据库"
// @Router /init/initdb [post]
func (i *DBApi) InitDB(c *gin.Context) {
if global.GVA_DB != nil {
global.GVA_LOG.Error("已存在数据库配置!")
@@ -39,11 +39,11 @@ func (i *DBApi) InitDB(c *gin.Context) {
}
// CheckDB
// @Tags CheckDB
// @Summary 初始化用户数据库
// @Tags CheckDB
// @Summary 初始化用户数据库
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "初始化用户数据库"
// @Router /init/checkdb [post]
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "初始化用户数据库"
// @Router /init/checkdb [post]
func (i *DBApi) CheckDB(c *gin.Context) {
var (
message = "前往初始化数据库"
@@ -56,5 +56,4 @@ func (i *DBApi) CheckDB(c *gin.Context) {
}
global.GVA_LOG.Info(message)
response.OkWithDetailed(gin.H{"needInit": needInit}, message, c)
return
}
+15 -11
View File
@@ -4,26 +4,30 @@ 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"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type JwtApi struct{}
// @Tags Jwt
// @Summary jwt加入黑名单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "jwt加入黑名单"
// @Router /jwt/jsonInBlacklist [post]
// JsonInBlacklist
// @Tags Jwt
// @Summary jwt加入黑名单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "jwt加入黑名单"
// @Router /jwt/jsonInBlacklist [post]
func (j *JwtApi) JsonInBlacklist(c *gin.Context) {
token := c.Request.Header.Get("x-token")
token := utils.GetToken(c)
jwt := system.JwtBlacklist{Jwt: token}
if err := jwtService.JsonInBlacklist(jwt); err != nil {
err := jwtService.JsonInBlacklist(jwt)
if err != nil {
global.GVA_LOG.Error("jwt作废失败!", zap.Error(err))
response.FailWithMessage("jwt作废失败", c)
} else {
response.OkWithMessage("jwt作废成功", c)
return
}
utils.ClearToken(c)
response.OkWithMessage("jwt作废成功", c)
}
+170 -118
View File
@@ -15,52 +15,61 @@ import (
type AuthorityMenuApi struct{}
// @Tags AuthorityMenu
// @Summary 获取用户动态路由
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body request.Empty true "空"
// @Success 200 {object} response.Response{data=systemRes.SysMenusResponse,msg=string} "获取用户动态路由,返回包括系统菜单详情列表"
// @Router /menu/getMenu [post]
// GetMenu
// @Tags AuthorityMenu
// @Summary 获取用户动态路由
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body request.Empty true "空"
// @Success 200 {object} response.Response{data=systemRes.SysMenusResponse,msg=string} "获取用户动态路由,返回包括系统菜单详情列表"
// @Router /menu/getMenu [post]
func (a *AuthorityMenuApi) GetMenu(c *gin.Context) {
if menus, err := menuService.GetMenuTree(utils.GetUserAuthorityId(c)); err != nil {
menus, err := menuService.GetMenuTree(utils.GetUserAuthorityId(c))
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
if menus == nil {
menus = []system.SysMenu{}
}
response.OkWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取成功", c)
return
}
if menus == nil {
menus = []system.SysMenu{}
}
response.OkWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取成功", c)
}
// @Tags AuthorityMenu
// @Summary 获取用户动态路由
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body request.Empty true "空"
// @Success 200 {object} response.Response{data=systemRes.SysBaseMenusResponse,msg=string} "获取用户动态路由,返回包括系统菜单列表"
// @Router /menu/getBaseMenuTree [post]
// GetBaseMenuTree
// @Tags AuthorityMenu
// @Summary 获取用户动态路由
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body request.Empty true "空"
// @Success 200 {object} response.Response{data=systemRes.SysBaseMenusResponse,msg=string} "获取用户动态路由,返回包括系统菜单列表"
// @Router /menu/getBaseMenuTree [post]
func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) {
if menus, err := menuService.GetBaseMenuTree(); err != nil {
menus, err := menuService.GetBaseMenuTree()
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(systemRes.SysBaseMenusResponse{Menus: menus}, "获取成功", c)
return
}
response.OkWithDetailed(systemRes.SysBaseMenusResponse{Menus: menus}, "获取成功", c)
}
// @Tags AuthorityMenu
// @Summary 增加menu和角色关联关系
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.AddMenuAuthorityInfo true "角色ID"
// @Success 200 {object} response.Response{msg=string} "增加menu和角色关联关系"
// @Router /menu/addMenuAuthority [post]
// AddMenuAuthority
// @Tags AuthorityMenu
// @Summary 增加menu和角色关联关系
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.AddMenuAuthorityInfo true "角色ID"
// @Success 200 {object} response.Response{msg=string} "增加menu和角色关联关系"
// @Router /menu/addMenuAuthority [post]
func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) {
var authorityMenu systemReq.AddMenuAuthorityInfo
_ = c.ShouldBindJSON(&authorityMenu)
err := c.ShouldBindJSON(&authorityMenu)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := utils.Verify(authorityMenu, utils.AuthorityIdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
@@ -73,154 +82,197 @@ func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) {
}
}
// @Tags AuthorityMenu
// @Summary 获取指定角色menu
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetAuthorityId true "角色ID"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取指定角色menu"
// @Router /menu/getMenuAuthority [post]
// GetMenuAuthority
// @Tags AuthorityMenu
// @Summary 获取指定角色menu
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetAuthorityId true "角色ID"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取指定角色menu"
// @Router /menu/getMenuAuthority [post]
func (a *AuthorityMenuApi) GetMenuAuthority(c *gin.Context) {
var param request.GetAuthorityId
_ = c.ShouldBindJSON(&param)
if err := utils.Verify(param, utils.AuthorityIdVerify); err != nil {
err := c.ShouldBindJSON(&param)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if menus, err := menuService.GetMenuAuthority(&param); err != nil {
err = utils.Verify(param, utils.AuthorityIdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
menus, err := menuService.GetMenuAuthority(&param)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取失败", c)
} else {
response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c)
return
}
response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c)
}
// @Tags Menu
// @Summary 新增菜单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Success 200 {object} response.Response{msg=string} "新增菜单"
// @Router /menu/addBaseMenu [post]
// AddBaseMenu
// @Tags Menu
// @Summary 新增菜单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Success 200 {object} response.Response{msg=string} "新增菜单"
// @Router /menu/addBaseMenu [post]
func (a *AuthorityMenuApi) AddBaseMenu(c *gin.Context) {
var menu system.SysBaseMenu
_ = c.ShouldBindJSON(&menu)
if err := utils.Verify(menu, utils.MenuVerify); err != nil {
err := c.ShouldBindJSON(&menu)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := utils.Verify(menu.Meta, utils.MenuMetaVerify); err != nil {
err = utils.Verify(menu, utils.MenuVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := menuService.AddBaseMenu(menu); err != nil {
err = utils.Verify(menu.Meta, utils.MenuMetaVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = menuService.AddBaseMenu(menu)
if err != nil {
global.GVA_LOG.Error("添加失败!", zap.Error(err))
response.FailWithMessage("添加失败", c)
} else {
response.OkWithMessage("添加成功", c)
return
}
response.OkWithMessage("添加成功", c)
}
// @Tags Menu
// @Summary 删除菜单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "菜单id"
// @Success 200 {object} response.Response{msg=string} "删除菜单"
// @Router /menu/deleteBaseMenu [post]
// DeleteBaseMenu
// @Tags Menu
// @Summary 删除菜单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "菜单id"
// @Success 200 {object} response.Response{msg=string} "删除菜单"
// @Router /menu/deleteBaseMenu [post]
func (a *AuthorityMenuApi) DeleteBaseMenu(c *gin.Context) {
var menu request.GetById
_ = c.ShouldBindJSON(&menu)
if err := utils.Verify(menu, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&menu)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := baseMenuService.DeleteBaseMenu(menu.ID); err != nil {
err = utils.Verify(menu, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = baseMenuService.DeleteBaseMenu(menu.ID)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
return
}
response.OkWithMessage("删除成功", c)
}
// @Tags Menu
// @Summary 更新菜单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Success 200 {object} response.Response{msg=string} "更新菜单"
// @Router /menu/updateBaseMenu [post]
// UpdateBaseMenu
// @Tags Menu
// @Summary 更新菜单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Success 200 {object} response.Response{msg=string} "更新菜单"
// @Router /menu/updateBaseMenu [post]
func (a *AuthorityMenuApi) UpdateBaseMenu(c *gin.Context) {
var menu system.SysBaseMenu
_ = c.ShouldBindJSON(&menu)
if err := utils.Verify(menu, utils.MenuVerify); err != nil {
err := c.ShouldBindJSON(&menu)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := utils.Verify(menu.Meta, utils.MenuMetaVerify); err != nil {
err = utils.Verify(menu, utils.MenuVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := baseMenuService.UpdateBaseMenu(menu); err != nil {
err = utils.Verify(menu.Meta, utils.MenuMetaVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = baseMenuService.UpdateBaseMenu(menu)
if err != nil {
global.GVA_LOG.Error("更新失败!", zap.Error(err))
response.FailWithMessage("更新失败", c)
} else {
response.OkWithMessage("更新成功", c)
return
}
response.OkWithMessage("更新成功", c)
}
// @Tags Menu
// @Summary 根据id获取菜单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "菜单id"
// @Success 200 {object} response.Response{data=systemRes.SysBaseMenuResponse,msg=string} "根据id获取菜单,返回包括系统菜单列表"
// @Router /menu/getBaseMenuById [post]
// GetBaseMenuById
// @Tags Menu
// @Summary 根据id获取菜单
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "菜单id"
// @Success 200 {object} response.Response{data=systemRes.SysBaseMenuResponse,msg=string} "根据id获取菜单,返回包括系统菜单列表"
// @Router /menu/getBaseMenuById [post]
func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) {
var idInfo request.GetById
_ = c.ShouldBindJSON(&idInfo)
if err := utils.Verify(idInfo, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&idInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if menu, err := baseMenuService.GetBaseMenuById(idInfo.ID); err != nil {
err = utils.Verify(idInfo, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
menu, err := baseMenuService.GetBaseMenuById(idInfo.ID)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(systemRes.SysBaseMenuResponse{Menu: menu}, "获取成功", c)
return
}
response.OkWithDetailed(systemRes.SysBaseMenuResponse{Menu: menu}, "获取成功", c)
}
// @Tags Menu
// @Summary 分页获取基础menu列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取基础menu列表,返回包括列表,总数,页码,每页数量"
// @Router /menu/getMenuList [post]
// GetMenuList
// @Tags Menu
// @Summary 分页获取基础menu列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @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
_ = c.ShouldBindJSON(&pageInfo)
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if menuList, total, err := menuService.GetInfoList(); err != nil {
err = utils.Verify(pageInfo, utils.PageInfoVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
menuList, total, err := menuService.GetInfoList()
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: menuList,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithDetailed(response.PageResult{
List: menuList,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
+120 -89
View File
@@ -13,106 +13,137 @@ import (
type OperationRecordApi struct{}
// @Tags SysOperationRecord
// @Summary 创建SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysOperationRecord true "创建SysOperationRecord"
// @Success 200 {object} response.Response{msg=string} "创建SysOperationRecord"
// @Router /sysOperationRecord/createSysOperationRecord [post]
// CreateSysOperationRecord
// @Tags SysOperationRecord
// @Summary 创建SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysOperationRecord true "创建SysOperationRecord"
// @Success 200 {object} response.Response{msg=string} "创建SysOperationRecord"
// @Router /sysOperationRecord/createSysOperationRecord [post]
func (s *OperationRecordApi) CreateSysOperationRecord(c *gin.Context) {
var sysOperationRecord system.SysOperationRecord
_ = c.ShouldBindJSON(&sysOperationRecord)
if err := operationRecordService.CreateSysOperationRecord(sysOperationRecord); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// @Tags SysOperationRecord
// @Summary 删除SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysOperationRecord true "SysOperationRecord模型"
// @Success 200 {object} response.Response{msg=string} "删除SysOperationRecord"
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
func (s *OperationRecordApi) DeleteSysOperationRecord(c *gin.Context) {
var sysOperationRecord system.SysOperationRecord
_ = c.ShouldBindJSON(&sysOperationRecord)
if err := operationRecordService.DeleteSysOperationRecord(sysOperationRecord); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
}
}
// @Tags SysOperationRecord
// @Summary 批量删除SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除SysOperationRecord"
// @Success 200 {object} response.Response{msg=string} "批量删除SysOperationRecord"
// @Router /sysOperationRecord/deleteSysOperationRecordByIds [delete]
func (s *OperationRecordApi) DeleteSysOperationRecordByIds(c *gin.Context) {
var IDS request.IdsReq
_ = c.ShouldBindJSON(&IDS)
if err := operationRecordService.DeleteSysOperationRecordByIds(IDS); err != nil {
global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
response.FailWithMessage("批量删除失败", c)
} else {
response.OkWithMessage("批量删除成功", c)
}
}
// @Tags SysOperationRecord
// @Summary 用id查询SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query system.SysOperationRecord true "Id"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysOperationRecord"
// @Router /sysOperationRecord/findSysOperationRecord [get]
func (s *OperationRecordApi) FindSysOperationRecord(c *gin.Context) {
var sysOperationRecord system.SysOperationRecord
_ = c.ShouldBindQuery(&sysOperationRecord)
if err := utils.Verify(sysOperationRecord, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&sysOperationRecord)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if reSysOperationRecord, err := operationRecordService.GetSysOperationRecord(sysOperationRecord.ID); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Error(err))
response.FailWithMessage("查询失败", c)
} else {
response.OkWithDetailed(gin.H{"reSysOperationRecord": reSysOperationRecord}, "查询成功", c)
err = operationRecordService.CreateSysOperationRecord(sysOperationRecord)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
return
}
response.OkWithMessage("创建成功", c)
}
// @Tags SysOperationRecord
// @Summary 分页获取SysOperationRecord列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query request.SysOperationRecordSearch true "页码, 每页大小, 搜索条件"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysOperationRecord列表,返回包括列表,总数,页码,每页数量"
// @Router /sysOperationRecord/getSysOperationRecordList [get]
// DeleteSysOperationRecord
// @Tags SysOperationRecord
// @Summary 删除SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysOperationRecord true "SysOperationRecord模型"
// @Success 200 {object} response.Response{msg=string} "删除SysOperationRecord"
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
func (s *OperationRecordApi) DeleteSysOperationRecord(c *gin.Context) {
var sysOperationRecord system.SysOperationRecord
err := c.ShouldBindJSON(&sysOperationRecord)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = operationRecordService.DeleteSysOperationRecord(sysOperationRecord)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
// DeleteSysOperationRecordByIds
// @Tags SysOperationRecord
// @Summary 批量删除SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除SysOperationRecord"
// @Success 200 {object} response.Response{msg=string} "批量删除SysOperationRecord"
// @Router /sysOperationRecord/deleteSysOperationRecordByIds [delete]
func (s *OperationRecordApi) DeleteSysOperationRecordByIds(c *gin.Context) {
var IDS request.IdsReq
err := c.ShouldBindJSON(&IDS)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = operationRecordService.DeleteSysOperationRecordByIds(IDS)
if err != nil {
global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
response.FailWithMessage("批量删除失败", c)
return
}
response.OkWithMessage("批量删除成功", c)
}
// FindSysOperationRecord
// @Tags SysOperationRecord
// @Summary 用id查询SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query system.SysOperationRecord true "Id"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "用id查询SysOperationRecord"
// @Router /sysOperationRecord/findSysOperationRecord [get]
func (s *OperationRecordApi) FindSysOperationRecord(c *gin.Context) {
var sysOperationRecord system.SysOperationRecord
err := c.ShouldBindQuery(&sysOperationRecord)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(sysOperationRecord, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
reSysOperationRecord, err := operationRecordService.GetSysOperationRecord(sysOperationRecord.ID)
if err != nil {
global.GVA_LOG.Error("查询失败!", zap.Error(err))
response.FailWithMessage("查询失败", c)
return
}
response.OkWithDetailed(gin.H{"reSysOperationRecord": reSysOperationRecord}, "查询成功", c)
}
// GetSysOperationRecordList
// @Tags SysOperationRecord
// @Summary 分页获取SysOperationRecord列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query request.SysOperationRecordSearch true "页码, 每页大小, 搜索条件"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取SysOperationRecord列表,返回包括列表,总数,页码,每页数量"
// @Router /sysOperationRecord/getSysOperationRecordList [get]
func (s *OperationRecordApi) GetSysOperationRecordList(c *gin.Context) {
var pageInfo systemReq.SysOperationRecordSearch
_ = c.ShouldBindQuery(&pageInfo)
if list, total, err := operationRecordService.GetSysOperationRecordInfoList(pageInfo); err != nil {
err := c.ShouldBindQuery(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := operationRecordService.GetSysOperationRecordInfoList(pageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
+48 -38
View File
@@ -6,73 +6,83 @@ 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"
)
type SystemApi struct{}
// @Tags System
// @Summary 获取配置文件内容
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {object} response.Response{data=systemRes.SysConfigResponse,msg=string} "获取配置文件内容,返回包括系统配置"
// @Router /system/getSystemConfig [post]
// GetSystemConfig
// @Tags System
// @Summary 获取配置文件内容
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {object} response.Response{data=systemRes.SysConfigResponse,msg=string} "获取配置文件内容,返回包括系统配置"
// @Router /system/getSystemConfig [post]
func (s *SystemApi) GetSystemConfig(c *gin.Context) {
if config, err := systemConfigService.GetSystemConfig(); err != nil {
config, err := systemConfigService.GetSystemConfig()
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(systemRes.SysConfigResponse{Config: config}, "获取成功", c)
return
}
response.OkWithDetailed(systemRes.SysConfigResponse{Config: config}, "获取成功", c)
}
// @Tags System
// @Summary 设置配置文件内容
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body system.System true "设置配置文件内容"
// @Success 200 {object} response.Response{data=string} "设置配置文件内容"
// @Router /system/setSystemConfig [post]
// SetSystemConfig
// @Tags System
// @Summary 设置配置文件内容
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body system.System true "设置配置文件内容"
// @Success 200 {object} response.Response{data=string} "设置配置文件内容"
// @Router /system/setSystemConfig [post]
func (s *SystemApi) SetSystemConfig(c *gin.Context) {
var sys system.System
_ = c.ShouldBindJSON(&sys)
if err := systemConfigService.SetSystemConfig(sys); err != nil {
err := c.ShouldBindJSON(&sys)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = systemConfigService.SetSystemConfig(sys)
if err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败", c)
} else {
response.OkWithMessage("设置成功", c)
return
}
response.OkWithMessage("设置成功", c)
}
// @Tags System
// @Summary 重启系统
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "重启系统"
// @Router /system/reloadSystem [post]
// ReloadSystem
// @Tags System
// @Summary 重启系统
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {object} response.Response{msg=string} "重启系统"
// @Router /system/reloadSystem [post]
func (s *SystemApi) ReloadSystem(c *gin.Context) {
err := utils.Reload()
if err != nil {
global.GVA_LOG.Error("重启系统失败!", zap.Error(err))
response.FailWithMessage("重启系统失败", c)
} else {
response.OkWithMessage("重启系统成功", c)
return
}
response.OkWithMessage("重启系统成功", c)
}
// @Tags System
// @Summary 获取服务器信息
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取服务器信息"
// @Router /system/getServerInfo [post]
// GetServerInfo
// @Tags System
// @Summary 获取服务器信息
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取服务器信息"
// @Router /system/getServerInfo [post]
func (s *SystemApi) GetServerInfo(c *gin.Context) {
if server, err := systemConfigService.GetServerInfo(); err != nil {
server, err := systemConfigService.GetServerInfo()
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"server": server}, "获取成功", c)
return
}
response.OkWithDetailed(gin.H{"server": server}, "获取成功", c)
}
+261 -180
View File
@@ -2,6 +2,7 @@ package system
import (
"strconv"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
@@ -12,62 +13,81 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
)
// @Tags Base
// @Summary 用户登录
// @Produce application/json
// @Param data body systemReq.Login true "用户名, 密码, 验证码"
// @Success 200 {object} response.Response{data=systemRes.LoginResponse,msg=string} "返回包括用户信息,token,过期时间"
// @Router /base/login [post]
// Login
// @Tags Base
// @Summary 用户登录
// @Produce application/json
// @Param data body systemReq.Login true "用户名, 密码, 验证码"
// @Success 200 {object} response.Response{data=systemRes.LoginResponse,msg=string} "返回包括用户信息,token,过期时间"
// @Router /base/login [post]
func (b *BaseApi) Login(c *gin.Context) {
var l systemReq.Login
_ = c.ShouldBindJSON(&l)
if err := utils.Verify(l, utils.LoginVerify); err != nil {
err := c.ShouldBindJSON(&l)
key := c.ClientIP()
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if store.Verify(l.CaptchaId, l.Captcha, true) {
u := &system.SysUser{Username: l.Username, Password: l.Password}
if user, err := userService.Login(u); err != nil {
global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Error(err))
response.FailWithMessage("用户名不存在或者密码错误", c)
} else {
if user.Enable != 1 {
global.GVA_LOG.Error("登陆失败! 用户被禁止登录!")
response.FailWithMessage("用户被禁止登录", c)
return
}
b.TokenNext(c, *user)
}
} else {
response.FailWithMessage("验证码错误", c)
err = utils.Verify(l, utils.LoginVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// 判断验证码是否开启
openCaptcha := global.GVA_CONFIG.Captcha.OpenCaptcha // 是否开启防爆次数
openCaptchaTimeOut := global.GVA_CONFIG.Captcha.OpenCaptchaTimeOut // 缓存超时时间
v, ok := global.BlackCache.Get(key)
if !ok {
global.BlackCache.Set(key, 1, time.Second*time.Duration(openCaptchaTimeOut))
}
var oc bool = openCaptcha == 0 || openCaptcha < interfaceToInt(v)
if !oc || (l.CaptchaId != "" && l.Captcha != "" && store.Verify(l.CaptchaId, l.Captcha, true)) {
u := &system.SysUser{Username: l.Username, Password: l.Password}
user, err := userService.Login(u)
if err != nil {
global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Error(err))
// 验证码次数+1
global.BlackCache.Increment(key, 1)
response.FailWithMessage("用户名不存在或者密码错误", c)
return
}
if user.Enable != 1 {
global.GVA_LOG.Error("登陆失败! 用户被禁止登录!")
// 验证码次数+1
global.BlackCache.Increment(key, 1)
response.FailWithMessage("用户被禁止登录", c)
return
}
b.TokenNext(c, *user)
return
}
// 验证码次数+1
global.BlackCache.Increment(key, 1)
response.FailWithMessage("验证码错误", c)
}
// 登录以后签发jwt
// 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)
return
}
if !global.GVA_CONFIG.System.UseMultipoint {
utils.SetToken(c, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
response.OkWithDetailed(systemRes.LoginResponse{
User: user,
Token: token,
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
}, "登录成功", c)
return
}
@@ -78,10 +98,11 @@ func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) {
response.FailWithMessage("设置登录状态失败", c)
return
}
utils.SetToken(c, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
response.OkWithDetailed(systemRes.LoginResponse{
User: user,
Token: token,
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
}, "登录成功", c)
} else if err != nil {
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
@@ -93,28 +114,35 @@ 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
}
utils.SetToken(c, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
response.OkWithDetailed(systemRes.LoginResponse{
User: user,
Token: token,
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
}, "登录成功", c)
}
}
// @Tags SysUser
// @Summary 用户注册账号
// @Produce application/json
// @Param data body systemReq.Register true "用户名, 昵称, 密码, 角色ID"
// @Success 200 {object} response.Response{data=systemRes.SysUserResponse,msg=string} "用户注册账号,返回包括用户信息"
// @Router /user/admin_register [post]
// Register
// @Tags SysUser
// @Summary 用户注册账号
// @Produce application/json
// @Param data body systemReq.Register true "用户名, 昵称, 密码, 角色ID"
// @Success 200 {object} response.Response{data=systemRes.SysUserResponse,msg=string} "用户注册账号,返回包括用户信息"
// @Router /user/admin_register [post]
func (b *BaseApi) Register(c *gin.Context) {
var r systemReq.Register
_ = c.ShouldBindJSON(&r)
if err := utils.Verify(r, utils.RegisterVerify); err != nil {
err := c.ShouldBindJSON(&r)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(r, utils.RegisterVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
@@ -124,134 +152,166 @@ func (b *BaseApi) Register(c *gin.Context) {
AuthorityId: v,
})
}
user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities, Enable: r.Enable}
user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities, Enable: r.Enable, Phone: r.Phone, Email: r.Email}
userReturn, err := userService.Register(*user)
if err != nil {
global.GVA_LOG.Error("注册失败!", zap.Error(err))
response.FailWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册失败", c)
} else {
response.OkWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册成功", c)
return
}
response.OkWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册成功", c)
}
// @Tags SysUser
// @Summary 用户修改密码
// @Security ApiKeyAuth
// ChangePassword
// @Tags SysUser
// @Summary 用户修改密码
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body systemReq.ChangePasswordReq true "用户名, 原密码, 新密码"
// @Success 200 {object} response.Response{msg=string} "用户修改密码"
// @Router /user/changePassword [post]
// @Param data body systemReq.ChangePasswordReq true "用户名, 原密码, 新密码"
// @Success 200 {object} response.Response{msg=string} "用户修改密码"
// @Router /user/changePassword [post]
func (b *BaseApi) ChangePassword(c *gin.Context) {
var req systemReq.ChangePasswordReq
_ = c.ShouldBindJSON(&req)
if err := utils.Verify(req, utils.ChangePasswordVerify); err != nil {
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(req, utils.ChangePasswordVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
uid := utils.GetUserID(c)
u := &system.SysUser{GVA_MODEL: global.GVA_MODEL{ID: uid}, Password: req.Password}
if _, err := userService.ChangePassword(u, req.NewPassword); err != nil {
_, err = userService.ChangePassword(u, req.NewPassword)
if err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage("修改失败,原密码与当前账户不符", c)
} else {
response.OkWithMessage("修改成功", c)
return
}
response.OkWithMessage("修改成功", c)
}
// @Tags SysUser
// @Summary 分页获取用户列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {object} response.Response{data=response.PageResult,msg=string} "分页获取用户列表,返回包括列表,总数,页码,每页数量"
// @Router /user/getUserList [post]
// GetUserList
// @Tags SysUser
// @Summary 分页获取用户列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo 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
_ = c.ShouldBindJSON(&pageInfo)
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
err := c.ShouldBindJSON(&pageInfo)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if list, total, err := userService.GetUserInfoList(pageInfo); err != nil {
err = utils.Verify(pageInfo, utils.PageInfoVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
list, total, err := userService.GetUserInfoList(pageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
return
}
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
// @Tags SysUser
// @Summary 更改用户权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SetUserAuth true "用户UUID, 角色ID"
// @Success 200 {object} response.Response{msg=string} "设置用户权限"
// @Router /user/setUserAuthority [post]
// SetUserAuthority
// @Tags SysUser
// @Summary 更改用户权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SetUserAuth true "用户UUID, 角色ID"
// @Success 200 {object} response.Response{msg=string} "设置用户权限"
// @Router /user/setUserAuthority [post]
func (b *BaseApi) SetUserAuthority(c *gin.Context) {
var sua systemReq.SetUserAuth
_ = c.ShouldBindJSON(&sua)
err := c.ShouldBindJSON(&sua)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if UserVerifyErr := utils.Verify(sua, utils.SetUserAuthorityVerify); UserVerifyErr != nil {
response.FailWithMessage(UserVerifyErr.Error(), c)
return
}
userID := utils.GetUserID(c)
if err := userService.SetUserAuthority(userID, sua.AuthorityId); err != nil {
err = userService.SetUserAuthority(userID, sua.AuthorityId)
if err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage(err.Error(), c)
return
}
claims := utils.GetUserInfo(c)
j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
claims.AuthorityId = sua.AuthorityId
if token, err := j.CreateToken(*claims); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage(err.Error(), c)
} else {
claims := utils.GetUserInfo(c)
j := &utils.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
claims.AuthorityId = sua.AuthorityId
if token, err := j.CreateToken(*claims); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage(err.Error(), c)
} else {
c.Header("new-token", token)
c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt, 10))
response.OkWithMessage("修改成功", c)
}
}
}
// @Tags SysUser
// @Summary 设置用户权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SetUserAuthorities true "用户UUID, 角色ID"
// @Success 200 {object} response.Response{msg=string} "设置用户权限"
// @Router /user/setUserAuthorities [post]
func (b *BaseApi) SetUserAuthorities(c *gin.Context) {
var sua systemReq.SetUserAuthorities
_ = c.ShouldBindJSON(&sua)
if err := userService.SetUserAuthorities(sua.ID, sua.AuthorityIds); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage("修改失败", c)
} else {
c.Header("new-token", token)
c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt.Unix(), 10))
utils.SetToken(c, token, int((claims.ExpiresAt.Unix()-time.Now().Unix())/60))
response.OkWithMessage("修改成功", c)
}
}
// @Tags SysUser
// @Summary 删除用户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "用户ID"
// @Success 200 {object} response.Response{msg=string} "删除用户"
// @Router /user/deleteUser [delete]
// SetUserAuthorities
// @Tags SysUser
// @Summary 设置用户权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SetUserAuthorities true "用户UUID, 角色ID"
// @Success 200 {object} response.Response{msg=string} "设置用户权限"
// @Router /user/setUserAuthorities [post]
func (b *BaseApi) SetUserAuthorities(c *gin.Context) {
var sua systemReq.SetUserAuthorities
err := c.ShouldBindJSON(&sua)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = userService.SetUserAuthorities(sua.ID, sua.AuthorityIds)
if err != nil {
global.GVA_LOG.Error("修改失败!", zap.Error(err))
response.FailWithMessage("修改失败", c)
return
}
response.OkWithMessage("修改成功", c)
}
// DeleteUser
// @Tags SysUser
// @Summary 删除用户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.GetById true "用户ID"
// @Success 200 {object} response.Response{msg=string} "删除用户"
// @Router /user/deleteUser [delete]
func (b *BaseApi) DeleteUser(c *gin.Context) {
var reqId request.GetById
_ = c.ShouldBindJSON(&reqId)
if err := utils.Verify(reqId, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&reqId)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(reqId, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
@@ -260,40 +320,46 @@ func (b *BaseApi) DeleteUser(c *gin.Context) {
response.FailWithMessage("删除失败, 自杀失败", c)
return
}
if err := userService.DeleteUser(reqId.ID); err != nil {
err = userService.DeleteUser(reqId.ID)
if err != nil {
global.GVA_LOG.Error("删除失败!", zap.Error(err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
return
}
response.OkWithMessage("删除成功", c)
}
// @Tags SysUser
// @Summary 设置用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "设置用户信息"
// @Router /user/setUserInfo [put]
// SetUserInfo
// @Tags SysUser
// @Summary 设置用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "设置用户信息"
// @Router /user/setUserInfo [put]
func (b *BaseApi) SetUserInfo(c *gin.Context) {
var user systemReq.ChangeUserInfo
_ = c.ShouldBindJSON(&user)
if err := utils.Verify(user, utils.IdVerify); err != nil {
err := c.ShouldBindJSON(&user)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(user, utils.IdVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if len(user.AuthorityIds) != 0 {
err := userService.SetUserAuthorities(user.ID, user.AuthorityIds)
err = userService.SetUserAuthorities(user.ID, user.AuthorityIds)
if err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败", c)
return
}
}
if err := userService.SetUserInfo(system.SysUser{
err = userService.SetUserInfo(system.SysUser{
GVA_MODEL: global.GVA_MODEL{
ID: user.ID,
},
@@ -303,27 +369,33 @@ func (b *BaseApi) SetUserInfo(c *gin.Context) {
Email: user.Email,
SideMode: user.SideMode,
Enable: user.Enable,
}); err != nil {
})
if err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败", c)
} else {
response.OkWithMessage("设置成功", c)
return
}
response.OkWithMessage("设置成功", c)
}
// @Tags SysUser
// @Summary 设置用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "设置用户信息"
// @Router /user/SetSelfInfo [put]
// SetSelfInfo
// @Tags SysUser
// @Summary 设置用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "设置用户信息"
// @Router /user/SetSelfInfo [put]
func (b *BaseApi) SetSelfInfo(c *gin.Context) {
var user systemReq.ChangeUserInfo
_ = c.ShouldBindJSON(&user)
err := c.ShouldBindJSON(&user)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
user.ID = utils.GetUserID(c)
if err := userService.SetUserInfo(system.SysUser{
err = userService.SetSelfInfo(system.SysUser{
GVA_MODEL: global.GVA_MODEL{
ID: user.ID,
},
@@ -333,45 +405,54 @@ func (b *BaseApi) SetSelfInfo(c *gin.Context) {
Email: user.Email,
SideMode: user.SideMode,
Enable: user.Enable,
}); err != nil {
})
if err != nil {
global.GVA_LOG.Error("设置失败!", zap.Error(err))
response.FailWithMessage("设置失败", c)
} else {
response.OkWithMessage("设置成功", c)
return
}
response.OkWithMessage("设置成功", c)
}
// @Tags SysUser
// @Summary 获取用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取用户信息"
// @Router /user/getUserInfo [get]
// GetUserInfo
// @Tags SysUser
// @Summary 获取用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取用户信息"
// @Router /user/getUserInfo [get]
func (b *BaseApi) GetUserInfo(c *gin.Context) {
uuid := utils.GetUserUuid(c)
if ReqUser, err := userService.GetUserInfo(uuid); err != nil {
ReqUser, err := userService.GetUserInfo(uuid)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "获取成功", c)
return
}
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "获取成功", c)
}
// @Tags SysUser
// @Summary 重置用户密码
// @Security ApiKeyAuth
// ResetPassword
// @Tags SysUser
// @Summary 重置用户密码
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body system.SysUser true "ID"
// @Success 200 {object} response.Response{msg=string} "重置用户密码"
// @Router /user/resetPassword [post]
// @Param data body system.SysUser true "ID"
// @Success 200 {object} response.Response{msg=string} "重置用户密码"
// @Router /user/resetPassword [post]
func (b *BaseApi) ResetPassword(c *gin.Context) {
var user system.SysUser
_ = c.ShouldBindJSON(&user)
if err := userService.ResetPassword(user.ID); err != nil {
err := c.ShouldBindJSON(&user)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = userService.ResetPassword(user.ID)
if err != nil {
global.GVA_LOG.Error("重置失败!", zap.Error(err))
response.FailWithMessage("重置失败"+err.Error(), c)
} else {
response.OkWithMessage("重置成功", c)
return
}
response.OkWithMessage("重置成功", c)
}
+93 -76
View File
@@ -2,46 +2,61 @@
# jwt configuration
jwt:
signing-key: 'qmPlus'
expires-time: 604800
buffer-time: 86400
issuer: 'qmPlus'
signing-key: qmPlus
expires-time: 7d
buffer-time: 1d
issuer: qmPlus
# zap logger configuration
zap:
level: 'info'
prefix: '[github.com/flipped-aurora/gin-vue-admin/server]'
format: 'console'
director: 'log'
encode-level: 'LowercaseColorLevelEncoder'
stacktrace-key: 'stacktrace'
max-age: 30 # 默认日志留存默认以天为单位
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
# redis configuration
redis:
db: 0
addr: '177.7.0.14:6379'
addr: 177.7.0.14:6379
password: ""
# mongo configuration
mongo:
coll: ''
options: ''
database: ''
username: ''
password: ''
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'
to: xxx@qq.com
port: 465
from: 'xxx@163.com'
host: 'smtp.163.com'
from: xxx@163.com
host: smtp.163.com
is-ssl: true
secret: 'xxx'
nickname: 'test'
secret: xxx
nickname: test
# system configuration
system:
env: 'public' # Change to "develop" to skip authentication for development mode
env: public # Change to "develop" to skip authentication for development mode
addr: 8888
db-type: 'mysql'
oss-type: 'local' # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
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
@@ -53,16 +68,18 @@ captcha:
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: ''
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
@@ -71,27 +88,27 @@ mysql:
# pgsql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
pgsql:
path: ''
port: ''
config: ''
db-name: ''
username: ''
password: ''
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
db-list:
- disabled: true # 是否启用
- disable: true # 是否禁用
type: "" # 数据库的类型,目前支持mysql、pgsql
alias-name: "" # 数据库的名称,注意: alias-name 需要在db-list中唯一
path: ''
port: ''
config: ''
db-name: ''
username: ''
password: ''
path: ""
port: ""
config: ""
db-name: ""
username: ""
password: ""
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
@@ -100,8 +117,8 @@ db-list:
# local configuration
local:
path: 'uploads/file' # 访问路径
store-path: 'uploads/file' # 存储路径
path: uploads/file
store-path: uploads/file
# autocode configuration
autocode:
@@ -124,70 +141,70 @@ autocode:
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu:
zone: 'ZoneHuaDong'
bucket: ''
img-path: ''
zone: ZoneHuaDong
bucket: ""
img-path: ""
use-https: false
access-key: ''
secret-key: ''
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: 'xxxxxxxx'
secret-key: 'xxxxxxxx'
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: ''
endpoint: ""
s3-force-path-style: false
disable-ssl: false
secret-id: xxxxxxxx
secret-key: xxxxxxxx
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
# 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/
# timer task db clear table
Timer:
start: true
spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3
detail:
- tableName: "sys_operation_records"
compareField: "created_at"
interval: "2160h"
- tableName: "jwt_blacklists"
compareField: "created_at"
interval: "168h"
- tableName: sys_operation_records
compareField: created_at
interval: 2160h
- tableName: jwt_blacklists
compareField: created_at
interval: 168h
# 跨域配置
# 需要配合 server/initialize/router.go#L32 使用
# 需要配合 server/initialize/router.go -> `Router.Use(middleware.CorsByRules())` 使用
cors:
mode: whitelist # 放行模式: allow-all, 放行全部; whitelist, 白名单模式, 来自白名单内域名的请求添加 cors 头; strict-whitelist 严格白名单模式, 白名单外的请求一律拒绝
whitelist:
@@ -200,4 +217,4 @@ cors:
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 # 布尔值
+216 -122
View File
@@ -1,58 +1,91 @@
aliyun-oss:
endpoint: yourEndpoint
access-key-id: yourAccessKeyId
access-key-secret: yourAccessKeySecret
bucket-name: yourBucketName
bucket-url: yourBucketUrl
base-path: yourBasePath
autocode:
transfer-restart: true
root: E:\gin-vue-admin
server: /server
server-api: /api/v1/%s
server-plug: /plugin/%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
aws-s3:
bucket: xxxxx-10005608
region: ap-shanghai
endpoint: ""
s3-force-path-style: false
disable-ssl: false
secret-id: xxxxxxxx
secret-key: xxxxxxxx
base-url: https://gin.vue.admin
path-prefix: github.com/flipped-aurora/gin-vue-admin/server
# github.com/flipped-aurora/gin-vue-admin/server Global Configuration
# jwt configuration
jwt:
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
retention-day: -1
# redis configuration
redis:
#是否使用redis集群模式
useCluster: false
#使用集群模式addr和db默认无效
addr: 127.0.0.1:6379
password: ""
db: 0
clusterAddrs:
- "172.21.0.3:7000"
- "172.21.0.4:7001"
- "172.21.0.2:7002"
# 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: ''
# email configuration
email:
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: ""
# captcha configuration
captcha:
key-long: 6
img-width: 240
img-height: 80
cors:
mode: whitelist
whitelist:
- allow-origin: example1.com
allow-methods: GET, POST
allow-headers: content-type
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,
Content-Type
allow-credentials: true
- allow-origin: example2.com
allow-methods: GET, POST
allow-headers: content-type
expose-headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,
Content-Type
allow-credentials: true
db-list:
- disable: false
type: ""
alias-name: ""
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: ""
@@ -63,41 +96,9 @@ db-list:
max-open-conns: 100
log-mode: ""
log-zap: false
email:
to: xxx@qq.com
port: 465
from: xxx@163.com
host: smtp.163.com
is-ssl: true
secret: xxx
nickname: test
excel:
dir: ./resource/excel/
hua-wei-obs:
path: you-path
bucket: you-bucket
endpoint: you-endpoint
access-key: you-access-key
secret-key: you-secret-key
jwt:
signing-key: 8a60885b-caa4-4832-85e8-b4dcd9524778
expires-time: 604800
buffer-time: 86400
issuer: qmPlus
local:
path: uploads/file
store-path: uploads/file
mysql:
path: 127.0.0.1
port: "3306"
config: charset=utf8mb4&parseTime=True&loc=Local
db-name: gva
username: root
password: Aa@6447985
max-idle-conns: 10
max-open-conns: 100
log-mode: error
log-zap: false
# pgsql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://gin-vue-admin.com/docs/first_master)
pgsql:
path: ""
port: ""
@@ -109,6 +110,68 @@ pgsql:
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
# autocode configuration
autocode:
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: ""
@@ -117,44 +180,75 @@ qiniu:
access-key: ""
secret-key: ""
use-cdn-domains: false
redis:
db: 0
addr: 127.0.0.1:6379
password: ""
system:
env: public
addr: 8888
db-type: mysql
oss-type: local
use-multipoint: false
use-redis: false
iplimit-count: 15000
iplimit-time: 3600
# aliyun oss configuration
aliyun-oss:
endpoint: yourEndpoint
access-key-id: yourAccessKeyId
access-key-secret: yourAccessKeySecret
bucket-name: yourBucketName
bucket-url: yourBucketUrl
base-path: yourBasePath
# tencent cos configuration
tencent-cos:
bucket: xxxxx-10005608
region: ap-shanghai
secret-id: xxxxxxxx
secret-key: xxxxxxxx
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
timer:
start: true
spec: '@daily'
with_seconds: false
detail:
- tableName: sys_operation_records
compareField: created_at
interval: 2160h
- tableName: jwt_blacklists
compareField: created_at
interval: 168h
zap:
level: info
prefix: '[github.com/flipped-aurora/gin-vue-admin/server]'
format: console
director: log
encode-level: LowercaseColorLevelEncoder
stacktrace-key: stacktrace
max-age: 30
show-line: true
log-in-console: true
# 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
# 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
# excel configuration
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
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 {
TransferRestart bool `mapstructure:"transfer-restart" json:"transfer-restart" yaml:"transfer-restart"`
Root string `mapstructure:"root" json:"root" yaml:"root"`
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"`
SModel string `mapstructure:"server-model" json:"server-model" yaml:"server-model"`
SRequest string `mapstructure:"server-request" json:"server-request" yaml:"server-request"`
SRouter string `mapstructure:"server-router" json:"server-router" yaml:"server-router"`
SService string `mapstructure:"server-service" json:"server-service" yaml:"server-service"`
Web string `mapstructure:"web" json:"web" yaml:"web"`
WApi string `mapstructure:"web-api" json:"web-api" yaml:"web-api"`
WForm string `mapstructure:"web-form" json:"web-form" yaml:"web-form"`
WTable string `mapstructure:"web-table" json:"web-table" yaml:"web-table"`
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...)
}
+5 -3
View File
@@ -1,7 +1,9 @@
package config
type Captcha struct {
KeyLong int `mapstructure:"key-long" json:"key-long" yaml:"key-long"` // 验证码长度
ImgWidth int `mapstructure:"img-width" json:"img-width" yaml:"img-width"` // 验证码宽度
ImgHeight int `mapstructure:"img-height" json:"img-height" yaml:"img-height"` // 验证码高度
KeyLong int `mapstructure:"key-long" json:"key-long" yaml:"key-long"` // 验证码长度
ImgWidth int `mapstructure:"img-width" json:"img-width" yaml:"img-width"` // 验证码宽度
ImgHeight int `mapstructure:"img-height" json:"img-height" yaml:"img-height"` // 验证码高度
OpenCaptcha int `mapstructure:"open-captcha" json:"open-captcha" yaml:"open-captcha"` // 防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码
OpenCaptchaTimeOut int `mapstructure:"open-captcha-timeout" json:"open-captcha-timeout" yaml:"open-captcha-timeout"` // 防爆破验证码超时时间,单位:s(秒)
}
+13 -7
View File
@@ -4,6 +4,7 @@ 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"`
@@ -11,18 +12,23 @@ type Server struct {
AutoCode Autocode `mapstructure:"autocode" json:"autocode" yaml:"autocode"`
// gorm
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
Mssql Mssql `mapstructure:"mssql" json:"mssql" yaml:"mssql"`
Pgsql Pgsql `mapstructure:"pgsql" json:"pgsql" yaml:"pgsql"`
Oracle Oracle `mapstructure:"oracle" json:"oracle" yaml:"oracle"`
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"`
Timer Timer `mapstructure:"timer" json:"timer" yaml:"timer"`
DiskList []DiskList `mapstructure:"disk-list" json:"disk-list" yaml:"disk-list"`
// 跨域配置
Cors CORS `mapstructure:"cors" json:"cors" yaml:"cors"`
+28 -5
View File
@@ -1,5 +1,10 @@
package config
import (
"gorm.io/gorm/logger"
"strings"
)
type DsnProvider interface {
Dsn() string
}
@@ -9,21 +14,39 @@ type DsnProvider interface {
// GeneralDB 也被 Pgsql 和 Mysql 原样使用
type GeneralDB struct {
Path string `mapstructure:"path" json:"path" yaml:"path"` // 服务器地址:端口
Port string `mapstructure:"port" json:"port" yaml:"port"` //:端口
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"` // 数据库用户名
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"` // 打开到数据库的最大连接数
LogMode string `mapstructure:"log-mode" json:"log-mode" yaml:"log-mode"` // 是否开启Gorm全局日志
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 {
Disable bool `mapstructure:"disable" json:"disable" yaml:"disable"`
Type string `mapstructure:"type" json:"type" yaml:"type"`
AliasName string `mapstructure:"alias-name" json:"alias-name" yaml:"alias-name"`
GeneralDB `yaml:",inline" mapstructure:",squash"`
Disable bool `mapstructure:"disable" json:"disable" yaml:"disable"`
}
+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"`
}
+7 -7
View File
@@ -1,11 +1,11 @@
package config
type Email struct {
To string `mapstructure:"to" json:"to" yaml:"to"` // 收件人:多个以英文逗号分隔
Port int `mapstructure:"port" json:"port" yaml:"port"` // 端口
From string `mapstructure:"from" json:"from" yaml:"from"` // 收件人
Host string `mapstructure:"host" json:"host" yaml:"host"` // 服务器地址
IsSSL bool `mapstructure:"is-ssl" json:"is-ssl" yaml:"is-ssl"` // 是否SSL
Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` // 密钥
Nickname string `mapstructure:"nickname" json:"nickname" yaml:"nickname"` // 昵称
To string `mapstructure:"to" json:"to" yaml:"to"` // 收件人:多个以英文逗号分隔 例:a@qq.com b@qq.com 正式开发中请把此项目作为参数使用
From string `mapstructure:"from" json:"from" yaml:"from"` // 发件人 你自己要发邮件的邮箱
Host string `mapstructure:"host" json:"host" yaml:"host"` // 服务器地址 例如 smtp.qq.com 请前往QQ或者你要发邮件的邮箱查看其smtp协议
Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` // 密钥 用于登录的密钥 最好不要用邮箱密码 去邮箱smtp申请一个用于登录的密钥
Nickname string `mapstructure:"nickname" json:"nickname" yaml:"nickname"` // 昵称 发件人昵称 通常为自己的邮箱
Port int `mapstructure:"port" json:"port" yaml:"port"` // 端口 请前往QQ或者你要发邮件的邮箱查看其smtp协议 大多为 465
IsSSL bool `mapstructure:"is-ssl" json:"is-ssl" yaml:"is-ssl"` // 是否SSL 是否开启SSL
}
+10
View File
@@ -0,0 +1,10 @@
package config
type Mssql struct {
GeneralDB `yaml:",inline" mapstructure:",squash"`
}
// 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"
}
-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
}
+10
View File
@@ -0,0 +1,10 @@
package config
type Oracle struct {
GeneralDB `yaml:",inline" mapstructure:",squash"`
}
func (m *Oracle) Dsn() string {
return "oracle://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "/" + m.Dbname + "?" + m.Config
}
-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
}
+13
View File
@@ -0,0 +1,13 @@
package config
import (
"path/filepath"
)
type Sqlite struct {
GeneralDB `yaml:",inline" mapstructure:",squash"`
}
func (s *Sqlite) Dsn() string {
return filepath.Join(s.Path, s.Dbname+".db")
}
+2 -2
View File
@@ -2,7 +2,7 @@ package config
type JWT struct {
SigningKey string `mapstructure:"signing-key" json:"signing-key" yaml:"signing-key"` // jwt签名
ExpiresTime int64 `mapstructure:"expires-time" json:"expires-time" yaml:"expires-time"` // 过期时间
BufferTime int64 `mapstructure:"buffer-time" json:"buffer-time" yaml:"buffer-time"` // 缓冲时间
ExpiresTime string `mapstructure:"expires-time" json:"expires-time" yaml:"expires-time"` // 过期时间
BufferTime string `mapstructure:"buffer-time" json:"buffer-time" yaml:"buffer-time"` // 缓冲时间
Issuer string `mapstructure:"issuer" json:"issuer" yaml:"issuer"` // 签发者
}
+41
View File
@@ -0,0 +1,41 @@
package config
import (
"fmt"
"strings"
)
type Mongo struct {
Coll string `json:"coll" yaml:"coll" mapstructure:"coll"` // collection name
Options string `json:"options" yaml:"options" mapstructure:"options"` // mongodb options
Database string `json:"database" yaml:"database" mapstructure:"database"` // database name
Username string `json:"username" yaml:"username" mapstructure:"username"` // 用户名
Password string `json:"password" yaml:"password" mapstructure:"password"` // 密码
AuthSource string `json:"auth-source" yaml:"auth-source" mapstructure:"auth-source"` // 验证数据库
MinPoolSize uint64 `json:"min-pool-size" yaml:"min-pool-size" mapstructure:"min-pool-size"` // 最小连接池
MaxPoolSize uint64 `json:"max-pool-size" yaml:"max-pool-size" mapstructure:"max-pool-size"` // 最大连接池
SocketTimeoutMs int64 `json:"socket-timeout-ms" yaml:"socket-timeout-ms" mapstructure:"socket-timeout-ms"` // socket超时时间
ConnectTimeoutMs int64 `json:"connect-timeout-ms" yaml:"connect-timeout-ms" mapstructure:"connect-timeout-ms"` // 连接超时时间
IsZap bool `json:"is-zap" yaml:"is-zap" mapstructure:"is-zap"` // 是否开启zap日志
Hosts []*MongoHost `json:"hosts" yaml:"hosts" mapstructure:"hosts"` // 主机列表
}
type MongoHost struct {
Host string `json:"host" yaml:"host" mapstructure:"host"` // ip地址
Port string `json:"port" yaml:"port" mapstructure:"port"` // 端口
}
// Uri .
func (x *Mongo) Uri() string {
length := len(x.Hosts)
hosts := make([]string, 0, length)
for i := 0; i < length; i++ {
if x.Hosts[i].Host != "" && x.Hosts[i].Port != "" {
hosts = append(hosts, x.Hosts[i].Host+":"+x.Hosts[i].Port)
}
}
if x.Options != "" {
return fmt.Sprintf("mongodb://%s/%s?%s", strings.Join(hosts, ","), x.Database, x.Options)
}
return fmt.Sprintf("mongodb://%s/%s", strings.Join(hosts, ","), x.Database)
}
+2 -2
View File
@@ -4,10 +4,10 @@ type AwsS3 struct {
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
Region string `mapstructure:"region" json:"region" yaml:"region"`
Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"`
S3ForcePathStyle bool `mapstructure:"s3-force-path-style" json:"s3-force-path-style" yaml:"s3-force-path-style"`
DisableSSL bool `mapstructure:"disable-ssl" json:"disable-ssl" yaml:"disable-ssl"`
SecretID string `mapstructure:"secret-id" json:"secret-id" yaml:"secret-id"`
SecretKey string `mapstructure:"secret-key" json:"secret-key" yaml:"secret-key"`
BaseURL string `mapstructure:"base-url" json:"base-url" yaml:"base-url"`
PathPrefix string `mapstructure:"path-prefix" json:"path-prefix" yaml:"path-prefix"`
S3ForcePathStyle bool `mapstructure:"s3-force-path-style" json:"s3-force-path-style" yaml:"s3-force-path-style"`
DisableSSL bool `mapstructure:"disable-ssl" json:"disable-ssl" yaml:"disable-ssl"`
}
+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"`
}
+1 -1
View File
@@ -4,8 +4,8 @@ type Qiniu struct {
Zone string `mapstructure:"zone" json:"zone" yaml:"zone"` // 存储区域
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` // 空间名称
ImgPath string `mapstructure:"img-path" json:"img-path" yaml:"img-path"` // CDN加速域名
UseHTTPS bool `mapstructure:"use-https" json:"use-https" yaml:"use-https"` // 是否使用https
AccessKey string `mapstructure:"access-key" json:"access-key" yaml:"access-key"` // 秘钥AK
SecretKey string `mapstructure:"secret-key" json:"secret-key" yaml:"secret-key"` // 秘钥SK
UseHTTPS bool `mapstructure:"use-https" json:"use-https" yaml:"use-https"` // 是否使用https
UseCdnDomains bool `mapstructure:"use-cdn-domains" json:"use-cdn-domains" yaml:"use-cdn-domains"` // 上传是否使用CDN上传加速
}
+5 -3
View File
@@ -1,7 +1,9 @@
package config
type Redis struct {
DB int `mapstructure:"db" json:"db" yaml:"db"` // redis的哪个数据库
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` // 服务器地址:端口
Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码
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"` // 集群模式下的节点地址列表
}
+7 -6
View File
@@ -1,12 +1,13 @@
package config
type System struct {
Env string `mapstructure:"env" json:"env" yaml:"env"` // 环境值
Addr int `mapstructure:"addr" json:"addr" yaml:"addr"` // 端口值
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类型
UseMultipoint bool `mapstructure:"use-multipoint" json:"use-multipoint" yaml:"use-multipoint"` // 多点登录拦截
UseRedis bool `mapstructure:"use-redis" json:"use-redis" yaml:"use-redis"` // 使用redis
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
}
-14
View File
@@ -1,14 +0,0 @@
package config
type Timer struct {
Start bool `mapstructure:"start" json:"start" yaml:"start"` // 是否启用
Spec string `mapstructure:"spec" json:"spec" yaml:"spec"` // CRON表达式
WithSeconds bool `mapstructure:"with_seconds" json:"with_seconds" yaml:"with_seconds"` // 是否精确到秒
Detail []Detail `mapstructure:"detail" json:"detail" yaml:"detail"`
}
type Detail struct {
TableName string `mapstructure:"tableName" json:"tableName" yaml:"tableName"` // 需要清理的表名
CompareField string `mapstructure:"compareField" json:"compareField" yaml:"compareField"` // 需要比较时间的字段
Interval string `mapstructure:"interval" json:"interval" yaml:"interval"` // 时间间隔
}
+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.WarnLevel
case "dpanic":
return zapcore.DPanicLevel
case "panic":
return zapcore.PanicLevel
case "fatal":
return zapcore.FatalLevel
default:
return zapcore.DebugLevel
}
}
+121
View File
@@ -0,0 +1,121 @@
package internal
import (
"os"
"path/filepath"
"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)
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)
// CutterWithLayout 时间格式
func CutterWithLayout(layout string) CutterOption {
return func(c *Cutter) {
c.layout = layout
}
}
// 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,
retentionDay: retentionDay,
mutex: new(sync.RWMutex),
}
for i := 0; i < len(options); i++ {
options[i](rotate)
}
return rotate
}
// Write satisfies the io.Writer interface. It writes to the
// appropriate file handle that is currently being used.
// If we have reached rotation time, the target file gets
// automatically rotated, and also purged if necessary.
func (c *Cutter) Write(bytes []byte) (n int, err error) {
c.mutex.Lock()
defer func() {
if c.file != nil {
_ = c.file.Close()
c.file = nil
}
c.mutex.Unlock()
}()
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))
}
for i := 0; i < length; i++ {
values = append(values, c.formats[i])
}
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
}
err = removeNDaysFolders(c.director, c.retentionDay)
if err != nil {
return 0, err
}
c.file, err = os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return 0, err
}
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
})
}
-29
View File
@@ -1,29 +0,0 @@
package internal
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"go.uber.org/zap/zapcore"
"os"
"path"
"time"
)
var FileRotatelogs = new(fileRotatelogs)
type fileRotatelogs struct{}
// GetWriteSyncer 获取 zapcore.WriteSyncer
// Author [SliverHorn](https://github.com/SliverHorn)
func (r *fileRotatelogs) GetWriteSyncer(level string) (zapcore.WriteSyncer, error) {
fileWriter, err := rotatelogs.New(
path.Join(global.GVA_CONFIG.Zap.Director, "%Y-%m-%d", level+".log"),
rotatelogs.WithClock(rotatelogs.Local),
rotatelogs.WithMaxAge(time.Duration(global.GVA_CONFIG.Zap.MaxAge)*24*time.Hour), // 日志留存时间
rotatelogs.WithRotationTime(time.Hour*24),
)
if global.GVA_CONFIG.Zap.LogInConsole {
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(fileWriter)), err
}
return zapcore.AddSync(fileWriter), err
}
-107
View File
@@ -1,107 +0,0 @@
package internal
import (
"fmt"
"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, err := FileRotatelogs.GetWriteSyncer(l.String()) // 使用file-rotatelogs进行日志分割
if err != nil {
fmt.Printf("Get Write Syncer Failed err:%v", err.Error())
return nil
}
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(t.Format(global.GVA_CONFIG.Zap.Prefix + "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()
}
+14 -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"
@@ -19,7 +17,12 @@ func RunWindowsServer() {
// 初始化redis服务
initialize.Redis()
}
if global.GVA_CONFIG.System.UseMongo {
err := initialize.Mongo.Initialization()
if err != nil {
zap.L().Error(fmt.Sprintf("%+v", err))
}
}
// 从db加载jwt数据
if global.GVA_DB != nil {
system.LoadAll()
@@ -30,20 +33,22 @@ func RunWindowsServer() {
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.5.3b
加群方式:微信号:shouzi_1994 QQ群:622360840
当前版本:v2.7.1
加群方式:微信号: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,
}
}
+4 -11
View File
@@ -7,14 +7,12 @@ import (
"github.com/gin-gonic/gin"
"os"
"path/filepath"
"time"
"github.com/songzhibin97/gkit/cache/local_cache"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"github.com/flipped-aurora/gin-vue-admin/server/global"
_ "github.com/flipped-aurora/gin-vue-admin/server/packfile"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
// Viper //
@@ -31,14 +29,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)
@@ -67,13 +63,10 @@ func Viper(path ...string) *viper.Viper {
}
})
if err = v.Unmarshal(&global.GVA_CONFIG); err != nil {
fmt.Println(err)
panic(err)
}
// root 适配性 根据root位置去找到对应迁移位置,保证root路径有效
global.GVA_CONFIG.AutoCode.Root, _ = filepath.Abs("..")
global.BlackCache = local_cache.NewCache(
local_cache.SetDefaultExpire(time.Second * time.Duration(global.GVA_CONFIG.JWT.ExpiresTime)),
)
return v
}
+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())
}
+2396 -1081
View File
File diff suppressed because it is too large Load Diff
+2383 -1031
View File
File diff suppressed because it is too large Load Diff
+1549 -712
View File
File diff suppressed because it is too large Load Diff
+9 -5
View File
@@ -1,6 +1,8 @@
package global
import (
"github.com/gin-gonic/gin"
"github.com/qiniu/qmgo"
"sync"
"github.com/flipped-aurora/gin-vue-admin/server/utils/timer"
@@ -12,7 +14,7 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/go-redis/redis/v8"
"github.com/redis/go-redis/v9"
"github.com/spf13/viper"
"gorm.io/gorm"
)
@@ -20,16 +22,18 @@ import (
var (
GVA_DB *gorm.DB
GVA_DBList map[string]*gorm.DB
GVA_REDIS *redis.Client
GVA_REDIS 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
+1 -1
View File
@@ -7,7 +7,7 @@ import (
)
type GVA_MODEL struct {
ID uint `gorm:"primarykey"` // 主键ID
ID uint `gorm:"primarykey" json:"ID"` // 主键ID
CreatedAt time.Time // 创建时间
UpdatedAt time.Time // 更新时间
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` // 删除时间
+148 -45
View File
@@ -1,60 +1,163 @@
module github.com/flipped-aurora/gin-vue-admin/server
go 1.16
go 1.22
require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible
github.com/aws/aws-sdk-go v1.42.27
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/casbin/casbin/v2 v2.51.0
github.com/casbin/gorm-adapter/v3 v3.7.3
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.87.1
github.com/casbin/gorm-adapter/v3 v3.18.0
github.com/flipped-aurora/ws v1.0.2
github.com/fsnotify/fsnotify v1.4.9
github.com/fsnotify/fsnotify v1.6.0
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
github.com/gin-gonic/gin v1.7.0
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/spec v0.20.3 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-redis/redis/v8 v8.11.0
github.com/go-sql-driver/mysql v1.6.0
github.com/golang-jwt/jwt/v4 v4.3.0
github.com/gookit/color v1.3.1
github.com/gin-gonic/gin v1.9.1
github.com/glebarez/sqlite v1.8.0
github.com/go-sql-driver/mysql v1.8.1
github.com/goccy/go-json v0.10.2
github.com/gofrs/uuid/v5 v5.0.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/json-iterator/go v1.1.10 // indirect
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lestrrat-go/strftime v1.0.6 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/mapstructure v1.2.2 // indirect
github.com/mojocn/base64Captcha v1.3.1
github.com/mholt/archiver/v4 v4.0.0-alpha.8
github.com/mojocn/base64Captcha v1.3.6
github.com/otiai10/copy v1.7.0
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1
github.com/qiniu/api.v7/v7 v7.4.1
github.com/qiniu/qmgo v1.1.8
github.com/redis/go-redis/v9 v9.0.5
github.com/robfig/cron/v3 v3.0.1
github.com/satori/go.uuid v1.2.0
github.com/shirou/gopsutil/v3 v3.22.5
github.com/songzhibin97/gkit v1.1.1
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.1 // indirect
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/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.2
github.com/tencentyun/cos-go-sdk-v5 v0.7.42
github.com/unrolled/secure v1.13.0
github.com/xuri/excelize/v2 v2.8.0
go.mongodb.org/mongo-driver v1.12.1
go.uber.org/automaxprocs v1.5.3
go.uber.org/zap v1.24.0
golang.org/x/crypto v0.22.0
golang.org/x/sync v0.6.0
golang.org/x/text v0.14.0
gorm.io/datatypes v1.2.1
gorm.io/driver/mysql v1.5.6
gorm.io/driver/postgres v1.5.7
gorm.io/driver/sqlserver v1.5.1
gorm.io/gen v0.3.26
gorm.io/gorm v1.25.10
nhooyr.io/websocket v1.8.7
)
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/bodgit/plumbing v1.2.0 // indirect
github.com/bodgit/sevenzip v1.3.0 // indirect
github.com/bodgit/windows v1.0.0 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/casbin/govaluate v1.1.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/clbanning/mxj v1.8.4 // indirect
github.com/connesc/cipherio v0.2.1 // indirect
github.com/davecgh/go-spew v1.1.1 // 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/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/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/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.4 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgx/v5 v5.5.5 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/microsoft/go-mssqldb v1.1.0 // indirect
github.com/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/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pierrec/lz4/v4 v4.1.15 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // 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/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/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.0
github.com/stretchr/testify v1.7.1
github.com/swaggo/gin-swagger v1.3.0
github.com/swaggo/swag v1.7.0
github.com/tencentyun/cos-go-sdk-v5 v0.7.19
github.com/unrolled/secure v1.0.7
github.com/xuri/excelize/v2 v2.4.1
go.uber.org/zap v1.16.0
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/text v0.3.7
golang.org/x/tools v0.1.5 // indirect
gopkg.in/ini.v1 v1.55.0 // indirect
gorm.io/driver/mysql v1.3.3
gorm.io/driver/postgres v1.3.4
gorm.io/gorm v1.23.4
nhooyr.io/websocket v1.8.6
github.com/subosito/gotenv v1.4.2 // indirect
github.com/therootcompany/xz v1.0.1 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/ulikunitz/xz v0.5.10 // 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
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/image v0.15.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/time v0.1.0 // indirect
golang.org/x/tools v0.17.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/hints v1.1.0 // indirect
gorm.io/plugin/dbresolver v1.5.0 // 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
)
+607 -650
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -17,8 +17,12 @@ func DBList() {
switch info.Type {
case "mysql":
dbMap[info.AliasName] = GormMysqlByConfig(config.Mysql{GeneralDB: info.GeneralDB})
case "mssql":
dbMap[info.AliasName] = GormMssqlByConfig(config.Mssql{GeneralDB: info.GeneralDB})
case "pgsql":
dbMap[info.AliasName] = GormPgSqlByConfig(config.Pgsql{GeneralDB: info.GeneralDB})
case "oracle":
dbMap[info.AliasName] = GormOracleByConfig(config.Oracle{GeneralDB: info.GeneralDB})
default:
continue
}
+8 -2
View File
@@ -47,7 +47,10 @@ 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{},
adapter.CasbinRule{},
@@ -82,7 +85,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{},
+27 -13
View File
@@ -11,25 +11,35 @@ import (
"gorm.io/gorm"
)
// Gorm 初始化数据库并产生数据库全局变量
// Author SliverHorn
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()
}
}
// RegisterTables 注册数据库表专用
// Author SliverHorn
func RegisterTables(db *gorm.DB) {
func RegisterTables() {
db := global.GVA_DB
err := db.AutoMigrate(
// 系统模块表
system.SysApi{},
system.SysIgnoreApi{},
system.SysUser{},
system.SysBaseMenu{},
system.JwtBlacklist{},
@@ -41,22 +51,26 @@ func RegisterTables(db *gorm.DB) {
system.SysBaseMenuParameter{},
system.SysBaseMenuBtn{},
system.SysAuthorityBtn{},
system.SysAutoCode{},
system.SysAutoCodePackage{},
system.SysExportTemplate{},
system.Condition{},
system.JoinTemplate{},
// 示例模块表
example.ExaFile{},
example.ExaCustomer{},
example.ExaFileChunk{},
example.ExaFileUploadAndDownload{},
// 自动化模块表
// Code generated by github.com/flipped-aurora/gin-vue-admin/server Begin; DO NOT EDIT.
// Code generated by github.com/flipped-aurora/gin-vue-admin/server End; DO NOT EDIT.
)
if err != nil {
global.GVA_LOG.Error("register table failed", zap.Error(err))
os.Exit(0)
}
err = bizModel()
if err != nil {
global.GVA_LOG.Error("register biz_table failed", zap.Error(err))
os.Exit(0)
}
global.GVA_LOG.Info("register table success")
}
+14
View File
@@ -0,0 +1,14 @@
package initialize
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
)
func bizModel() error {
db := global.GVA_DB
err := db.AutoMigrate()
if err != nil {
return err
}
return nil
}
+59
View File
@@ -0,0 +1,59 @@
/*
* @Author: 逆光飞翔 191180776@qq.com
* @Date: 2022-12-08 17:25:49
* @LastEditors: 逆光飞翔 191180776@qq.com
* @LastEditTime: 2022-12-08 18:00:00
* @FilePath: \server\initialize\gorm_mssql.go
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
package initialize
import (
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/initialize/internal"
"gorm.io/driver/sqlserver"
"gorm.io/gorm"
)
// GormMssql 初始化Mssql数据库
// Author [LouisZhang](191180776@qq.com)
func GormMssql() *gorm.DB {
m := global.GVA_CONFIG.Mssql
if m.Dbname == "" {
return nil
}
mssqlConfig := sqlserver.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
return nil
} else {
db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine)
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
}
// GormMssqlByConfig 初始化Mysql数据库用过传入配置
func GormMssqlByConfig(m config.Mssql) *gorm.DB {
if m.Dbname == "" {
return nil
}
mssqlConfig := sqlserver.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(sqlserver.New(mssqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
panic(err)
} else {
db.InstanceSet("gorm:table_options", "ENGINE=InnoDB")
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
}
+5 -2
View File
@@ -4,6 +4,7 @@ import (
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/initialize/internal"
_ "github.com/go-sql-driver/mysql"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
@@ -21,9 +22,10 @@ func GormMysql() *gorm.DB {
DefaultStringSize: 191, // string 类型字段的默认长度
SkipInitializeWithVersion: false, // 根据版本自动配置
}
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil {
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
return nil
} else {
db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine)
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
@@ -41,9 +43,10 @@ func GormMysqlByConfig(m config.Mysql) *gorm.DB {
DefaultStringSize: 191, // string 类型字段的默认长度
SkipInitializeWithVersion: false, // 根据版本自动配置
}
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config()); err != nil {
if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
panic(err)
} else {
db.InstanceSet("gorm:table_options", "ENGINE=InnoDB")
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
+52
View File
@@ -0,0 +1,52 @@
package initialize
import (
//"github.com/dzwvip/oracle"
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/initialize/internal"
//_ "github.com/godror/godror"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// GormOracle 初始化oracle数据库
// 如果需要Oracle库 放开import里的注释 把下方 mysql.Config 改为 oracle.Config ; mysql.New 改为 oracle.New
func GormOracle() *gorm.DB {
m := global.GVA_CONFIG.Oracle
if m.Dbname == "" {
return nil
}
oracleConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
}
// GormOracleByConfig 初始化Oracle数据库用过传入配置
func GormOracleByConfig(m config.Oracle) *gorm.DB {
if m.Dbname == "" {
return nil
}
oracleConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
}
+2 -2
View File
@@ -20,7 +20,7 @@ func GormPgSql() *gorm.DB {
DSN: p.Dsn(), // DSN data source name
PreferSimpleProtocol: false,
}
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config()); err != nil {
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil {
return nil
} else {
sqlDB, _ := db.DB()
@@ -39,7 +39,7 @@ func GormPgSqlByConfig(p config.Pgsql) *gorm.DB {
DSN: p.Dsn(), // DSN data source name
PreferSimpleProtocol: false,
}
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config()); err != nil {
if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
+42
View File
@@ -0,0 +1,42 @@
package initialize
import (
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/initialize/internal"
"github.com/glebarez/sqlite"
"gorm.io/gorm"
)
// GormSqlite 初始化Sqlite数据库
func GormSqlite() *gorm.DB {
s := global.GVA_CONFIG.Sqlite
if s.Dbname == "" {
return nil
}
if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(s.MaxIdleConns)
sqlDB.SetMaxOpenConns(s.MaxOpenConns)
return db
}
}
// GormSqliteByConfig 初始化Sqlite数据库用过传入配置
func GormSqliteByConfig(s config.Sqlite) *gorm.DB {
if s.Dbname == "" {
return nil
}
if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(s.MaxIdleConns)
sqlDB.SetMaxOpenConns(s.MaxOpenConns)
return db
}
}
+27 -34
View File
@@ -1,55 +1,48 @@
package internal
import (
"log"
"os"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"log"
"os"
"time"
)
type DBBASE interface {
GetLogMode() string
}
var Gorm = new(_gorm)
type _gorm struct{}
// Config gorm 自定义配置
// Author [SliverHorn](https://github.com/SliverHorn)
func (g *_gorm) Config() *gorm.Config {
config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
_default := logger.New(NewWriter(log.New(os.Stdout, "\r\n", log.LstdFlags)), logger.Config{
SlowThreshold: 200 * time.Millisecond,
LogLevel: logger.Warn,
Colorful: true,
})
var logMode DBBASE
func (g *_gorm) Config(prefix string, singular bool) *gorm.Config {
var general config.GeneralDB
switch global.GVA_CONFIG.System.DbType {
case "mysql":
logMode = &global.GVA_CONFIG.Mysql
break
general = global.GVA_CONFIG.Mysql.GeneralDB
case "pgsql":
logMode = &global.GVA_CONFIG.Pgsql
break
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:
logMode = &global.GVA_CONFIG.Mysql
general = global.GVA_CONFIG.Mysql.GeneralDB
}
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 &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,
}
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...)
}
}
+29
View File
@@ -0,0 +1,29 @@
package internal
import (
"context"
"fmt"
"github.com/qiniu/qmgo/options"
"go.mongodb.org/mongo-driver/event"
opt "go.mongodb.org/mongo-driver/mongo/options"
"go.uber.org/zap"
)
var Mongo = new(mongo)
type mongo struct{}
func (m *mongo) GetClientOptions() []options.ClientOptions {
cmdMonitor := &event.CommandMonitor{
Started: func(ctx context.Context, event *event.CommandStartedEvent) {
zap.L().Info(fmt.Sprintf("[MongoDB][RequestID:%d][database:%s] %s\n", event.RequestID, event.DatabaseName, event.Command), zap.String("business", "mongo"))
},
Succeeded: func(ctx context.Context, event *event.CommandSucceededEvent) {
zap.L().Info(fmt.Sprintf("[MongoDB][RequestID:%d] [%s] %s\n", event.RequestID, event.Duration.String(), event.Reply), zap.String("business", "mongo"))
},
Failed: func(ctx context.Context, event *event.CommandFailedEvent) {
zap.L().Error(fmt.Sprintf("[MongoDB][RequestID:%d] [%s] %s\n", event.RequestID, event.Duration.String(), event.Failure), zap.String("business", "mongo"))
},
}
return []options.ClientOptions{{ClientOptions: &opt.ClientOptions{Monitor: cmdMonitor}}}
}
+151
View File
@@ -0,0 +1,151 @@
package initialize
import (
"context"
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/initialize/internal"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/pkg/errors"
"github.com/qiniu/qmgo"
"github.com/qiniu/qmgo/options"
"go.mongodb.org/mongo-driver/bson"
option "go.mongodb.org/mongo-driver/mongo/options"
"sort"
"strings"
)
var Mongo = new(mongo)
type (
mongo struct{}
Index struct {
V any `bson:"v"`
Ns any `bson:"ns"`
Key []bson.E `bson:"key"`
Name string `bson:"name"`
}
)
func (m *mongo) Indexes(ctx context.Context) error {
// 表名:索引列表 列: "表名": [][]string{{"index1", "index2"}}
indexMap := map[string][][]string{}
for collection, indexes := range indexMap {
err := m.CreateIndexes(ctx, collection, indexes)
if err != nil {
return err
}
}
return nil
}
func (m *mongo) Initialization() error {
var opts []options.ClientOptions
if global.GVA_CONFIG.Mongo.IsZap {
opts = internal.Mongo.GetClientOptions()
}
ctx := context.Background()
client, err := qmgo.Open(ctx, &qmgo.Config{
Uri: global.GVA_CONFIG.Mongo.Uri(),
Coll: global.GVA_CONFIG.Mongo.Coll,
Database: global.GVA_CONFIG.Mongo.Database,
MinPoolSize: &global.GVA_CONFIG.Mongo.MinPoolSize,
MaxPoolSize: &global.GVA_CONFIG.Mongo.MaxPoolSize,
SocketTimeoutMS: &global.GVA_CONFIG.Mongo.SocketTimeoutMs,
ConnectTimeoutMS: &global.GVA_CONFIG.Mongo.ConnectTimeoutMs,
Auth: &qmgo.Credential{
Username: global.GVA_CONFIG.Mongo.Username,
Password: global.GVA_CONFIG.Mongo.Password,
AuthSource: global.GVA_CONFIG.Mongo.AuthSource,
},
}, opts...)
if err != nil {
return errors.Wrap(err, "链接mongodb数据库失败!")
}
global.GVA_MONGO = client
err = m.Indexes(ctx)
if err != nil {
return err
}
return nil
}
func (m *mongo) CreateIndexes(ctx context.Context, name string, indexes [][]string) error {
collection, err := global.GVA_MONGO.Database.Collection(name).CloneCollection()
if err != nil {
return errors.Wrapf(err, "获取[%s]的表对象失败!", name)
}
list, err := collection.Indexes().List(ctx)
if err != nil {
return errors.Wrapf(err, "获取[%s]的索引对象失败!", name)
}
var entities []Index
err = list.All(ctx, &entities)
if err != nil {
return errors.Wrapf(err, "获取[%s]的索引列表失败!", name)
}
length := len(indexes)
indexMap1 := make(map[string][]string, length)
for i := 0; i < length; i++ {
sort.Strings(indexes[i]) // 对索引key进行排序, 在使用bson.M搜索时, bson会自动按照key的字母顺序进行排序
length1 := len(indexes[i])
keys := make([]string, 0, length1)
for j := 0; j < length1; j++ {
if indexes[i][i][0] == '-' {
keys = append(keys, indexes[i][j], "-1")
continue
}
keys = append(keys, indexes[i][j], "1")
}
key := strings.Join(keys, "_")
_, o1 := indexMap1[key]
if o1 {
return errors.Errorf("索引[%s]重复!", key)
}
indexMap1[key] = indexes[i]
}
length = len(entities)
indexMap2 := make(map[string]map[string]string, length)
for i := 0; i < length; i++ {
v1, o1 := indexMap2[entities[i].Name]
if !o1 {
keyLength := len(entities[i].Key)
v1 = make(map[string]string, keyLength)
for j := 0; j < keyLength; j++ {
v2, o2 := v1[entities[i].Key[j].Key]
if !o2 {
v1 = make(map[string]string)
}
v2 = entities[i].Key[j].Key
v1[entities[i].Key[j].Key] = v2
indexMap2[entities[i].Name] = v1
}
}
}
for k1, v1 := range indexMap1 {
_, o2 := indexMap2[k1]
if o2 {
continue
} // 索引存在
if len(fmt.Sprintf("%s.%s.$%s", collection.Name(), name, v1)) > 127 {
err = global.GVA_MONGO.Database.Collection(name).CreateOneIndex(ctx, options.IndexModel{
Key: v1,
IndexOptions: option.Index().SetName(utils.MD5V([]byte(k1))),
// IndexOptions: option.Index().SetName(utils.MD5V([]byte(k1))).SetExpireAfterSeconds(86400), // SetExpireAfterSeconds(86400) 设置索引过期时间, 86400 = 1天
})
if err != nil {
return errors.Wrapf(err, "创建索引[%s]失败!", k1)
}
return nil
}
err = global.GVA_MONGO.Database.Collection(name).CreateOneIndex(ctx, options.IndexModel{
Key: v1,
IndexOptions: option.Index().SetExpireAfterSeconds(86400),
// IndexOptions: option.Index().SetName(utils.MD5V([]byte(k1))).SetExpireAfterSeconds(86400), // SetExpireAfterSeconds(86400) 设置索引过期时间(秒), 86400 = 1天
})
if err != nil {
return errors.Wrapf(err, "创建索引[%s]失败!", k1)
}
}
return nil
}
+32
View File
@@ -0,0 +1,32 @@
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"
)
func OtherInit() {
dr, err := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
if err != nil {
panic(err)
}
_, err = utils.ParseDuration(global.GVA_CONFIG.JWT.BufferTime)
if err != nil {
panic(err)
}
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 -26
View File
@@ -1,35 +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)
}

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