Compare commits

...
222 Commits
Author SHA1 Message Date
奇淼(piexlmax 7085c6c7db 正式发布V2.4.4版本
正式发布V2.4.4版本
2021-07-31 16:00:08 +08:00
piexlmax 6fe19ab6ae 修改版本号为V2.4.4正式 2021-07-31 15:53:39 +08:00
奇淼(piexlmax 462bc8b5fb Merge pull request #597 from flipped-aurora/gva_gormv2_dev
修复分页器左侧border消失的bug
2021-07-26 21:45:29 +08:00
pixel 051b064f21 修复分页器active右侧左边框消失的bug 2021-07-26 20:05:26 +08:00
songzhibin97 0e8b66b183 fix:配置文件修复 2021-07-22 18:24:01 +08:00
songzhibin97 3c64b12e89 fix:配置文件修复 2021-07-22 18:23:39 +08:00
songzhibin97 444c47f678 fix:配置文件修改 2021-07-22 18:23:03 +08:00
奇淼(piexlmax 7477c97b39 Merge pull request #594 from flipped-aurora/gva_gormv2_dev
增加多角色功能和角色切换功能  调整前端获取用户信息方式
2021-07-22 16:54:42 +08:00
pixel aadc3acdec Merge branch 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gva_gormv2_dev 2021-07-22 16:53:13 +08:00
pixel 8f9ecebf41 增加多角色功能和角色切换功能
调整前端获取用户信息方式
2021-07-22 16:46:09 +08:00
奇淼(piexlmax d02b71fe4f Merge pull request #591 from flipped-aurora/gva_gormv2_dev
swag调整适应当前模块化版本
2021-07-20 23:40:36 +08:00
蒋吉兆 4f306ffaab Merge branches 'gva_gormv2_dev' and 'master' of https://github.com/flipped-aurora/gin-vue-admin into gva_gormv2_dev 2021-07-20 23:35:33 +08:00
蒋吉兆 69e9b153b8 调整swagger 2021-07-20 23:29:34 +08:00
奇淼(piexlmax 91d2c2f71e Update server.go 2021-07-20 19:42:43 +08:00
奇淼(piexlmax 957a138df8 Update gin-vue-admin.js 2021-07-20 19:42:15 +08:00
奇淼(piexlmax 60748b4843 Merge pull request #589 from flipped-aurora/gva_gormv2_dev
项目目录支持模块化
2021-07-20 19:38:35 +08:00
songzhibin97 152cb4ec01 Merge branch 'gva_gormv2_dev' into develop 2021-07-20 18:19:05 +08:00
songzhibin97 b758edb28e Merge branch 'master' into develop 2021-07-20 18:15:05 +08:00
songzhibin97 2e2d916b6f Merge branch 'master' into gva_gormv2_dev 2021-07-20 18:08:29 +08:00
奇淼(piexlmax 05983fcfb1 Merge pull request #583 from RickieL/master
新增验证码使用redis存储方式
2021-07-20 14:35:12 +08:00
蒋吉兆 a332527ad3 自动化代码模板bug调整 2021-07-18 19:57:37 +08:00
奇淼(piexlmax f383f025f2 Merge pull request #588 from songzhibin97/gva_gormv2_dev
feat:增加自动注入代码段
2021-07-18 19:11:05 +08:00
songzhibin97 cf4ecd5ff9 feat:优化自动代码段 2021-07-18 14:53:11 +08:00
songzhibin97 b83ad51dd7 fix:增加自动化代码插入点&修复路径配置 2021-07-18 14:16:26 +08:00
songzhibin97 ba05ef0e57 fix:修正mac情况下的文件冲突 2021-07-18 13:13:48 +08:00
pixel 7b6b610a74 代码移动默认配置 2021-07-17 17:07:09 +08:00
pixel 12ac8b6337 模板调整完成 TODO:自动代码移动 2021-07-17 14:45:10 +08:00
pixel c7de76b849 基础架构变更 增加模块化 2021-07-17 14:18:52 +08:00
pixel b5c1babec9 模块化变更 2021-07-16 20:08:11 +08:00
pixel 73a8052c08 模板优化 搜索功能优化 2021-07-15 19:53:30 +08:00
奇淼(piexlmax e69d79cdb8 增加自动化代码回滚功能
增加自动化代码回滚功能
2021-07-14 19:56:51 +08:00
pixel cb8f8ddb16 增加自动化代码回滚功能 2021-07-14 19:54:30 +08:00
pixel d9dde27aa0 增加自动化代码回滚功能 2021-07-14 19:53:23 +08:00
奇淼(piexlmax 2b1ea2947d Merge pull request #585 from flipped-aurora/gva_gormv2_dev
新增自动化代码回滚功能
2021-07-14 19:30:00 +08:00
pixel 065b0d711d 增加自动化代码回滚功能 2021-07-14 19:24:46 +08:00
奇淼(piexlmax f4275d9243 Merge pull request #584 from songzhibin97/gva_gormv2_dev
feat:增加删除历史记录api
2021-07-14 19:10:21 +08:00
songzhibin97 739e8bb06c feat:增加删除历史记录api 2021-07-14 18:25:18 +08:00
pixel 3434b2ba5e 增加自动化代码回滚功能 2021-07-14 14:37:04 +08:00
奇淼(piexlmax 2de1d42a30 Merge pull request #582 from songzhibin97/gva_gormv2_dev
feat:完善前后端回滚交互信息交换
2021-07-14 12:08:15 +08:00
liaoyongfu 83465f4b10 add captcha redis 2021-07-14 10:57:53 +08:00
liaoyongfu e82cfa6d26 add captcha redis 2021-07-14 10:52:36 +08:00
songzhibin97 607022bc08 fix:补充过滤 2021-07-13 20:07:21 +08:00
songzhibin97 b67e17d8ff feat:完善前后端回滚交互信息交换 2021-07-13 19:59:44 +08:00
pixel e0f314d862 增加自动化代码管理页面 2021-07-13 19:45:21 +08:00
pixel 982c4f4d67 Merge branch 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gva_gormv2_dev 2021-07-13 19:04:57 +08:00
奇淼(piexlmax df3c6be36c Merge pull request #581 from songzhibin97/gva_gormv2_dev
feat:新存储了meta信息,完善了记录逻辑
2021-07-13 17:38:17 +08:00
pixel 1a665f3c14 Merge remote-tracking branch 'origin/gva_gormv2_dev' into gva_gormv2_dev 2021-07-13 17:30:42 +08:00
songzhibin97 7fcdaa523c feat:新存储了meta信息,完善了记录逻辑 2021-07-13 17:30:30 +08:00
奇淼(piexlmax beedef280c Merge pull request #579 from songzhibin97/gva_gormv2_dev
fix:修改redis包,使用推荐的v8
2021-07-13 17:22:30 +08:00
奇淼(piexlmax b841919e01 Merge pull request #580 from flipped-aurora/SliverHorn-patch-2
fix: web/Dockerfile cnpm install error
2021-07-13 17:20:55 +08:00
pixel ba77a808df 排除当dns为空时候的bug 2021-07-13 16:25:47 +08:00
SliverHorn e160920e53 fix: web/Dockerfile cnpm install error
update file
- web/Dockerfile

fixed:
- cnpm install error
2021-07-12 20:18:45 +08:00
pixel 43e4c76f83 Merge remote-tracking branch 'origin/gva_gormv2_dev' into gva_gormv2_dev 2021-07-12 19:24:27 +08:00
songzhibin97 07ec0841c9 fix:修改redis包,使用推荐的v8 2021-07-12 19:23:56 +08:00
奇淼(piexlmax 2242f57627 Merge pull request #577 from songzhibin97/gva_gormv2_dev
feat:自动迁移代码回滚&对应历史记录查询
2021-07-12 19:21:26 +08:00
songzhibin97 ff506730de feat:完善回滚逻辑,如果勾选api也会创建对应信息 2021-07-12 14:53:25 +08:00
songzhibin97 e01a0aed49 fix:swagger 2021-07-12 11:37:33 +08:00
pixel 194c671ec0 Merge remote-tracking branch 'origin/gva_gormv2_dev' into gva_gormv2_dev 2021-07-12 09:49:34 +08:00
songzhibin97 14371c0e45 feat:增加查询api 2021-07-10 19:01:56 +08:00
songzhibin97 686163808d feat:回滚删除对应api 2021-07-10 18:47:23 +08:00
songzhibin97 76d38c1108 feat:回滚自动化生产代码 2021-07-10 17:39:24 +08:00
奇淼(piexlmax bbf6549490 Merge pull request #576 from flipped-aurora/gva_gormv2_dev
修复了closeTab不生效的bug
2021-07-10 17:16:48 +08:00
蒋吉兆 e2d13aa238 修复了closeTab不生效的bug 2021-07-10 16:20:57 +08:00
奇淼(piexlmax 1f4b265dbc Merge pull request #575 from SliverHorn/master
fix: config.yaml, config.docker.yaml
2021-07-10 14:36:19 +08:00
SliverHorn d520f84ba1 fix: config.yaml, config.docker.yaml 2021-07-10 14:17:40 +08:00
奇淼(piexlmax 8ce6c76a7b Merge pull request #574 from flipped-aurora/gva_gormv2_dev
fix eslint
2021-07-10 12:37:29 +08:00
蒋吉兆 7431457ebe fix eslint 2021-07-10 12:36:33 +08:00
奇淼(piexlmax c13acf641d Merge pull request #573 from flipped-aurora/gva_gormv2_dev
自动化代码可选项优化
2021-07-10 12:30:11 +08:00
蒋吉兆 073994bca7 自动化代码可选项优化 2021-07-10 12:28:52 +08:00
奇淼(piexlmax 34494b00ff v2.4.3发版
v2.4.3发版
2021-07-10 12:13:44 +08:00
蒋吉兆 3d6c0d2a14 调整项目编号 2021-07-10 12:11:48 +08:00
蒋吉兆 3271542a9b 修改上传图片相关bug 2021-07-10 12:08:28 +08:00
奇淼(piexlmax 44e7b643f9 Merge pull request #571 from flipped-aurora/master
分支版本合并
2021-07-10 11:26:02 +08:00
bypanghu@163.com 0683c99f00 change web/init on method , update web README 2021-07-10 11:11:13 +08:00
奇淼(piexlmax 0298d1df76 Merge pull request #548 from neo-6/NeoSunDevelop
[修复阿里云OSS图片上传路径不一致错误]
2021-07-10 11:06:10 +08:00
奇淼(piexlmax 0c4ca3ecb0 Merge pull request #569 from SliverHorn/master
update: 自定义gorm的logger优化
2021-07-10 11:04:22 +08:00
奇淼(piexlmax d5e5088778 Merge pull request #570 from SliverHorn/sliver_horn_gva_gormv2_dev_develop
update: server/README.md
2021-07-10 11:04:09 +08:00
SliverHorn d239aa1f1d update: server/README.md 2021-07-10 10:22:25 +08:00
SliverHorn a4623373a7 update: 自定义gorm的logger优化 2021-07-09 21:52:17 +08:00
pixel af595f9cf0 清理无用debugger 2021-07-09 18:49:06 +08:00
奇淼(piexlmax 2ac327acea Merge pull request #568 from flipped-aurora/gva_gormv2_dev
添加版权信息
2021-07-09 17:29:44 +08:00
pixel f112a056be 添加版权信息 2021-07-09 17:26:43 +08:00
奇淼(piexlmax c05cfada13 Merge pull request #567 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-07-09 16:13:55 +08:00
pixel 8f3291e6da 更新sync库版本 2021-07-09 16:01:10 +08:00
奇淼(piexlmax 488332c74d Merge pull request #566 from songzhibin97/gva_gormv2_dev
feat:增加singleFlight并发控制jwt颁发
2021-07-08 17:40:08 +08:00
songzhibin97 6b487a4afd feat:增加singleFlight并发控制jwt颁发 2021-07-07 19:32:05 +08:00
奇淼(piexlmax 6869c9350b Merge pull request #565 from JamieSlome/patch-1
Create SECURITY.md
2021-07-06 16:54:45 +08:00
Jamie Slome b7485f1335 Create SECURITY.md 2021-07-06 09:53:20 +01:00
奇淼(piexlmax 39badd53b1 Merge pull request #560 from iiiusky/fix/commentStyle
修改模板中的注释格式为官方推荐的格式
2021-07-05 10:37:03 +08:00
奇淼(piexlmax e8beb157b9 Merge pull request #563 from flipped-aurora/SliverHorn-patch-1
Update sys_api.go
2021-07-05 10:32:58 +08:00
SliverHorn 0ac3b20736 Update sys_api.go
修改文件
- server/model/sys_api.go
修复问题
- gorm tag 编写错误,使用分号进行分割,而不是写两个gorm tag
2021-07-04 16:01:20 +08:00
奇淼(piexlmax 377501efcf Merge pull request #561 from iiiusky/fix/autoCodeDesc
修改web页面代码生成部分描述信息
2021-07-03 11:37:28 +08:00
奇淼(piexlmax fd4072155b Merge pull request #562 from SliverHorn/master
update: README.md and README-en.md
2021-07-03 10:18:36 +08:00
SliverHorn e31ecc6852 update: README.md and README-en.md 2021-07-03 08:08:39 +08:00
SliverHorn d78185cb64 Update Dockerfile 2021-07-03 00:29:16 +08:00
SliverHorn 4260a2eab9 Update service.go.tpl
回参与入参,我觉得可以去掉,基本调用的时候都知道是什么类型,就没必要写了
2021-07-02 17:18:51 +08:00
sky c7781be21d fix: 修复字段生成代码中文件名称相关的描述信息 2021-07-02 17:03:49 +08:00
sky 73edd03aa4 fix: 修复字段生成代码中API相关的描述信息 2021-07-02 17:01:30 +08:00
sky 6f7a7b7d4c fix: 修改模板中的注释格式为官方推荐的格式.https://github.com/golang/go/wiki/CodeReviewComments#comment-sentences 2021-07-02 15:22:13 +08:00
奇淼(piexlmax 110fb33c24 Merge pull request #558 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-07-01 19:02:51 +08:00
pixel 57c6ba3624 修复了标签页右键点击事件被覆盖的bug
调整了左侧默认高度
2021-07-01 18:06:27 +08:00
奇淼(piexlmax fee7165079 Merge pull request #557 from bypanghu/master
add
2021-07-01 17:53:10 +08:00
奇淼(piexlmax 1cc5f53324 Merge pull request #555 from bbqi/master
fix: css中小疏漏rgba
2021-07-01 17:52:45 +08:00
Devil 17a95c45cc add 2021-07-01 17:42:01 +08:00
ipanghu 35a3b3e372 Merge pull request #1 from flipped-aurora/master
拉取代码
2021-07-01 17:17:17 +08:00
bbqi 362f1a5311 fix: css中小疏漏rgba 2021-06-30 14:47:31 +08:00
奇淼(piexlmax eb5298a6bd 修复特殊符号下初始化数据库时报错的bug
修复特殊符号下初始化数据库时报错的bug
2021-06-30 12:42:23 +08:00
pixel c9c8a4ff7a 修复特殊符号下初始化数据库时报错的bug 2021-06-30 12:37:48 +08:00
奇淼(piexlmax 07d7a518c6 Merge pull request #553 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-06-29 19:56:35 +08:00
pixel 4b7b07cd57 规范化px 2021-06-29 19:41:08 +08:00
pixel 4d383d53fe 清理编译warning 2021-06-29 19:24:01 +08:00
pixel c0dd212b41 统一样式调整 2021-06-29 19:16:28 +08:00
pixel 37993f3246 统一样式调整 2021-06-29 19:15:04 +08:00
pixel 13ea198fcd 改变主题色配置标签位置 2021-06-29 16:35:47 +08:00
pixel 7a68c5c6cf 暂时屏蔽运行时sass警告 2021-06-29 15:42:37 +08:00
pixel df75dae39d 主题色功能bug修复 2021-06-29 15:28:39 +08:00
pixel 4a39a2f81c 增加自定义皮肤功能 清理无用文件 2021-06-29 14:46:47 +08:00
奇淼(piexlmax e253ee0970 Merge pull request #552 from bypanghu/master
新增侧边栏修改主题
2021-06-29 10:22:07 +08:00
Devil 5599eeb9c9 init 2021-06-28 10:55:37 +08:00
Devil c90d04dbbd 前端新增修改侧边栏主题风格 2021-06-28 10:53:46 +08:00
奇淼(piexlmax 567256160e Merge pull request #551 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-06-28 09:54:04 +08:00
奇淼(piexlmax d0ad41c935 Merge pull request #550 from flipped-aurora/revert-546-gva_gormv2_dev
Revert "Gva gormv2 dev"
2021-06-27 16:30:27 +08:00
奇淼(piexlmax cc535b7a0d Revert "Gva gormv2 dev" 2021-06-27 16:30:17 +08:00
奇淼(piexlmax 40d75ce42a Merge pull request #549 from flipped-aurora/revert-544-master
Revert "新增网页侧边栏颜色配置,新增网页主题色配置"
2021-06-27 16:30:02 +08:00
奇淼(piexlmax 16cbb7a03e Revert "新增网页侧边栏颜色配置,新增网页主题色配置" 2021-06-27 16:29:24 +08:00
奇淼(piexlmax 440e13a07b Merge pull request #544 from bypanghu/master
新增网页侧边栏颜色配置,新增网页主题色配置
2021-06-27 15:00:36 +08:00
奇淼(piexlmax 6f8810ec60 Merge pull request #546 from songzhibin97/gva_gormv2_dev
Gva gormv2 dev
2021-06-27 14:59:41 +08:00
csnero fad9733802 [修复阿里云OSS图片上传路径不一致错误] 2021-06-26 20:54:12 +08:00
songzhibin97 8c9170d365 fix:uuid package 2021-06-26 13:56:50 +08:00
songzhibin97 dc79c106e2 feat:适配前端风格存储 2021-06-26 13:53:32 +08:00
Devil 84c430c819 修改侧边栏logo处的bug 2021-06-26 13:44:54 +08:00
ipanghu ca45b3ee01 Merge pull request #3 from flipped-aurora/master
拉取信息
2021-06-26 13:38:51 +08:00
Devil be640251c5 修改readme 2021-06-26 13:37:52 +08:00
Devil 0535f8b55f 修复vue.config.js 2021-06-26 13:34:18 +08:00
Devil 67dcec4c9a 修复logo随着主题色变化的bug 2021-06-26 13:32:42 +08:00
ipanghu 5ed1292503 Merge branch 'master' into master 2021-06-26 12:02:59 +08:00
Devil 9f5b59c4b5 前端新增可配置侧边栏风格,可以配置网页主题色 2021-06-25 17:24:02 +08:00
奇淼(piexlmax dfcf1609ed Merge pull request #542 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-06-25 15:29:08 +08:00
奇淼(piexlmax eb6175b2d5 Merge pull request #541 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-06-25 15:28:36 +08:00
pixel 74cff901c8 增加空menu的兼容 2021-06-25 12:15:12 +08:00
奇淼(piexlmax 04b3125894 Merge pull request #540 from flipped-aurora/develop
Develop
2021-06-24 17:40:14 +08:00
ipanghu 7e1348cb41 Merge pull request #2 from flipped-aurora/master
拉取请求
2021-06-24 15:59:35 +08:00
奇淼(piexlmax 1772c1ccfc Merge pull request #538 from songzhibin97/gva_gormv2_dev
fix:创建用户初始化权限,确保用户可用
2021-06-24 14:27:33 +08:00
songzhibin97 a2737af68f fix:添加id避免tree重复添加 2021-06-23 12:53:41 +08:00
奇淼(piexlmax ebf7a11ffb Merge pull request #539 from bstdn/develop
modified 统一代码风格
2021-06-23 12:37:05 +08:00
何秀钢 3af12113b2 modified 统一代码风格 2021-06-23 11:36:22 +08:00
pixel c044fcd2dd 文案调整 2021-06-23 10:46:54 +08:00
songzhibin97 a2551e86f4 fix:创建用户初始化权限,确保用户可用
修改了:
- server/api/v1/sys_authority.go
- server/model/request/sys_casbin.go
- server/model/request/sys_menu.go
2021-06-22 12:39:26 +08:00
奇淼(piexlmax ed926452f0 Merge pull request #531 from hxcode/develop
directory.go: fix os.MkdirAll return error
2021-06-21 19:11:35 +08:00
VUCA d824a6b7b0 Merge branch 'flipped-aurora:develop' into develop 2021-06-18 18:51:50 +08:00
奇淼(piexlmax 4cdc9ed6cd Merge pull request #535 from flipped-aurora/master
前端模板eslit修改
2021-06-17 19:57:26 +08:00
奇淼(piexlmax 93b373d37a Merge pull request #534 from flipped-aurora/gva_gormv2_dev
前端模板eslit修改
2021-06-17 19:56:29 +08:00
pixel deee053883 前端模板eslit修改 2021-06-17 19:52:31 +08:00
奇淼(piexlmax 38a5da1cd0 Merge pull request #533 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-06-17 17:11:51 +08:00
奇淼(piexlmax d4268e1a54 Merge pull request #532 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-06-17 17:09:39 +08:00
黄笑 ac0158605c directory.go: fix os.MkdirAll return error 2021-06-17 16:47:22 +08:00
pixel 4b159fe5f4 初始化流程整体优化,前端报错锁死的情况提供登出操作 2021-06-17 16:02:12 +08:00
pixel b99fe53c6b 初始化流程整体优化,前端报错锁死的情况提供登出操作 2021-06-17 15:54:32 +08:00
pixel da0d5d2413 更改初始化模式 2021-06-17 15:42:09 +08:00
pixel cb85f1c78a Merge branch 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into gva_gormv2_dev 2021-06-17 15:41:26 +08:00
奇淼(piexlmax 0371765357 Merge pull request #529 from flipped-aurora/develop
Develop
2021-06-17 15:33:22 +08:00
pixel 73ecd371df 初始化不再自动进行 2021-06-17 15:17:26 +08:00
奇淼(piexlmax 1907de840c Merge pull request #528 from hxcode/develop
aliyun_oss,qiniu,tencent_cos:  fix file open close
2021-06-17 15:15:48 +08:00
奇淼(piexlmax 2c29220645 Merge pull request #527 from songzhibin97/gva_gormv2_dev
perf:优化初始化流程
2021-06-17 15:14:08 +08:00
黄笑 04d7aa9ab4 aliyun_oss,qiniu,tencent_cos: fix file open close 2021-06-17 14:51:35 +08:00
pixel 2cffefcf1c 配置文件增加注释提示 2021-06-17 14:36:04 +08:00
pixel 74d6c237cd 自动生成文件名称修改为 前端为小驼峰 后端为下划线 2021-06-17 12:12:31 +08:00
songzhibin97 0cd3555904 perf:优化初始化流程
创建失败不更改config文件保持,前端保持在init界面
修改文件
- server/api/sys_initdb.go
- server/service/sys_initdb.go
2021-06-17 09:03:55 +08:00
奇淼(piexlmax 3eed60996e Merge pull request #525 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-06-16 17:00:07 +08:00
pixel f6865ba6ba 清理lock 2021-06-16 16:56:13 +08:00
pixel fc19b81104 前端环境变量文件规范化 2021-06-16 16:55:02 +08:00
奇淼(piexlmax 6b79d7c38d Merge pull request #521 from bypanghu/master
新增网站配置文件
2021-06-16 10:59:19 +08:00
奇淼(piexlmax 9364f2a24a Merge pull request #523 from hxcode/develop
exa_excel_parse.go: fix return err
2021-06-16 10:53:22 +08:00
黄笑 427294ec25 exa_excel_parse.go: fix return err 2021-06-15 15:05:04 +08:00
pixel 86bfa374bb 修复init初始化失败页面跳转到空白的错误
修复model模板string给予长度导致的初始化错误
2021-06-15 11:33:51 +08:00
bypanghu@163.com aac76dcd58 '添加gin-vue-admin的web配置文件,具体文件请看core/config文件' 2021-06-11 21:37:07 +08:00
ipanghu 5cc87c5b6c Merge pull request #1 from flipped-aurora/master
拉取master
2021-06-11 20:50:08 +08:00
奇淼(piexlmax c09533052d 修改node-sass为dart-sass
修改node-sass为dart-sass
2021-06-11 17:28:14 +08:00
奇淼(piexlmax e716a31880 Merge pull request #519 from flipped-aurora/gva_gormv2_dev
修改node-sass为dart-sass
2021-06-11 17:26:23 +08:00
pixel 7c3b0b9b8d Merge remote-tracking branch 'origin/gva_gormv2_dev' into gva_gormv2_dev
# Conflicts:
#	web/package-lock.json
2021-06-11 17:17:35 +08:00
奇淼(piexlmax 44c65a6812 login页面init页面美化
login页面init页面美化
2021-06-11 16:49:14 +08:00
奇淼(piexlmax bea9b5d04d login页面init页面美化
login页面init页面美化
2021-06-11 16:47:15 +08:00
奇淼(piexlmax 3de30b45ed 新版本的login 和 init页面
船新版本的login 和 init页面
2021-06-11 16:27:11 +08:00
Devil ca9579fa6d 全新init页面,适配手机页面,login页面新增logo 2021-06-11 16:22:31 +08:00
Devil 2c9b228eb5 全新init页面,提升用户体验 2021-06-11 16:15:10 +08:00
Devil a2b6bb37bf 新增新的login页面,适配手机端,老的login页面依旧存在 2021-06-11 15:04:56 +08:00
Devil 6943ccb7db 新增新的login页面,适配手机端,老的login页面依旧存在 2021-06-11 15:04:27 +08:00
奇淼(piexlmax 3b563252ff 合并更新至主干
合并更新至主干
2021-06-11 12:12:36 +08:00
奇淼(piexlmax f4e0aa8575 合并更新至主干
合并更新至主干
2021-06-11 12:10:39 +08:00
pixel 34808cae7a Merge branch 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into develop 2021-06-11 12:07:41 +08:00
pixel d9b7661946 格式化前端代码 2021-06-11 12:01:10 +08:00
奇淼(piexlmax f0369ecf18 整合gin-vue-admin前端框架引入组合,减少main.js代码
整合gin-vue-admin前端框架引入组合,减少main.js代码
2021-06-11 11:31:23 +08:00
奇淼(piexlmax 5a2fb90420 Merge pull request #512 from flipped-aurora/revert-508-master
Revert "增加sqlite数据库的初始化"
2021-06-11 11:14:37 +08:00
奇淼(piexlmax 6bf4a9943c Revert "增加sqlite数据库的初始化" 2021-06-11 11:14:17 +08:00
Devil b9e0a9e126 修复引入time_line的绝对路径错误 2021-06-11 11:04:49 +08:00
奇淼(piexlmax 8ec0eb5166 增加sqlite数据库的初始化
增加sqlite数据库的初始化
2021-06-11 10:56:38 +08:00
Devil f001b518f9 整合gin-vue-admin前端框架引入组合,减少main.js代码 2021-06-11 10:55:59 +08:00
奇淼(piexlmax 4c7c91a2d5 docker-compose 优化
docker-compose 优化
2021-06-11 10:52:20 +08:00
pixel ad785fb3e3 放弃node-sass 替换为 sass(dart-sass) 2021-06-11 10:41:20 +08:00
SliverHorn 8516dbbcaf update: docker-compose 优化 2021-06-10 22:05:14 +08:00
Arthur Liu 4902101cbe 增加sqlite数据库的初始化 2021-06-10 12:15:40 +08:00
奇淼(piexlmax 9b47c8f57c 依照eslint格式化
依照eslint格式化
2021-06-09 11:56:11 +08:00
pixel 1dbba19cac 依照eslint格式化 2021-06-08 12:22:46 +08:00
奇淼(piexlmax a9c9199bf4 规范化代码结构,提升系统使用便捷度。
规范化代码结构,提升系统使用便捷度。
2021-06-08 10:23:39 +08:00
奇淼(piexlmax a84433520d Merge pull request #504 from flipped-aurora/master
pr整理合并
2021-06-08 10:20:04 +08:00
奇淼(piexlmax 9aa34bff89 Merge pull request #503 from flipped-aurora/develop
pr合并
2021-06-08 10:15:14 +08:00
奇淼(piexlmax e4b177f5f7 Merge branch 'gva_gormv2_dev' into develop 2021-06-08 10:12:11 +08:00
奇淼(piexlmax a9946732a2 Merge pull request #497 from bstdn/master
modified 统一代码风格
2021-06-08 10:09:17 +08:00
奇淼(piexlmax 90f4c85034 Merge pull request #499 from bstdn/develop
added ESlint 语法检测
2021-06-08 10:08:35 +08:00
奇淼(piexlmax 72a6b2148f Merge pull request #501 from songzhibin97/gva_gormv2_dev
增加 go generate 懒人模式
2021-06-08 10:08:22 +08:00
奇淼(piexlmax ec393100d0 Merge pull request #500 from SliverHorn/master
fix: docker-compose windows 启动失败
2021-06-08 10:07:53 +08:00
奇淼(piexlmax f521e3fbc9 Merge pull request #502 from allinprogram/patch-1
Fix the inappropriate description
2021-06-08 10:07:41 +08:00
pixel 98a3e9abb2 增加预览代码全选和复制 2021-06-07 19:58:48 +08:00
allinprogram d83da1fa08 Fix the inappropriate description 2021-06-05 09:29:21 +08:00
songzhibin97 c082403868 增加 go generate 懒人模式 2021-06-03 14:44:28 +08:00
SliverHorn b708e70f8f fix: docker-compose 依赖sh命令启动 windows启动失败的bug 2021-06-03 11:44:26 +08:00
何秀钢 2f0465a1a1 added ESlint 语法检测 2021-06-02 14:11:45 +08:00
SliverHorn 3932a8fbf3 Merge branch 'master' of https://github.com/flipped-aurora/gin-vue-admin into develop 2021-06-01 16:32:50 +08:00
SliverHorn 1f4f5a9a2c Merge branch 'gva_gormv2_dev' of https://github.com/flipped-aurora/gin-vue-admin into develop 2021-06-01 16:32:42 +08:00
何秀钢 3ffe0d89d8 modified 统一代码风格 2021-06-01 16:20:46 +08:00
SliverHorn 747ffc43d9 Merge branch 'master' of https://github.com/flipped-aurora/gin-vue-admin into develop 2021-05-20 16:58:30 +08:00
奇淼(piexlmax aba0eeea80 Merge pull request #477 from flipped-aurora/gva_gormv2_dev
Gva gormv2 dev
2021-05-18 16:47:39 +08:00
340 changed files with 38631 additions and 26229 deletions
-88
View File
@@ -1,88 +0,0 @@
#! /bin/bash
rm -f ./config.yaml
# 生成config.yaml文件, 用于docker-compose的使用
touch ./config.yaml
filename="./config.yaml"
cat>"${filename}"<<EOF
# Gin-Vue-Admin Global Configuration
# jwt configuration
jwt:
signing-key: 'qmPlus'
expires-time: 604800
buffer-time: 86400
# zap logger configuration
zap:
level: 'info'
format: 'console'
prefix: '[GIN-VUE-ADMIN]'
director: 'log'
link-name: 'latest_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'
password: ''
# email configuration
email:
to: 'xxx@qq.com'
port: 465
from: 'xxx@163.com'
host: 'smtp.163.com'
is-ssl: true
secret: 'xxx'
nickname: 'test'
# casbin configuration
casbin:
model-path: './resource/rbac_model.conf'
# system configuration
system:
env: 'public' # Change to "develop" to skip authentication for development mode
addr: 8888
db-type: 'mysql'
oss-type: 'local'
use-multipoint: false
# captcha configuration
captcha:
key-long: 6
img-width: 240
img-height: 80
# mysql connect configuration
mysql:
path: ''
config: ''
db-name: ''
username: ''
password: ''
max-idle-conns: 10
max-open-conns: 100
log-mode: false
log-zap: ""
# local configuration
local:
path: 'uploads/file'
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu:
zone: 'ZoneHuadong'
bucket: 'qm-plus-img'
img-path: 'http://qmplusimg.henrongyi.top'
use-https: false
access-key: '25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
use-cdn-domains: false
EOF
-119
View File
@@ -1,119 +0,0 @@
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.pnp.*
**/node_modules
-41
View File
@@ -1,41 +0,0 @@
FROM golang:alpine as builder
RUN apk add --update --no-cache yarn make g++
RUN yarn global add cross-env node-sass
ENV GOPROXY=https://goproxy.cn,https://goproxy.io,direct \
GO111MODULE=on \
CGO_ENABLED=1
WORKDIR /go/src/gin-vue-admin
RUN go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct
COPY server/ ./
RUN go env && go list && go build -v -a -ldflags "-extldflags \"-static\" " -o gvadmin .
WORKDIR /web
COPY web/ ./
RUN yarn install && yarn run build
FROM nginx:alpine
LABEL MAINTAINER="rikugun"
RUN apk add --no-cache gettext tzdata && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && \
date && \
apk del tzdata
COPY docker/etc/nginx/nginx.conf.tpl /etc/nginx/nginx.conf.tpl
WORKDIR /app
#copy web
COPY --from=builder /web/dist/ /var/www/
#copy go app
COPY --from=builder /go/src/gin-vue-admin/gvadmin ./
COPY --from=builder /go/src/gin-vue-admin/db.db ./
COPY --from=builder /go/src/gin-vue-admin/config.yaml ./
COPY --from=builder /go/src/gin-vue-admin/resource ./resource
COPY docker/docker-start.sh ./
ENV API_SERVER="http://localhost:8888/"
EXPOSE 80
ENTRYPOINT ["./docker-start.sh"]
+106 -173
View File
@@ -3,36 +3,43 @@
<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.12-blue"/>
<img src="https://img.shields.io/badge/gin-1.4.0-lightBlue"/>
<img src="https://img.shields.io/badge/golang-1.14-blue"/>
<img src="https://img.shields.io/badge/gin-1.6.3-lightBlue"/>
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen"/>
<img src="https://img.shields.io/badge/element--ui-2.12.0-green"/>
<img src="https://img.shields.io/badge/gorm-1.9.12-red"/>
<img src="https://img.shields.io/badge/gorm-1.20.7-red"/>
</div>
English | [简体中文](./README.md)
[gitee](https://gitee.com/pixelmax/gin-vue-admin): https://gitee.com/pixelmax/gin-vue-admin
[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>)
- Web UI Framework:[element-ui](https://github.com/ElemeFE/element)
- Server Framework:[gin](https://github.com/gin-gonic/gin)
## 1. Basic Introduction
### 1.1 Project Introduction
[Online Demo](http://demo.gin-vue-admin.com/)
> Gin-vue-admin is a backstage management system based on [vue](https://vuejs.org) and [gin](https://gin-gonic.com), which separates the front and rear of the full stack. It integrates jwt authentication, dynamic routing, dynamic menu, casbin authentication, form generator, code generator and other functions. It provides a variety of sample files, allowing you to focus more time on business development.
[Online Demo](http://demo.gin-vue-admin.com): http://demo.gin-vue-admin.com
username:admin
password:123456
> Gin-vue-admin is a full-stack (frontend and backend separation) framework designed for management system.
> It integrates multiple functions, such as JWT authentication, dynamic routing, dynamic menu, casbin authentication, form generator, code generator, etc. So that you can focus more time on your business Requirements.
### 1.2 Contributing Guide
Hi! Thank you for choosing gin-vue-admin.
@@ -40,7 +47,6 @@ Gin-vue-admin is a full-stack (frontend and backend separation) framework for de
We are excited that you are interested in contributing to gin-vue-admin. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines.
### 1.2 Contributing Guide
#### 1.2.1 Issue Guidelines
- Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly. If any questions come up when you are using Element, please hit [Gitter](https://gitter.im/element-en/Lobby) for help.
@@ -72,81 +78,34 @@ We are excited that you are interested in contributing to gin-vue-admin. Before
- node version > v8.6.0
- golang version >= v1.14
- IDE recommendation: Goland
- We recommend you to apply for your own cloud service in QINIU. Replace the public key, private key, warehouse name and default url address with your own, so as not to mess up the test database.
- initialization project: different versions of the database are not initialized. See synonyms at initialization https://www.gin-vue-admin.com/docs/first
- Replace the Qiniuyun public key, private key, warehouse name and default url address in the project to avoid data confusion in the test file.
```
> Use docker-compose to experience this project
- Installation docker-compose [Official document](https://docs.docker.com/compose/install/)
- ```shell script
# Install on Linux
# 1.1 Run this command to download the current stable version of Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 1.2 Apply executable permissions to binary files
sudo chmod +x /usr/local/bin/docker-compose
```
- ```shell script
# Use Python's pip installation
pip3 install docker-compose -i https://pypi.tuna.tsinghua.edu.cn/simple
```
- Use Docker Desktop
- Windows: https://hub.docker.com/editions/community/docker-ce-desktop-windows
- Mac: https://hub.docker.com/editions/community/docker-ce-desktop-mac/
### 2.1 server project
- Use git to clone this project
- ```git
git clone https://github.com/flipped-aurora/gin-vue-admin.git
```
- Use docker-compose up to start the startup project with one click
- ```shell script
# Use docker-compose to start four containers
docker-compose up
# If you modify some configuration options, you can use this command to repackage the image
docker-compose up --build
# Use docker-compose to start in the background
docker-compose up -d
```
- Web project preview [http://127.0.0.1:8000](http://127.0.0.1:8000)
- swagger APIs [http://127.0.0.1:8888/swagger/index.html](http://127.0.0.1:8888/swagger/index.html)
- If the internal ip of the server's 177.7.0.12 container is occupied, the place to be modified is
- Replace 177.7.0.12 on line 39 of [docker-compose.yaml](./docker-compose.yaml) with the ip you want
- Replace 177.7.0.12 in line 20 of [.docker-compose/nginx/conf.d/my.conf](./.docker-compose/nginx/conf.d/my.conf) with the ip you want
- docker-compose uses a custom docker network
- ```dockerfile
networks:
network:
ipam:
driver: default
config:
- subnet: '177.7.0.0/16'
```
- Subnet address, the default gateway is 177.7.0.1 (docker-compose V2 needs to write, V3 does not need),For specific information, see the [official document](https://docs.docker.com/compose/compose-file/#ipv4_address-ipv6_address)
- The default network name is gin-vue-admin_network, and the default is bridge mode
- If the subnet is modified, the ipv4_address of each service needs to be modified, and the ip of the server on line 20 of [.docker-compose/nginx/conf.d/my.conf](.docker-compose/nginx/conf.d/my.conf) also needs to be modified
> <font color=red>**Use docker-compose to deploy this project need attention**</font>
- For mysql database, please use a local database installed on the server disk.
- Avoid using mysql in the docker container, there may be write problems, io is lower than the host machine, docker's persistence mechanism problem
- [init.sql](.docker-compose/docker-entrypoint-initdb.d/init.sql) is for docker-compose ==experience this project==, prohibit the use of [init.sql](.docker-compose/docker-entrypoint-initdb.d/init.sql) to initialize project data, Database initialization[Please use this method](https://www.gin-vue-admin.com/docs/help#step1%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E5%88%9D%E5%A7%8B%E5%8C%96)
- Use [init.sql](.docker-compose/docker-entrypoint-initdb.d/init.sql) to initialize all problems, please bear it yourself, and have nothing to do with this project
- When deploying using docker-compose of this project,Please modify the [nginx configuration](.docker-compose/nginx/conf.d/my.conf), mysql configuration, networks configuration, redis configuration corresponding to [docker-compose.yaml](./docker-compose.yaml), and make changes as needed.
### 2.1 Web
use `Goland` And other editing tools,open server catalogue,You can't open it. `gin-vue-admin` root directory
```bash
# clone the project
git clone https://github.com/piexlmax/gin-vue-admin.git
git clone https://github.com/flipped-aurora/gin-vue-admin.git
# open server catalogue
cd server
# use go mod And install the go dependency package
go generate
# Compile
go build -o server main.go (windows the compile command is go build -o server.exe main.go )
# Run binary
./server (windows The run command is server.exe)
```
### 2.1 web project
```bash
# enter the project directory
cd web
@@ -169,47 +128,6 @@ go list (go mod tidy)
go build
```
> Zap log library usage guide && configuration guide
The configuration of the Zap log library selects zap under [config.yaml](./server/config.yaml)
```yaml
# zap logger configuration
zap:
level: 'debug'
format: 'console'
prefix: '[GIN-VUE-ADMIN]'
director: 'log'
link_name: 'latest_log'
show_line: true
encode_level: 'LowercaseColorLevelEncoder'
stacktrace_key: 'stacktrace'
log_in_console: true
```
| Configuration Name | Type Of Configuration | Description |
| ------------------ | --------------------- | ------------------------------------------------------------ |
| level | string | For a detailed description of the level mode, please see the official [zap documentation](https://pkg.go.dev/go.uber.org/zap?tab=doc#pkg-constants) <br />info: info mode, stack information without errors, only output information<br />debug: debug mode, stack details with errors<br />warn:warn mode<br />error: error mode, stack details with error<br />dpanic: dpanic mode<br />panic: panic mode<br />fatal: fatal mode<br /> |
| format | string | console: Output log in console format<br />json: json format output log |
| prefix | string | Log prefix |
| director | string | The folder to store the log can be modified, no need to create it manually |
| link_name | string | [A soft connection file](https://baike.baidu.com/item/%E8%BD%AF%E9%93%BE%E6%8E%A5) of link_name will be generated in the server directory, and the link is the latest log file of the director configuration item |
| show_line | bool | Display the line number, the default is true, it is not recommended to modify |
| encode_level | string | LowercaseLevelEncoder: lowercase<br /> LowercaseColorLevelEncoder: lowercase with color<br />CapitalLevelEncoder: uppercase<br />CapitalColorLevelEncoder: uppercase with color |
| stacktrace_key | string | The name of the stack, that is, the key of josn when outputting the log in json format |
| log_in_console | bool | Whether to output to the console, the default is true |
- Development environment || Debug environment configuration recommendations
- `level:debug`
- `format:console`
- `encode_level:LowercaseColorLevelEncoder`或者`encode_leve:CapitalColorLevelEncoder`
- Deployment environment configuration recommendations
- `level:error`
- `format:json`
- `encode_level: LowercaseLevelEncoder `或者 `encode_level:CapitalLevelEncoder`
- `log_in_console: false`
- <font color=red>Suggestions are only suggestions, you can proceed according to your own needs, and suggestions are for reference only</font>
### 2.3 API docs auto-generation using swagger
#### 2.3.1 install swagger
@@ -221,19 +139,20 @@ go get -u github.com/swaggo/swag/cmd/swag
##### (2) In mainland China
In mainland China, access to go.org/x is prohibited,we recommend [goproxy.io](https://goproxy.io/zh/)
In mainland China, access to go.org/x is prohibited,we recommend [goproxy.io](https://goproxy.io/zh/) or [goproxy.cn](https://goproxy.cn)
````bash
If you are using Go version 1.13 and above (recommended)
# Enable Go Modules function
# If you are using a version of Go 1.13 - 1.15 Need to set up manually GO111MODULE=on, The opening mode is as follows, If your Go version is 1.16 ~ Latest edition You can ignore the following step one
# Step one、Enable Go Modules Function
go env -w GO111MODULE=on
# Configure GOPROXY environment variables
go env -w GOPROXY=https://goproxy.io,direct
If you are using Go version 1.12 and below
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io
# Step two、Configuration GOPROXY Environment variable
go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct
# Use the following command to download swag
# If you dislike trouble,You can use the go generate Automatically execute code before compilation, But this can't be used command line terminal of `Goland` or `Vscode`
cd server
go generate -run "go env -w .*?"
# 使用如下命令下载swag
go get -u github.com/swaggo/swag/cmd/swag
````
@@ -243,18 +162,19 @@ go get -u github.com/swaggo/swag/cmd/swag
cd server
swag init
````
After executing the above command,`docs` will show in `server/`,then open your browser, jump into `http://localhost:8888/swagger/index.html` to see the swagger APIs.
> After executing the above command,server directory will appear in the docs folder `docs.go`, `swagger.json`, `swagger.yaml` Three file updates,After starting the go service, type in the browser [http://localhost:8888/swagger/index.html](http://localhost:8888/swagger/index.html) You can view swagger document
## 3. Technical selection
- Frontend: using `Element-UI` based on vue,to code the page.
- Backend: using `Gin` to quickly build basic RESTful API. `Gin` is a web framework written in Go (Golang).
- DB: `MySql`(5.6.44),using `gorm` to implement data manipulation, added support for SQLite databases.
- Frontend: using [Element](https://github.com/ElemeFE/element) based on [Vue](https://vuejs.org),to code the page.
- Backend: using [Gin](https://gin-gonic.com/) to quickly build basic RESTful API. [Gin](https://gin-gonic.com/)is a web framework written in Go (Golang).
- DB: `MySql`(5.6.44),using [gorm](http://gorm.io)` to implement data manipulation, added support for SQLite databases.
- Cache: using `Redis` to implement the recording of the JWT token of the currently active user and implement the multi-login restriction.
- API: using Swagger to auto generate APIs docs。
- Config: using `fsnotify` and `viper` to implement `yaml` config file。
- Log: using `go-logging` record logs。
- Config: using [fsnotify](https://github.com/fsnotify/fsnotify) and [viper](https://github.com/spf13/viper) to implement `yaml` config file。
- Log: using [zap](https://github.com/uber-go/zap) record logs。
## 4. Project Architecture
@@ -269,19 +189,31 @@ After executing the above command,`docs` will show in `server/`,then open yo
### 4.3 Project Layout
```
├─server (backend)
│ ├─api (API entrance)
│ ├─config (config file)
│ ├─core (core code)
│ ├─docs (swagger APIs docs)
│ ├─global (global objet)
│ ├─initialiaze (initialiazation)
│ ├─middleware (middle ware)
│ ├─model (model and services)
│ ├─resource (resources, such as static pages, templates)
│ ├─router (routers)
│ ├─service (services)
│ └─utils (common utilities)
├── server
├── api (api entrance)
│ └── v1 (v1 version interface)
├── config (configuration package)
├── core (core document)
├── docs (swagger document directory)
├── global (global object)
├── initialize (initialization)
│ └── internal (initialize internal function)
├── middleware (middleware layer)
├── model (model layer)
│ ├── request (input parameter structure)
│ └── response (out-of-parameter structure)
├── packfile (static file packaging)
├── resource (static resource folder)
│ ├── excel (excel import and export default path)
│ ├── page (form generator)
│ └── template (template)
├── router (routing layer)
├── service (service layer)
├── source (source layer)
└── utils (tool kit)
├── timer (timer interface encapsulation)
└── upload (oss interface encapsulation)
└─web (frontend)
├─public (deploy templates)
└─src (source code)
@@ -299,58 +231,59 @@ After executing the above command,`docs` will show in `server/`,then open yo
## 5. Features
- Authority management: Authority management based on `jwt` and `casbin`.
- File upload & download: File upload operation based on Qiniu Cloud (In order to make it easier for everyone to test, I have provided various important tokens of my Qiniu test number, and I urge you not to make things a mess).
- Pagination Encapsulation:The frontend uses mixins to encapsulate paging, and the paging method can call mixins
- File upload and download: implement file upload operations based on `Qiniuyun', `Aliyun 'and `Tencent Cloud` (please develop your own application for each platform corresponding to `token` or `key` ).
- Pagination Encapsulation:The frontend uses `mixins` to encapsulate paging, and the paging method can call `mixins` .
- User management: The system administrator assigns user roles and role permissions.
- Role management: Create the main object of permission control, and then assign different API permissions and menu permissions to the role.
- Menu management: User dynamic menu configuration implementation, assigning different menus to different roles.
- API management: Different users can call different API permissions.
- Configuration management: The configuration file can be modified in the web page (the test environment does not provide this function).
- Rich text editor: Embed MarkDown editor function.
- Configuration management: the configuration file can be modified in the foreground (this feature is not available in the online experience site).
- Conditional search: Add an example of conditional search.
- Restful example: You can see sample APIs in user management module.
```
fontend code file: src\view\superAdmin\api\api.vue
backend code file: model\dnModel\api.go
```
- Multi-login restriction: Change `userMultipoint` to true in `system` in `config.yaml` (You need to configure redis and redis parameters yourself. During the test period, please report in time if there is a bug).
- Front-end file reference: [web/src/view/superAdmin/api/api.vue](https://github.com/flipped-aurora/gin-vue-admin/blob/master/web/src/view/superAdmin/api/api.vue).
- Stage reference: [server/router/sys_api.go](https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/router/sys_api.go).
- Multi-login restriction: Change `user-multipoint` to true in `system` in `config.yaml` (You need to configure redis and redis parameters yourself. During the test period, please report in time if there is a bug).
- Upload file by chunk:Provides examples of file upload and large file upload by chunk.
- Form Builder:With the help of [@form-generator](https://github.com/JakHuang/form-generator).
- Code generator: Providing backend with basic logic and simple curd code generator.
## 6. To-do list
## 6. Knowledge base
- [ ] upload & export Excel
- [ ] e-chart
- [ ] workflow, task transfer function
- [ ] frontend independent mode, mock
## 7. Knowledge base
### 7.1 Team blog
### 6.1 Team blog
> https://www.yuque.com/flipped-aurora
>
>There are video courses about frontend framework in our blo. If you think the project is helpful to you, you can add my personal WeChat:shouzi_1994,your comments is welcomed。
### 7.2 Video courses
### 6.2 Video courses
(1) Development environment course
> Bilibili:https://www.bilibili.com/video/BV1Fg4y187Bw/
(2) Template course
> Bilibili:https://www.bilibili.com/video/BV16K4y1r7BD/
(3)2.0 version introduction and development experience
(3) 2.0 version introduction and development experience
> Bilibili:https://www.bilibili.com/video/BV1aV411d7Gm#reply2831798461
(4) Golang basic course (coming soon)
(4) Golang basic course
> https://space.bilibili.com/322210472/channel/detail?cid=108884
## 8. Contacts
### 8.1 Groups
(5) gin frame basic teaching
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=126418&ctype=0
(6) gin-vue-admin version update introduction video
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=126418&ctype=0
## 7.Contacts
### 7.1 Groups
#### QQ group: 622360840
| QQ group |d
@@ -366,11 +299,11 @@ backend code file: model\dnModel\api.go
#### [About Us](https://www.gin-vue-admin.com/about/)
## 9. Donate
## 8. 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)
## 10. Commercial considerations
## 9. Commercial considerations
If you use this project for commercial purposes, please comply with the Apache2.0 agreement and retain the author's technical support statement.
+114 -198
View File
@@ -3,44 +3,42 @@
<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.12-blue"/>
<img src="https://img.shields.io/badge/gin-1.4.0-lightBlue"/>
<img src="https://img.shields.io/badge/golang-1.14-blue"/>
<img src="https://img.shields.io/badge/gin-1.6.3-lightBlue"/>
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen"/>
<img src="https://img.shields.io/badge/element--ui-2.12.0-green"/>
<img src="https://img.shields.io/badge/gorm-1.9.12-red"/>
<img src="https://img.shields.io/badge/gorm-1.20.7-red"/>
</div>
[English](./README-en.md) | 简体中文
[gitee地址:https://gitee.com/pixelmax/gin-vue-admin](https://gitee.com/pixelmax/gin-vue-admin)
[gitee地址](https://gitee.com/pixelmax/gin-vue-admin): https://gitee.com/pixelmax/gin-vue-admin
[github地址:https://github.com/flipped-aurora/gin-vue-admin](https://github.com/flipped-aurora/gin-vue-admin)
[github地址](https://github.com/flipped-aurora/gin-vue-admin): https://github.com/flipped-aurora/gin-vue-admin
[vue3版本分支地址:https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop](https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop)
[vue3版本分支地址](https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop): https://github.com/flipped-aurora/gin-vue-admin/tree/vue3Develop
[审批流分支:https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow](https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow)
[审批流分支](https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow): https://github.com/flipped-aurora/gin-vue-admin/tree/gva_workflow
# 项目文档
[在线文档](https://www.gin-vue-admin.com/) : https://www.gin-vue-admin.com/
[在线文档](https://www.gin-vue-admin.com) : https://www.gin-vue-admin.com
[从环境到部署教学视频](https://www.bilibili.com/video/BV1fV411y7dT)
[开发教学](https://www.gin-vue-admin.com/docs/help) (贡献者: <a href="https://github.com/LLemonGreen">LLemonGreen</a> And <a href="https://github.com/fkk0509">Fann</a>)
- 前端UI框架:[element-ui](https://github.com/ElemeFE/element)
- 后台框架:[gin](https://github.com/gin-gonic/gin)
## 1. 基本介绍
### 1.1 项目介绍
[在线预览](http://demo.gin-vue-admin.com/)
> Gin-vue-admin是一个基于 [vue](https://vuejs.org) 和 [gin](https://gin-gonic.com) 开发的全栈前后端分离的后台管理系统,集成jwt鉴权,动态路由,动态菜单,casbin鉴权,表单生成器,代码生成器等功能,提供多种示例文件,让您把更多时间专注在业务开发上。
[在线预览](http://demo.gin-vue-admin.com): http://demo.gin-vue-admin.com
测试用户名:admin
测试密码:123456
> Gin-vue-admin是一个基于vue和gin开发的全栈前后端分离的后台管理系统,集成jwt鉴权,动态路由,动态菜单,casbin鉴权,表单生成器,代码生成器等功能,提供多种示例文件,让您把更多时间专注在业务开发上。
### 1.2 贡献指南
Hi! 首先感谢你使用 gin-vue-admin。
@@ -77,167 +75,68 @@ Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-adm
- node版本 > v8.6.0
- golang版本 >= v1.14
- IDE推荐:Goland
- 初始化项目: 不同版本数据库初始化不通 参见https://www.gin-vue-admin.com/docs/server#1-%E5%88%9D%E5%A7%8B%E5%8C%96server%E9%A1%B9%E7%9B%AE
- 初始化项目: 不同版本数据库初始化不通 参见 https://www.gin-vue-admin.com/docs/first
- 替换掉项目中的七牛云公钥,私钥,仓名和默认url地址,以免发生测试文件数据错乱
```
> 使用docker-compose体验本项目
- 安装 docker-compose [官方文档](https://docs.docker.com/compose/install/)
- ```shell script
# 在Linux安装
# 1.1 运行此命令以下载Docker Compose的当前稳定版本
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 1.2 将可执行权限应用于二进制文件
sudo chmod +x /usr/local/bin/docker-compose
```
- ```shell script
# 使用Python的pip安装
pip3 install docker-compose -i https://pypi.tuna.tsinghua.edu.cn/simple
```
- 使用 Docker Desktop
- Windows: https://hub.docker.com/editions/community/docker-ce-desktop-windows
- Mac: https://hub.docker.com/editions/community/docker-ce-desktop-mac/
### 2.1 server项目
- 使用git克隆本项目
- ```git
git clone https://github.com/flipped-aurora/gin-vue-admin.git
```
- 使用docker-compose up一键启动启动项目
- ```shell script
# 使用docker-compose启动四个容器
docker-compose up
# 如果您修改了某些配置选项,可以使用此命令重新打包镜像
docker-compose up --build
# 使用docker-compose 后台启动
docker-compose up -d
```
- web项目预览 [http://127.0.0.1:8000](http://127.0.0.1:8000)
- swagger文档 [http://127.0.0.1:8888/swagger/index.html](http://127.0.0.1:8888/swagger/index.html)
- 如果server的177.7.0.12这个容器内部ip被占用了,需要修改地方为
- [docker-compose.yaml](./docker-compose.yaml)的第39行的177.7.0.12更换为你想要的ip
- [.docker-compose/nginx/conf.d/my.conf](./.docker-compose/nginx/conf.d/my.conf)的第20行的177.7.0.12更换为你想要的ip
- docker-compose使用自定义的一个docker网络
- ```dockerfile
networks:
network:
ipam:
driver: default
config:
- subnet: '177.7.0.0/16'
```
- 子网地址, 默认网关是177.7.0.1(docker-compose V2需要写,V3则不需要),具体信息看[官方文档](https://docs.docker.com/compose/compose-file/#ipv4_address-ipv6_address)
- 默认的network名为gin-vue-admin_network,默认是bridge模式
- 如果修改了子网,对应的每个service的ipv4_address都需要修改,还有[.docker-compose/nginx/conf.d/my.conf](./.docker-compose/nginx/conf.d/my.conf)的第20行的server的ip也需要修改
> <font color=red>**使用docker-compose进行部署本项目需注意的问题**</font>
- dockerfile_server使用了多阶段构建,这是docker 17.05后引入的,因此安装的docker版本需要高于17.05
- mysql数据库请使用装在服务器磁盘的本地数据库.
- 避免使用docker容器内的mysql,可能会出现写入的问题, io比宿主机低 docker的持久化机制问题
- [init.sql](.docker-compose/docker-entrypoint-initdb.d/init.sql)是给docker-compose进行<font color=red>体验本项目</font>的, 禁止[init.sql](.docker-compose/docker-entrypoint-initdb.d/init.sql)使用进行项目数据的初始化, 数据库初始化[请使用此方法](https://www.gin-vue-admin.com/docs/help#step1%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E5%88%9D%E5%A7%8B%E5%8C%96)
- 使用[init.sql](.docker-compose/docker-entrypoint-initdb.d/init.sql)进行初始化出现的所有问题,请自行承担,与本项目无关
- 使用本项目的docker-compose进行部署时,请修改[docker-compose.yaml](./docker-compose.yaml)对应的[nginx配置](.docker-compose/nginx/conf.d/my.conf),mysql配置,networks配置,redis配置,按需自行更改.
### 2.1 web端
使用 `Goland` 等编辑工具,打开server目录,不可以打开 gin-vue-admin 根目录
```bash
# clone the project
git clone https://github.com/piexlmax/gin-vue-admin.git
# enter the project directory
# 克隆项目
git clone https://github.com/flipped-aurora/gin-vue-admin.git
# 进入server文件夹
cd server
# 使用 go mod 并安装go依赖包
go generate
# 编译
go build -o server main.go (windows编译命令为go build -o server.exe main.go )
# 运行二进制
./server (windows运行命令为 server.exe)
```
### 2.2 web项目
```bash
# 进入web文件夹
cd web
# install dependency
npm install
# 安装依赖
cnpm install || npm install
# develop
# 启动web项目
npm run serve
```
### 2.2 server端
使用 goland等编辑工具,打开server目录,不可以打开 gin-vue-admin 根目录
```bash
# 使用 go.mod
# 安装go依赖包
go list (go mod tidy)
# 编译
go build
```
> Zap日志库使用指南&&配置指南
Zap日志库的配置选择在[config.yaml](./server/config.yaml)下的zap
```yaml
# zap logger configuration
zap:
level: 'debug'
format: 'console'
prefix: '[GIN-VUE-ADMIN]'
director: 'log'
link_name: 'latest_log'
show_line: true
encode_level: 'LowercaseColorLevelEncoder'
stacktrace_key: 'stacktrace'
log_in_console: true
```
| 配置名 | 配置的类型 | 说明 |
| -------------- | ---------- | ------------------------------------------------------------ |
| level | string | level的模式的详细说明,请看[zap官方文档](https://pkg.go.dev/go.uber.org/zap?tab=doc#pkg-constants) <br />info: info模式,无错误的堆栈信息,只输出信息<br />debug:debug模式,有错误的堆栈详细信息<br />warn:warn模式<br />error: error模式,有错误的堆栈详细信息<br />dpanic: dpanic模式<br />panic: panic模式<br />fatal: fatal模式<br /> |
| format | string | console: 控制台形式输出日志<br />json: json格式输出日志 |
| prefix | string | 日志的前缀 |
| director | string | 存放日志的文件夹,修改即可,不需要手动创建 |
| link_name | string | 在server目录下会生成一个link_name的[软连接文件](https://baike.baidu.com/item/%E8%BD%AF%E9%93%BE%E6%8E%A5),链接的是director配置项的最新日志文件 |
| show_line | bool | 显示行号, 默认为true,不建议修改 |
| encode_level | string | LowercaseLevelEncoder:小写<br /> LowercaseColorLevelEncoder:小写带颜色<br />CapitalLevelEncoder: 大写<br />CapitalColorLevelEncoder: 大写带颜色 |
| stacktrace_key | string | 堆栈的名称,即在json格式输出日志时的josn的key |
| log_in_console | bool | 是否输出到控制台,默认为true |
- 开发环境 || 调试环境配置建议
- `level:debug`
- `format:console`
- `encode_level:LowercaseColorLevelEncoder`或者`encode_leve:CapitalColorLevelEncoder`
- 部署环境配置建议
- `level:error`
- `format:json`
- `encode_level: LowercaseLevelEncoder `或者 `encode_level:CapitalLevelEncoder`
- `log_in_console: false`
- <font color=red>建议只是建议,按照自己的需求进行即可,给出建议仅供参考</font>
### 2.3 swagger自动化API文档
#### 2.3.1 安装 swagger
##### (1)可以访问外国网站
````
go get -u github.com/swaggo/swag/cmd/swag
````
##### (2)无法访问外国网站
由于国内没法安装 go.org/x 包下面的东西,推荐使用 [goproxy.io](https://goproxy.io/zh/)
由于国内没法安装 go.org/x 包下面的东西,推荐使用 [goproxy.cn](https://goproxy.cn) 或者 [goproxy.io](https://goproxy.io/zh/)
```bash
如果您使用的 Go 版本是 1.13 及以上(推荐)
# 启用 Go Modules 功能
# 如果您使用的 Go 版本是 1.13 - 1.15 需要手动设置GO111MODULE=on, 开启方式如下命令, 如果你的 Go 版本 是 1.16 ~ 最新版 可以忽略以下步骤一
# 步骤一、启用 Go Modules 功能
go env -w GO111MODULE=on
# 配置 GOPROXY 环境变量
go env -w GOPROXY=https://goproxy.io,direct
# 步骤二、配置 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
@@ -245,25 +144,26 @@ go get -u github.com/swaggo/swag/cmd/swag
#### 2.3.2 生成API文档
````
```` shell
cd server
swag init
````
执行上面的命令后,server目录下会出现docs文件夹,登录 http://localhost:8888/swagger/index.html ,即可查看swagger文档
> 执行上面的命令后,server目录下会出现docs文件夹里的 `docs.go`, `swagger.json`, `swagger.yaml` 三个文件更新,启动go服务之后, 在浏览器输入 [http://localhost:8888/swagger/index.html](http://localhost:8888/swagger/index.html) 即可查看swagger文档
## 3. 技术选型
- 前端:用基于`vue`的`Element-UI`构建基础页面。
- 后端:用`Gin`快速搭建基础restful风格API,`Gin`是一个go语言编写的Web框架。
- 数据库:采用`MySql`(5.6.44)版本,使用`gorm`实现对数据库的基本操作,已添加对sqlite数据库的支持。
- 前端:用基于 [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) 实现对数据库的基本操作。
- 缓存:使用`Redis`实现记录当前活跃用户的`jwt`令牌并实现多点登录限制。
- API文档:使用`Swagger`构建自动化文档。
- 配置文件:使用`fsnotify`和`viper`实现`yaml`格式的配置文件。
- 日志:使用`go-logging`实现日志记录。
- 配置文件:使用 [fsnotify](https://github.com/fsnotify/fsnotify) 和 [viper](https://github.com/spf13/viper) 实现`yaml`格式的配置文件。
- 日志:使用 [zap](https://github.com/uber-go/zap) 实现日志记录。
## 4. 项目架构
### 4.1 系统架构图
![系统架构图](http://qmplusimg.henrongyi.top/gva/gin-vue-admin.png)
@@ -275,19 +175,31 @@ swag init
### 4.3 目录结构
```
├─server (后端文件夹)
│ ├─api (API)
│ ├─config (配置包)
│ ├─core (內核)
│ ├─docs (swagger文档目录)
│ ├─global (全局对象)
│ ├─initialiaze (初始化)
│ ├─middleware (中间件)
│ ├─model (结构体层)
│ ├─resource (资源)
│ ├─router (路由)
│ ├─service (服务)
│ └─utils (公共功能)
├── server
├── api (api层)
│ └── v1 (v1版本接口)
├── config (配置包)
├── core (核心文件)
├── docs (swagger文档目录)
├── global (全局对象)
├── initialize (初始化)
│ └── internal (初始化内部函数)
├── middleware (中间件层)
├── model (模型层)
│ ├── request (入参结构体)
│ └── response (出参结构体)
├── packfile (静态文件打包)
├── resource (静态资源文件夹)
│ ├── excel (excel导入导出默认路径)
│ ├── page (表单生成器)
│ └── template (模板)
├── router (路由层)
├── service (service层)
├── source (source层)
└── utils (工具包)
├── timer (定时器接口封装)
└── upload (oss接口封装)
└─web (前端文件)
├─public (发布模板)
└─src (源码包)
@@ -304,56 +216,60 @@ swag init
## 5. 主要功能
- 权限管理:基于`jwt`和`casbin`实现的权限管理
- 文件上传下载:实现基于七牛云的文件上传操作(为了方便大家测试,我公开了自己的七牛测试号的各种重要token,恳请大家不要乱传东西)
- 分页封装:前端使用mixins封装分页,分页方法调用mixins即可
- 权限管理:基于`jwt`和`casbin`实现的权限管理。
- 文件上传下载:实现基于`七牛云`, `阿里云`, `腾讯云` 的文件上传操作(请开发自己去各个平台的申请对应 `token` 或者对应`key`)。
- 分页封装:前端使用 `mixins` 封装分页,分页方法调用 `mixins` 即可。
- 用户管理:系统管理员分配用户角色和角色权限。
- 角色管理:创建权限控制的主要对象,可以给角色分配不同api权限和菜单权限。
- 菜单管理:实现用户动态菜单配置,实现不同角色不同菜单。
- api管理:不同用户可调用的api接口的权限不同。
- 配置管理:配置文件可前台修改(测试环境不开放此功能)。
- 富文本编辑器:MarkDown编辑器功能嵌入。
- 配置管理:配置文件可前台修改(在线体验站点不开放此功能)。
- 条件搜索:增加条件搜索示例。
- restful示例:可以参考用户管理模块中的示例API。
```
前端文件参考: src\view\superAdmin\api\api.vue
后台文件参考: model\dnModel\api.go
```
- 多点登录限制:需要在`config.yaml`中把`system`中的`useMultipoint`修改为true(需要自行配置Redis和Config中的Redis参数,测试阶段,有bug请及时反馈)。
- restful示例:可以参考用户管理模块中的示例API。
- 前端文件参考: [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)。
- 代码生成器:后台基础逻辑以及简单curd的代码生成器。
- 表单生成器:表单生成器借助 [@form-generator](https://github.com/JakHuang/form-generator) 。
- 代码生成器:后台基础逻辑以及简单curd的代码生成器。
## 6. 计划任务
## 6. 知识库
- [ ] 导入,导出Excel
- [ ] Echart图表支持
- [ ] 单独前端使用模式以及数据模拟
## 7. 知识库
## 7.1 团队博客
## 6.1 团队博客
> https://www.yuque.com/flipped-aurora
>
>内有前端框架教学视频。如果觉得项目对您有所帮助可以添加我的个人微信:shouzi_1994,欢迎您提出宝贵的需求。
## 7.2 教学视频
## 6.2 教学视频
(1)环境搭建
> Bilibili:https://www.bilibili.com/video/BV1Fg4y187Bw/ (v1.0版本视频,v2.0操作相同目录不同)
> bilibili:https://www.bilibili.com/video/BV1Fg4y187Bw/ (v1.0版本视频,v2.0操作相同目录不同)
(2)模板使用
> Bilibili:https://www.bilibili.com/video/BV16K4y1r7BD/ (v1.0版本视频,v2.0操作相同目录不同)
> bilibili:https://www.bilibili.com/video/BV16K4y1r7BD/ (v1.0版本视频,v2.0操作相同目录不同)
(3)2.0目录以及开发体验
> Bilibili:https://www.bilibili.com/video/BV1aV411d7Gm#reply2831798461
(4)golang基础教学视频录制中...
> https://space.bilibili.com/322210472/channel/detail?cid=108884
> bilibili:https://www.bilibili.com/video/BV1aV411d7Gm#reply2831798461
## 8. 联系方式
(4)golang基础教学视频
### 8.1 技术群
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=108884
(5)gin框架基础教学
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=126418&ctype=0
(6)gin-vue-admin 版本更新介绍视频
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=126418&ctype=0
## 7. 联系方式
### 7.1 技术群
### QQ交流群:622360840
| QQ 群 |
@@ -369,10 +285,10 @@ swag init
### [关于我们](https://www.gin-vue-admin.com/about/)
## 9. 捐赠
## 8. 捐赠
如果你觉得这个项目对你有帮助,你可以请作者喝饮料 :tropical_drink: [点我](https://www.gin-vue-admin.com/docs/coffee)
## 10. 商用注意事项
## 9. 商用注意事项
如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。
+5
View File
@@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Please report security issues to qimiaojiangjizhao@gmail.com
+4 -4
View File
@@ -10,8 +10,8 @@ networks:
services:
web:
build:
context: ./
dockerfile: ./dockerfile_web
context: ./web
dockerfile: ./Dockerfile
container_name: gva-web
restart: always
ports:
@@ -25,8 +25,8 @@ services:
server:
build:
context: ./
dockerfile: ./dockerfile_server
context: ./server
dockerfile: ./Dockerfile
container_name: gva-server
restart: always
ports:
-4
View File
@@ -1,4 +0,0 @@
#!/bin/sh
envsubst '$API_SERVER' < /etc/nginx/nginx.conf.tpl > /etc/nginx/nginx.conf
env nginx
./gvadmin
-56
View File
@@ -1,56 +0,0 @@
daemon on;
worker_processes 50;
#error_log /dev/stdout warn;
error_log /var/log/nginx/error.log error;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
# See http://licson.net/post/optimizing-nginx-for-large-file-delivery/ for more detail
# This optimizes the server for HLS fragment delivery
sendfile off;
#tcp_nopush on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log /dev/stdout combined;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 10m;
server {
listen 80;
# Uncomment these lines to enable SSL.
# Update the ssl paths with your own certificate and private key.
# listen 443 ssl;
# ssl_certificate /opt/certs/example.com.crt;
# ssl_certificate_key /opt/certs/example.com.key;
location / {
root /var/www;
try_files $uri $uri/ /index.html;
index index.html;
}
location /v1/ {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_pass ${API_SERVER} ;
}
}
}
-28
View File
@@ -1,28 +0,0 @@
FROM golang:alpine
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io,direct
WORKDIR /go/src/gin-vue-admin
COPY server/ ./
RUN cat ./config.yaml
COPY .docker-compose/shell/server-handle.sh .
RUN ls -al
RUN sh ./server-handle.sh
RUN rm -f server-handle.sh
RUN cat ./config.yaml
RUN go env && go mod tidy && go build -o server .
FROM alpine:latest
LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com"
WORKDIR /go/src/gin-vue-admin
COPY --from=0 /go/src/gin-vue-admin/server ./
COPY --from=0 /go/src/gin-vue-admin/config.yaml ./
COPY --from=0 /go/src/gin-vue-admin/resource ./resource
EXPOSE 8888
ENTRYPOINT ./server
+4 -1
View File
@@ -1,3 +1,6 @@
{
"lockfileVersion": 1
"name": "gin-vue-admin",
"lockfileVersion": 2,
"requires": true,
"packages": {}
}
+1
View File
@@ -0,0 +1 @@
{}
+5 -8
View File
@@ -1,20 +1,17 @@
FROM golang:alpine
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io,direct
WORKDIR /go/src/gin-vue-admin
COPY . .
RUN go env && go build -o server .
RUN go generate && go env && go build -o server .
FROM alpine:latest
LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com"
WORKDIR /go/src/gin-vue-admin
COPY --from=0 /go/src/gin-vue-admin/server ./
COPY --from=0 /go/src/gin-vue-admin/config.yaml ./
COPY --from=0 /go/src/gin-vue-admin/resource ./resource
COPY --from=0 /go/src/gin-vue-admin ./
EXPOSE 8888
ENTRYPOINT ./server
ENTRYPOINT ./server -c config.docker.yaml
+53 -43
View File
@@ -1,44 +1,54 @@
## server项目结构
```shell
├── api
│   └── v1
├── config
├── core
├── docs
├── global
├── initialize
│   └── internal
├── middleware
├── model
│   ├── request
│   └── response
├── packfile
├── resource
│   ├── excel
│   ├── page
│   └── template
├── router
├── service
├── source
└── utils
├── timer
└── upload
```
| 文件夹 | 说明 | 描述 |
| ------------ | ----------------------- | --------------------------- |
| `api` | api层 | api层 |
| `--v1` | v1版本接口 | v1版本接口 |
| `config` | 配置包 | config.yaml对应的配置结构体 |
| `core` | 核心文件 | 核心组件(zap, viper, server)的初始化 |
| `docs` | swagger文档目录 | swagger文档目录 |
| `global` | 全局对象 | 全局对象 |
| `initialize` | 初始化 | router,redis,gorm,validator, timer的初始化 |
| `--internal` | 初始化内部函数 | gorm 的 longger 自定义,在此文件夹的函数只能由 `initialize` 层进行调用 |
| `middleware` | 中间件层 | 用于存放 `gin` 中间件代码 |
| `model` | 模型层 | 模型对应数据表 |
| `--request` | 入参结构体 | 接收前端发送到后端的数据。 |
| `--response` | 出参结构体 | 返回给前端的数据结构体 |
| `packfile` | 静态文件打包 | 静态文件打包 |
| `resource` | 静态资源文件夹 | 负责存放静态文件 |
| `--excel` | excel导入导出默认路径 | excel导入导出默认路径 |
| `--page` | 表单生成器 | 表单生成器 打包后的dist |
| `--template` | 模板 | 模板文件夹,存放的是代码生成器的模板 |
| `router` | 路由层 | 路由层 |
| `service` | service层 | 存放业务逻辑问题 |
| `source` | source层 | 存放初始化数据的函数 |
| `utils` | 工具包 | 工具函数封装 |
| `--timer` | timer | 定时器接口封装 |
| `--upload` | oss | oss接口封装 |
整理代码结构
``` lua
web
├── api/v1 -- 主要API
| ├── sys_initdb.go -- ico
| └── sys_user.go --
├── config -- 配置文件 设定操作的结构体
| ├── auto_code.go -- ico captcha.go
| ├── ... -- ico captcha.go
| └── zap.go -- core
├── core -- 主要结构代码
| ├── server_other.go -- ico captcha.go
| ├── ... -- ico captcha.go
| └── zap.go --
├── docs -- 文档系统
| ├── docs.go -- ico captcha.go
| ├── swagger.json -- json
| └── swagger.yaml -- yaml
├── global -- global
├── initialize -- initialize
├── middleware -- 中间键
├── model -- global
│ ├── request -- 所有请求model结构体
| | ├── common.go
| | ├── ...
| | └── sys_user.go -- yaml
| ├── response -- 返回数据
| | ├── common.go
| | ├── ...
| | └── sys_user.go -- yaml
├── packfile -- 文件写入
├── resource -- 资源文件
├── router -- 路由
├── service -- service层
├── source -- 文件目录操作
├── utils
├── config.yaml --
├── Dockerfile -- docker配置
├── go.mod -- mod 配置
├── go.sum -- sum
├── latest_log -- vue-cli 配置
└── main.go -- package.json
```
+121
View File
@@ -0,0 +1,121 @@
package autocode
import (
"gin-vue-admin/global"
"gin-vue-admin/model/autocode"
autocodeReq "gin-vue-admin/model/autocode/request"
"gin-vue-admin/model/common/response"
"gin-vue-admin/service"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AutoCodeExampleApi struct {
}
var autoCodeExampleService = service.ServiceGroupApp.AutoCodeServiceGroup.AutoCodeExampleService
// @Tags AutoCodeExample
// @Summary 创建AutoCodeExample
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body autocode.AutoCodeExample true "AutoCodeExample模型"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCodeExample/createAutoCodeExample [post]
func (autoCodeExampleApi *AutoCodeExampleApi) CreateAutoCodeExample(c *gin.Context) {
var autoCodeExample autocode.AutoCodeExample
_ = c.ShouldBindJSON(&autoCodeExample)
if err := autoCodeExampleService.CreateAutoCodeExample(autoCodeExample); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
response.FailWithMessage("创建失败", c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// @Tags AutoCodeExample
// @Summary 删除AutoCodeExample
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body autocode.AutoCodeExample true "AutoCodeExample模型"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /autoCodeExample/deleteAutoCodeExample [delete]
func (autoCodeExampleApi *AutoCodeExampleApi) DeleteAutoCodeExample(c *gin.Context) {
var autoCodeExample autocode.AutoCodeExample
_ = c.ShouldBindJSON(&autoCodeExample)
if err := autoCodeExampleService.DeleteAutoCodeExample(autoCodeExample); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
response.OkWithMessage("删除成功", c)
}
}
// @Tags AutoCodeExample
// @Summary 更新AutoCodeExample
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body autocode.AutoCodeExample true "更新AutoCodeExample"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /autoCodeExample/updateAutoCodeExample [put]
func (autoCodeExampleApi *AutoCodeExampleApi) UpdateAutoCodeExample(c *gin.Context) {
var autoCodeExample autocode.AutoCodeExample
_ = c.ShouldBindJSON(&autoCodeExample)
if err := autoCodeExampleService.UpdateAutoCodeExample(&autoCodeExample); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
response.FailWithMessage("更新失败", c)
} else {
response.OkWithMessage("更新成功", c)
}
}
// @Tags AutoCodeExample
// @Summary 用id查询AutoCodeExample
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body autocode.AutoCodeExample true "用id查询AutoCodeExample"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /autoCodeExample/findAutoCodeExample [get]
func (autoCodeExampleApi *AutoCodeExampleApi) FindAutoCodeExample(c *gin.Context) {
var autoCodeExample autocode.AutoCodeExample
_ = c.ShouldBindQuery(&autoCodeExample)
if err := utils.Verify(autoCodeExample, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, reAutoCodeExample := autoCodeExampleService.GetAutoCodeExample(autoCodeExample.ID); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Any("err", err))
response.FailWithMessage("查询失败", c)
} else {
response.OkWithDetailed(gin.H{"reAutoCodeExample": reAutoCodeExample}, "查询成功", c)
}
}
// @Tags AutoCodeExample
// @Summary 分页获取AutoCodeExample列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body autocodeReq.AutoCodeExampleSearch true "页码, 每页大小, 搜索条件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCodeExample/getAutoCodeExampleList [get]
func (autoCodeExampleApi *AutoCodeExampleApi) GetAutoCodeExampleList(c *gin.Context) {
var pageInfo autocodeReq.AutoCodeExampleSearch
_ = c.ShouldBindQuery(&pageInfo)
if err, list, total := autoCodeExampleService.GetAutoCodeExampleInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
}
+7
View File
@@ -0,0 +1,7 @@
package autocode
type ApiGroup struct {
// Code generated by gin-vue-admin Begin; DO NOT EDIT.
AutoCodeExampleApi
// Code generated by gin-vue-admin End; DO NOT EDIT.
}
+15
View File
@@ -0,0 +1,15 @@
package v1
import (
"gin-vue-admin/api/v1/autocode"
"gin-vue-admin/api/v1/example"
"gin-vue-admin/api/v1/system"
)
type ApiGroup struct {
ExampleApiGroup example.ApiGroup
SystemApiGroup system.ApiGroup
AutoCodeApiGroup autocode.ApiGroup
}
var ApiGroupApp = new(ApiGroup)
+15
View File
@@ -0,0 +1,15 @@
package example
import "gin-vue-admin/service"
type ApiGroup struct {
CustomerApi
ExcelApi
FileUploadAndDownloadApi
SimpleUploaderApi
}
var fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService
var customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService
var excelService = service.ServiceGroupApp.ExampleServiceGroup.ExcelService
var simpleUploaderService = service.ServiceGroupApp.ExampleServiceGroup.SimpleUploaderService
@@ -1,9 +1,9 @@
package v1
package example
import (
"gin-vue-admin/global"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
exampleRes "gin-vue-admin/model/example/response"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
@@ -19,7 +19,7 @@ import (
// @Param file formData file true "an example for breakpoint resume, 断点续传示例"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"切片创建成功"}"
// @Router /fileUploadAndDownload/breakpointContinue [post]
func BreakpointContinue(c *gin.Context) {
func (u *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) {
fileMd5 := c.Request.FormValue("fileMd5")
fileName := c.Request.FormValue("fileName")
chunkMd5 := c.Request.FormValue("chunkMd5")
@@ -44,7 +44,7 @@ func BreakpointContinue(c *gin.Context) {
response.FailWithMessage("检查md5失败", c)
return
}
err, file := service.FindOrCreateFile(fileMd5, fileName, chunkTotal)
err, file := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal)
if err != nil {
global.GVA_LOG.Error("查找或创建记录失败!", zap.Any("err", err))
response.FailWithMessage("查找或创建记录失败", c)
@@ -57,7 +57,7 @@ func BreakpointContinue(c *gin.Context) {
return
}
if err = service.CreateFileChunk(file.ID, pathc, chunkNumber); err != nil {
if err = fileUploadAndDownloadService.CreateFileChunk(file.ID, pathc, chunkNumber); err != nil {
global.GVA_LOG.Error("创建文件记录失败!", zap.Any("err", err))
response.FailWithMessage("创建文件记录失败", c)
return
@@ -73,16 +73,16 @@ func BreakpointContinue(c *gin.Context) {
// @Param file formData file true "Find the file, 查找文件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查找成功"}"
// @Router /fileUploadAndDownload/findFile [post]
func FindFile(c *gin.Context) {
func (u *FileUploadAndDownloadApi) FindFile(c *gin.Context) {
fileMd5 := c.Query("fileMd5")
fileName := c.Query("fileName")
chunkTotal, _ := strconv.Atoi(c.Query("chunkTotal"))
err, file := service.FindOrCreateFile(fileMd5, fileName, chunkTotal)
err, file := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal)
if err != nil {
global.GVA_LOG.Error("查找失败!", zap.Any("err", err))
response.FailWithMessage("查找失败", c)
} else {
response.OkWithDetailed(response.FileResponse{File: file}, "查找成功", c)
response.OkWithDetailed(exampleRes.FileResponse{File: file}, "查找成功", c)
}
}
@@ -94,15 +94,15 @@ func FindFile(c *gin.Context) {
// @Param file formData file true "上传文件完成"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"file uploaded, 文件创建成功"}"
// @Router /fileUploadAndDownload/findFile [post]
func BreakpointContinueFinish(c *gin.Context) {
func (b *FileUploadAndDownloadApi) BreakpointContinueFinish(c *gin.Context) {
fileMd5 := c.Query("fileMd5")
fileName := c.Query("fileName")
err, filePath := utils.MakeFile(fileName, fileMd5)
if err != nil {
global.GVA_LOG.Error("文件创建失败!", zap.Any("err", err))
response.FailWithDetailed(response.FilePathResponse{FilePath: filePath}, "文件创建失败", c)
response.FailWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "文件创建失败", c)
} else {
response.OkWithDetailed(response.FilePathResponse{FilePath: filePath}, "文件创建成功", c)
response.OkWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "文件创建成功", c)
}
}
@@ -114,16 +114,16 @@ func BreakpointContinueFinish(c *gin.Context) {
// @Param file formData file true "删除缓存切片"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"缓存切片删除成功"}"
// @Router /fileUploadAndDownload/removeChunk [post]
func RemoveChunk(c *gin.Context) {
func (u *FileUploadAndDownloadApi) RemoveChunk(c *gin.Context) {
fileMd5 := c.Query("fileMd5")
fileName := c.Query("fileName")
filePath := c.Query("filePath")
err := utils.RemoveChunk(fileMd5)
err = service.DeleteFileChunk(fileMd5, fileName, filePath)
err = fileUploadAndDownloadService.DeleteFileChunk(fileMd5, fileName, filePath)
if err != nil {
global.GVA_LOG.Error("缓存切片删除失败!", zap.Any("err", err))
response.FailWithDetailed(response.FilePathResponse{FilePath: filePath}, "缓存切片删除失败", c)
response.FailWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "缓存切片删除失败", c)
} else {
response.OkWithDetailed(response.FilePathResponse{FilePath: filePath}, "缓存切片删除成功", c)
response.OkWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "缓存切片删除成功", c)
}
}
@@ -1,35 +1,37 @@
package v1
package example
import (
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/example"
exampleRes "gin-vue-admin/model/example/response"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type CustomerApi struct {
}
// @Tags ExaCustomer
// @Summary 创建客户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaCustomer true "客户用户名, 客户手机号码"
// @Param data body example.ExaCustomer true "客户用户名, 客户手机号码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /customer/customer [post]
func CreateExaCustomer(c *gin.Context) {
var customer model.ExaCustomer
func (e *CustomerApi) CreateExaCustomer(c *gin.Context) {
var customer example.ExaCustomer
_ = c.ShouldBindJSON(&customer)
if err := utils.Verify(customer, utils.CustomerVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
customer.SysUserID = getUserID(c)
customer.SysUserAuthorityID = getUserAuthorityId(c)
if err := service.CreateExaCustomer(customer); err != nil {
customer.SysUserID = utils.GetUserID(c)
customer.SysUserAuthorityID = utils.GetUserAuthorityId(c)
if err := customerService.CreateExaCustomer(customer); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
response.FailWithMessage("创建失败", c)
} else {
@@ -42,17 +44,17 @@ func CreateExaCustomer(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaCustomer true "客户ID"
// @Param data body example.ExaCustomer true "客户ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /customer/customer [delete]
func DeleteExaCustomer(c *gin.Context) {
var customer model.ExaCustomer
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 {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.DeleteExaCustomer(customer); err != nil {
if err := customerService.DeleteExaCustomer(customer); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
@@ -65,11 +67,11 @@ func DeleteExaCustomer(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaCustomer true "客户ID, 客户信息"
// @Param data body example.ExaCustomer true "客户ID, 客户信息"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /customer/customer [put]
func UpdateExaCustomer(c *gin.Context) {
var customer model.ExaCustomer
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 {
response.FailWithMessage(err.Error(), c)
@@ -79,9 +81,9 @@ func UpdateExaCustomer(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.UpdateExaCustomer(&customer); err != nil {
if err := customerService.UpdateExaCustomer(&customer); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
response.FailWithMessage("更新失败!", c)
response.FailWithMessage("更新失败", c)
} else {
response.OkWithMessage("更新成功", c)
}
@@ -92,22 +94,22 @@ func UpdateExaCustomer(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaCustomer true "客户ID"
// @Param data body example.ExaCustomer true "客户ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /customer/customer [get]
func GetExaCustomer(c *gin.Context) {
var customer model.ExaCustomer
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 {
response.FailWithMessage(err.Error(), c)
return
}
err, data := service.GetExaCustomer(customer.ID)
err, data := customerService.GetExaCustomer(customer.ID)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.ExaCustomerResponse{Customer: data}, "获取成功", c)
response.OkWithDetailed(exampleRes.ExaCustomerResponse{Customer: data}, "获取成功", c)
}
}
@@ -119,17 +121,17 @@ func GetExaCustomer(c *gin.Context) {
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /customer/customerList [get]
func GetExaCustomerList(c *gin.Context) {
func (e *CustomerApi) GetExaCustomerList(c *gin.Context) {
var pageInfo request.PageInfo
_ = c.ShouldBindQuery(&pageInfo)
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err, customerList, total := service.GetCustomerInfoList(getUserAuthorityId(c), pageInfo)
err, customerList, total := customerService.GetCustomerInfoList(utils.GetUserAuthorityId(c), pageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage(fmt.Sprintf("获取失败:%v", err), c)
response.FailWithMessage("获取失败"+err.Error(), c)
} else {
response.OkWithDetailed(response.PageResult{
List: customerList,
@@ -1,15 +1,17 @@
package v1
package example
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/example"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type ExcelApi struct {
}
// /excel/importExcel 接口,与upload接口作用类似,只是把文件存到resource/excel目录下,用于导入Excel时存放Excel文件(ExcelImport.xlsx)
// /excel/loadExcel接口,用于读取resource/excel目录下的文件((ExcelImport.xlsx)并加载为[]model.SysBaseMenu类型的示例数据
// /excel/exportExcel 接口,用于读取前端传来的tableData,生成Excel文件并返回
@@ -20,14 +22,14 @@ import (
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/octet-stream
// @Param data body model.ExcelInfo true "导出Excel文件信息"
// @Param data body example.ExcelInfo true "导出Excel文件信息"
// @Success 200
// @Router /excel/exportExcel [post]
func ExportExcel(c *gin.Context) {
var excelInfo model.ExcelInfo
func (e *ExcelApi) ExportExcel(c *gin.Context) {
var excelInfo example.ExcelInfo
_ = c.ShouldBindJSON(&excelInfo)
filePath := global.GVA_CONFIG.Excel.Dir + excelInfo.FileName
err := service.ParseInfoList2Excel(excelInfo.InfoList, filePath)
err := excelService.ParseInfoList2Excel(excelInfo.InfoList, filePath)
if err != nil {
global.GVA_LOG.Error("转换Excel失败!", zap.Any("err", err))
response.FailWithMessage("转换Excel失败", c)
@@ -45,7 +47,7 @@ func ExportExcel(c *gin.Context) {
// @Param file formData file true "导入Excel文件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}"
// @Router /excel/importExcel [post]
func ImportExcel(c *gin.Context) {
func (e *ExcelApi) ImportExcel(c *gin.Context) {
_, header, err := c.Request.FormFile("file")
if err != nil {
global.GVA_LOG.Error("接收文件失败!", zap.Any("err", err))
@@ -62,10 +64,10 @@ func ImportExcel(c *gin.Context) {
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"加载数据成功"}"
// @Router /excel/loadExcel [get]
func LoadExcel(c *gin.Context) {
menus, err := service.ParseExcel2InfoList()
func (e *ExcelApi) LoadExcel(c *gin.Context) {
menus, err := excelService.ParseExcel2InfoList()
if err != nil {
global.GVA_LOG.Error("加载数据失败", zap.Any("err", err))
global.GVA_LOG.Error("加载数据失败!", zap.Any("err", err))
response.FailWithMessage("加载数据失败", c)
return
}
@@ -85,12 +87,12 @@ func LoadExcel(c *gin.Context) {
// @Param fileName query string true "模板名称"
// @Success 200
// @Router /excel/downloadTemplate [get]
func DownloadTemplate(c *gin.Context) {
func (e *ExcelApi) DownloadTemplate(c *gin.Context) {
fileName := c.Query("fileName")
filePath := global.GVA_CONFIG.Excel.Dir + fileName
ok, err := utils.PathExists(filePath)
if !ok || err != nil {
global.GVA_LOG.Error("文件不存在", zap.Any("err", err))
global.GVA_LOG.Error("文件不存在!", zap.Any("err", err))
response.FailWithMessage("文件不存在", c)
return
}
@@ -1,15 +1,18 @@
package v1
package example
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/example"
exampleRes "gin-vue-admin/model/example/response"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type FileUploadAndDownloadApi struct {
}
// @Tags ExaFileUploadAndDownload
// @Summary 上传文件示例
// @Security ApiKeyAuth
@@ -18,8 +21,8 @@ import (
// @Param file formData file true "上传文件示例"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"上传成功"}"
// @Router /fileUploadAndDownload/upload [post]
func UploadFile(c *gin.Context) {
var file model.ExaFileUploadAndDownload
func (u *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
var file example.ExaFileUploadAndDownload
noSave := c.DefaultQuery("noSave", "0")
_, header, err := c.Request.FormFile("file")
if err != nil {
@@ -27,26 +30,26 @@ func UploadFile(c *gin.Context) {
response.FailWithMessage("接收文件失败", c)
return
}
err, file = service.UploadFile(header, noSave) // 文件上传后拿到文件路径
err, file = fileUploadAndDownloadService.UploadFile(header, noSave) // 文件上传后拿到文件路径
if err != nil {
global.GVA_LOG.Error("修改数据库链接失败!", zap.Any("err", err))
response.FailWithMessage("修改数据库链接失败", c)
return
}
response.OkWithDetailed(response.ExaFileResponse{File: file}, "上传成功", c)
response.OkWithDetailed(exampleRes.ExaFileResponse{File: file}, "上传成功", c)
}
// @Tags ExaFileUploadAndDownload
// @Summary 删除文件
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body model.ExaFileUploadAndDownload true "传入文件里面id即可"
// @Param data body example.ExaFileUploadAndDownload true "传入文件里面id即可"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /fileUploadAndDownload/deleteFile [post]
func DeleteFile(c *gin.Context) {
var file model.ExaFileUploadAndDownload
func (u *FileUploadAndDownloadApi) DeleteFile(c *gin.Context) {
var file example.ExaFileUploadAndDownload
_ = c.ShouldBindJSON(&file)
if err := service.DeleteFile(file); err != nil {
if err := fileUploadAndDownloadService.DeleteFile(file); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
return
@@ -62,10 +65,10 @@ func DeleteFile(c *gin.Context) {
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /fileUploadAndDownload/getFileList [post]
func GetFileList(c *gin.Context) {
func (u *FileUploadAndDownloadApi) GetFileList(c *gin.Context) {
var pageInfo request.PageInfo
_ = c.ShouldBindJSON(&pageInfo)
err, list, total := service.GetFileRecordInfoList(pageInfo)
err, list, total := fileUploadAndDownloadService.GetFileRecordInfoList(pageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
@@ -1,15 +1,17 @@
package v1
package example
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/example"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type SimpleUploaderApi struct {
}
// @Tags SimpleUploader
// @Summary 断点续传插件版示例
// @Security ApiKeyAuth
@@ -17,9 +19,9 @@ import (
// @Produce application/json
// @Param file formData file true "断点续传插件版示例"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"切片创建成功"}"
// @Router /simpleUploader/upload [post]
func SimpleUploaderUpload(c *gin.Context) {
var chunk model.ExaSimpleUploader
// @Router /SimpleUploaderApi/upload [post]
func (s *SimpleUploaderApi) SimpleUploaderUpload(c *gin.Context) {
var chunk example.ExaSimpleUploader
_, header, err := c.Request.FormFile("file")
chunk.Filename = c.PostForm("filename")
chunk.ChunkNumber = c.PostForm("chunkNumber")
@@ -42,7 +44,7 @@ func SimpleUploaderUpload(c *gin.Context) {
return
}
chunk.CurrentChunkPath = chunkPath
err = service.SaveChunk(chunk)
err = simpleUploaderService.SaveChunk(chunk)
if err != nil {
global.GVA_LOG.Error("切片创建失败!", zap.Any("err", err))
response.FailWithMessage("切片创建失败", c)
@@ -58,10 +60,10 @@ func SimpleUploaderUpload(c *gin.Context) {
// @Produce application/json
// @Param md5 query string true "md5"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /simpleUploader/checkFileMd5 [get]
func CheckFileMd5(c *gin.Context) {
// @Router /SimpleUploaderApi/checkFileMd5 [get]
func (s *SimpleUploaderApi) CheckFileMd5(c *gin.Context) {
md5 := c.Query("md5")
err, chunks, isDone := service.CheckFileMd5(md5)
err, chunks, isDone := simpleUploaderService.CheckFileMd5(md5)
if err != nil {
global.GVA_LOG.Error("md5读取失败!", zap.Any("err", err))
response.FailWithMessage("md5读取失败", c)
@@ -79,11 +81,11 @@ func CheckFileMd5(c *gin.Context) {
// @Produce application/json
// @Param md5 query string true "md5"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"合并成功"}"
// @Router /simpleUploader/mergeFileMd5 [get]
func MergeFileMd5(c *gin.Context) {
// @Router /SimpleUploaderApi/mergeFileMd5 [get]
func (s *SimpleUploaderApi) MergeFileMd5(c *gin.Context) {
md5 := c.Query("md5")
fileName := c.Query("fileName")
err := service.MergeFileMd5(md5, fileName)
err := simpleUploaderService.MergeFileMd5(md5, fileName)
if err != nil {
global.GVA_LOG.Error("md5读取失败!", zap.Any("err", err))
response.FailWithMessage("md5读取失败", c)
-136
View File
@@ -1,136 +0,0 @@
package v1
import (
"errors"
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/utils"
"net/url"
"os"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// @Tags AutoCode
// @Summary 预览创建后的代码
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.AutoCodeStruct true "预览创建代码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCode/preview [post]
func PreviewTemp(c *gin.Context) {
var a model.AutoCodeStruct
_ = c.ShouldBindJSON(&a)
if err := utils.Verify(a, utils.AutoCodeVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
autoCode, err := service.PreviewTemp(a)
if err != nil {
global.GVA_LOG.Error("预览失败!", zap.Any("err", err))
response.FailWithMessage("预览失败", c)
} else {
response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c)
}
}
// @Tags AutoCode
// @Summary 自动代码模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.AutoCodeStruct true "创建自动代码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /autoCode/createTemp [post]
func CreateTemp(c *gin.Context) {
var a model.AutoCodeStruct
_ = c.ShouldBindJSON(&a)
if err := utils.Verify(a, utils.AutoCodeVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if a.AutoCreateApiToSql {
if err := service.AutoCreateApi(&a); err != nil {
global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Any("err", err))
c.Writer.Header().Add("success", "false")
c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
return
}
}
err := service.CreateTemp(a)
if err != nil {
if errors.Is(err, model.AutoMoveErr) {
c.Writer.Header().Add("success", "false")
c.Writer.Header().Add("msgtype", "success")
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")
}
}
// @Tags AutoCode
// @Summary 获取当前数据库所有表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getTables [get]
func GetTables(c *gin.Context) {
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
err, tables := service.GetTables(dbName)
if err != nil {
global.GVA_LOG.Error("查询table失败!", zap.Any("err", err))
response.FailWithMessage("查询table失败", c)
} else {
response.OkWithDetailed(gin.H{"tables": tables}, "获取成功", c)
}
}
// @Tags AutoCode
// @Summary 获取当前所有数据库
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getDatabase [get]
func GetDB(c *gin.Context) {
if err, dbs := service.GetDB(); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"dbs": dbs}, "获取成功", c)
}
}
// @Tags AutoCode
// @Summary 获取当前表所有字段
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getColumn [get]
func GetColumn(c *gin.Context) {
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
tableName := c.Query("tableName")
if err, columns := service.GetColumn(tableName, dbName); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"columns": columns}, "获取成功", c)
}
}
+34
View File
@@ -0,0 +1,34 @@
package system
import "gin-vue-admin/service"
type ApiGroup struct {
SystemApiApi
AuthorityApi
AutoCodeApi
BaseApi
CasbinApi
DictionaryApi
DictionaryDetailApi
SystemApi
DBApi
JwtApi
OperationRecordApi
AuthorityMenuApi
}
var authorityService = service.ServiceGroupApp.SystemServiceGroup.AuthorityService
var apiService = service.ServiceGroupApp.SystemServiceGroup.ApiService
var menuService = service.ServiceGroupApp.SystemServiceGroup.MenuService
var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
var autoCodeService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeService
var autoCodeHistoryService = service.ServiceGroupApp.SystemServiceGroup.AutoCodeHistoryService
var dictionaryService = service.ServiceGroupApp.SystemServiceGroup.DictionaryService
var dictionaryDetailService = service.ServiceGroupApp.SystemServiceGroup.DictionaryDetailService
var emailService = service.ServiceGroupApp.SystemServiceGroup.EmailService
var initDBService = service.ServiceGroupApp.SystemServiceGroup.InitDBService
var jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService
var baseMenuService = service.ServiceGroupApp.SystemServiceGroup.BaseMenuService
var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
var userService = service.ServiceGroupApp.SystemServiceGroup.UserService
var systemConfigService = service.ServiceGroupApp.SystemServiceGroup.SystemConfigService
@@ -1,33 +1,37 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
systemReq "gin-vue-admin/model/system/request"
systemRes "gin-vue-admin/model/system/response"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type SystemApiApi struct {
}
// @Tags SysApi
// @Summary 创建基础api
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysApi true "api路径, api中文描述, api组, 方法"
// @Param data body system.SysApi true "api路径, api中文描述, api组, 方法"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /api/createApi [post]
func CreateApi(c *gin.Context) {
var api model.SysApi
func (s *SystemApiApi) CreateApi(c *gin.Context) {
var api system.SysApi
_ = c.ShouldBindJSON(&api)
if err := utils.Verify(api, utils.ApiVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.CreateApi(api); err != nil {
if err := apiService.CreateApi(api); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
response.FailWithMessage("创建失败", c)
} else {
@@ -40,17 +44,17 @@ func CreateApi(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysApi true "ID"
// @Param data body system.SysApi true "ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /api/deleteApi [post]
func DeleteApi(c *gin.Context) {
var api model.SysApi
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 := service.DeleteApi(api); err != nil {
if err := apiService.DeleteApi(api); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
@@ -63,17 +67,17 @@ func DeleteApi(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SearchApiParams true "分页获取API列表"
// @Param data body systemReq.SearchApiParams true "分页获取API列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/getApiList [post]
func GetApiList(c *gin.Context) {
var pageInfo request.SearchApiParams
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)
return
}
if err, list, total := service.GetAPIInfoList(pageInfo.SysApi, pageInfo.PageInfo, pageInfo.OrderKey, pageInfo.Desc); err != nil {
if err, list, total := apiService.GetAPIInfoList(pageInfo.SysApi, pageInfo.PageInfo, pageInfo.OrderKey, pageInfo.Desc); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
@@ -94,19 +98,19 @@ func GetApiList(c *gin.Context) {
// @Param data body request.GetById true "根据id获取api"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/getApiById [post]
func GetApiById(c *gin.Context) {
func (s *SystemApiApi) GetApiById(c *gin.Context) {
var idInfo request.GetById
_ = c.ShouldBindJSON(&idInfo)
if err := utils.Verify(idInfo, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err, api := service.GetApiById(idInfo.ID)
err, api := apiService.GetApiById(idInfo.ID)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithData(response.SysAPIResponse{Api: api}, c)
response.OkWithData(systemRes.SysAPIResponse{Api: api}, c)
}
}
@@ -115,17 +119,17 @@ func GetApiById(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysApi true "api路径, api中文描述, api组, 方法"
// @Param data body system.SysApi true "api路径, api中文描述, api组, 方法"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
// @Router /api/updateApi [post]
func UpdateApi(c *gin.Context) {
var api model.SysApi
func (s *SystemApiApi) UpdateApi(c *gin.Context) {
var api system.SysApi
_ = c.ShouldBindJSON(&api)
if err := utils.Verify(api, utils.ApiVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.UpdateApi(api); err != nil {
if err := apiService.UpdateApi(api); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Any("err", err))
response.FailWithMessage("修改失败", c)
} else {
@@ -140,12 +144,12 @@ func UpdateApi(c *gin.Context) {
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /api/getAllApis [post]
func GetAllApis(c *gin.Context) {
if err, apis := service.GetAllApis(); err != nil {
func (s *SystemApiApi) GetAllApis(c *gin.Context) {
if err, apis := apiService.GetAllApis(); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.SysAPIListResponse{Apis: apis}, "获取成功", c)
response.OkWithDetailed(systemRes.SysAPIListResponse{Apis: apis}, "获取成功", c)
}
}
@@ -157,10 +161,10 @@ func GetAllApis(c *gin.Context) {
// @Param data body request.IdsReq true "ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /api/deleteApisByIds [delete]
func DeleteApisByIds(c *gin.Context) {
func (s *SystemApiApi) DeleteApisByIds(c *gin.Context) {
var ids request.IdsReq
_ = c.ShouldBindJSON(&ids)
if err := service.DeleteApisByIds(ids); err != nil {
if err := apiService.DeleteApisByIds(ids); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
@@ -1,36 +1,43 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
systemReq "gin-vue-admin/model/system/request"
systemRes "gin-vue-admin/model/system/response"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AuthorityApi struct {
}
// @Tags Authority
// @Summary 创建角色
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysAuthority true "权限id, 权限名, 父角色id"
// @Param data body system.SysAuthority true "权限id, 权限名, 父角色id"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /authority/createAuthority [post]
func CreateAuthority(c *gin.Context) {
var authority model.SysAuthority
func (a *AuthorityApi) CreateAuthority(c *gin.Context) {
var authority system.SysAuthority
_ = c.ShouldBindJSON(&authority)
if err := utils.Verify(authority, utils.AuthorityVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, authBack := service.CreateAuthority(authority); err != nil {
if err, authBack := authorityService.CreateAuthority(authority); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
response.FailWithMessage("创建失败"+err.Error(), c)
} else {
response.OkWithDetailed(response.SysAuthorityResponse{Authority: authBack}, "创建成功", c)
_ = menuService.AddMenuAuthority(systemReq.DefaultMenu(), authority.AuthorityId)
_ = casbinService.UpdateCasbin(authority.AuthorityId, systemReq.DefaultCasbin())
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "创建成功", c)
}
}
@@ -42,8 +49,8 @@ func CreateAuthority(c *gin.Context) {
// @Param data body response.SysAuthorityCopyResponse true "旧角色id, 新权限id, 新权限名, 新父角色id"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"拷贝成功"}"
// @Router /authority/copyAuthority [post]
func CopyAuthority(c *gin.Context) {
var copyInfo response.SysAuthorityCopyResponse
func (a *AuthorityApi) CopyAuthority(c *gin.Context) {
var copyInfo systemRes.SysAuthorityCopyResponse
_ = c.ShouldBindJSON(&copyInfo)
if err := utils.Verify(copyInfo, utils.OldAuthorityVerify); err != nil {
response.FailWithMessage(err.Error(), c)
@@ -53,11 +60,11 @@ func CopyAuthority(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
if err, authBack := service.CopyAuthority(copyInfo); err != nil {
if err, authBack := authorityService.CopyAuthority(copyInfo); err != nil {
global.GVA_LOG.Error("拷贝失败!", zap.Any("err", err))
response.FailWithMessage("拷贝失败"+err.Error(), c)
} else {
response.OkWithDetailed(response.SysAuthorityResponse{Authority: authBack}, "拷贝成功", c)
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authBack}, "拷贝成功", c)
}
}
@@ -66,17 +73,17 @@ func CopyAuthority(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysAuthority true "删除角色"
// @Param data body system.SysAuthority true "删除角色"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /authority/deleteAuthority [post]
func DeleteAuthority(c *gin.Context) {
var authority model.SysAuthority
func (a *AuthorityApi) DeleteAuthority(c *gin.Context) {
var authority system.SysAuthority
_ = c.ShouldBindJSON(&authority)
if err := utils.Verify(authority, utils.AuthorityIdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.DeleteAuthority(&authority); err != nil { // 删除角色之前需要判断是否有用户正在使用此角色
if err := authorityService.DeleteAuthority(&authority); err != nil { // 删除角色之前需要判断是否有用户正在使用此角色
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败"+err.Error(), c)
} else {
@@ -89,21 +96,21 @@ func DeleteAuthority(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysAuthority true "权限id, 权限名, 父角色id"
// @Param data body system.SysAuthority true "权限id, 权限名, 父角色id"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /authority/updateAuthority [post]
func UpdateAuthority(c *gin.Context) {
var auth model.SysAuthority
func (a *AuthorityApi) UpdateAuthority(c *gin.Context) {
var auth system.SysAuthority
_ = c.ShouldBindJSON(&auth)
if err := utils.Verify(auth, utils.AuthorityVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, authority := service.UpdateAuthority(auth); err != nil {
if err, authority := authorityService.UpdateAuthority(auth); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
response.FailWithMessage("更新失败"+err.Error(), c)
} else {
response.OkWithDetailed(response.SysAuthorityResponse{Authority: authority}, "更新成功", c)
response.OkWithDetailed(systemRes.SysAuthorityResponse{Authority: authority}, "更新成功", c)
}
}
@@ -115,14 +122,14 @@ func UpdateAuthority(c *gin.Context) {
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /authority/getAuthorityList [post]
func GetAuthorityList(c *gin.Context) {
func (a *AuthorityApi) GetAuthorityList(c *gin.Context) {
var pageInfo request.PageInfo
_ = c.ShouldBindJSON(&pageInfo)
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, list, total := service.GetAuthorityInfoList(pageInfo); err != nil {
if err, list, total := authorityService.GetAuthorityInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败"+err.Error(), c)
} else {
@@ -140,17 +147,17 @@ func GetAuthorityList(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysAuthority true "设置角色资源权限"
// @Param data body system.SysAuthority true "设置角色资源权限"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
// @Router /authority/setDataAuthority [post]
func SetDataAuthority(c *gin.Context) {
var auth model.SysAuthority
func (a *AuthorityApi) SetDataAuthority(c *gin.Context) {
var auth system.SysAuthority
_ = c.ShouldBindJSON(&auth)
if err := utils.Verify(auth, utils.AuthorityIdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.SetDataAuthority(auth); err != nil {
if err := authorityService.SetDataAuthority(auth); err != nil {
global.GVA_LOG.Error("设置失败!", zap.Any("err", err))
response.FailWithMessage("设置失败"+err.Error(), c)
} else {
+224
View File
@@ -0,0 +1,224 @@
package system
import (
"errors"
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
systemReq "gin-vue-admin/model/system/request"
"gin-vue-admin/utils"
"net/url"
"os"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AutoCodeApi struct {
}
// @Tags AutoCode
// @Summary 删除回滚记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.AutoHistoryByID true "删除回滚记录"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /autoCode/delSysHistory [post]
func (autoApi *AutoCodeApi) DelSysHistory(c *gin.Context) {
var id systemReq.AutoHistoryByID
_ = c.ShouldBindJSON(&id)
err := autoCodeHistoryService.DeletePage(id.ID)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
}
response.OkWithMessage("删除成功", c)
}
// @Tags AutoCode
// @Summary 查询回滚记录
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.SysAutoHistory true "查询回滚记录"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getSysHistory [post]
func (autoApi *AutoCodeApi) GetSysHistory(c *gin.Context) {
var search systemReq.SysAutoHistory
_ = c.ShouldBindJSON(&search)
err, list, total := autoCodeHistoryService.GetSysHistoryPage(search.PageInfo)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: search.Page,
PageSize: search.PageSize,
}, "获取成功", c)
}
}
// @Tags AutoCode
// @Summary 回滚
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.AutoHistoryByID true "回滚自动生成代码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"回滚成功"}"
// @Router /autoCode/rollback [post]
func (autoApi *AutoCodeApi) RollBack(c *gin.Context) {
var id systemReq.AutoHistoryByID
_ = c.ShouldBindJSON(&id)
if err := autoCodeHistoryService.RollBack(id.ID); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
response.OkWithMessage("回滚成功", c)
}
// @Tags AutoCode
// @Summary 回滚
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body systemReq.AutoHistoryByID true "获取meta信息"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getMeta [post]
func (autoApi *AutoCodeApi) GetMeta(c *gin.Context) {
var id systemReq.AutoHistoryByID
_ = c.ShouldBindJSON(&id)
if v, err := autoCodeHistoryService.GetMeta(id.ID); err != nil {
response.FailWithMessage(err.Error(), c)
return
} else {
response.OkWithDetailed(gin.H{"meta": v}, "获取成功", c)
}
}
// @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/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
}
autoCode, err := autoCodeService.PreviewTemp(a)
if err != nil {
global.GVA_LOG.Error("预览失败!", zap.Any("err", err))
response.FailWithMessage("预览失败", c)
} else {
response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c)
}
}
// @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
}
var apiIds []uint
if a.AutoCreateApiToSql {
if ids, err := autoCodeService.AutoCreateApi(&a); err != nil {
global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Any("err", err))
c.Writer.Header().Add("success", "false")
c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
return
} else {
apiIds = ids
}
}
err := autoCodeService.CreateTemp(a, apiIds...)
if err != nil {
if errors.Is(err, system.AutoMoveErr) {
c.Writer.Header().Add("success", "false")
c.Writer.Header().Add("msgtype", "success")
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")
}
}
// @Tags AutoCode
// @Summary 获取当前数据库所有表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getTables [get]
func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
err, tables := autoCodeService.GetTables(dbName)
if err != nil {
global.GVA_LOG.Error("查询table失败!", zap.Any("err", err))
response.FailWithMessage("查询table失败", c)
} else {
response.OkWithDetailed(gin.H{"tables": tables}, "获取成功", c)
}
}
// @Tags AutoCode
// @Summary 获取当前所有数据库
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getDatabase [get]
func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
if err, dbs := autoCodeService.GetDB(); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"dbs": dbs}, "获取成功", c)
}
}
// @Tags AutoCode
// @Summary 获取当前表所有字段
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /autoCode/getColumn [get]
func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) {
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
tableName := c.Query("tableName")
if err, columns := autoCodeService.GetColumn(tableName, dbName); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(gin.H{"columns": columns}, "获取成功", c)
}
}
@@ -1,15 +1,21 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model/response"
"gin-vue-admin/model/common/response"
systemRes "gin-vue-admin/model/system/response"
"github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha"
"go.uber.org/zap"
)
// 当开启多服务器部署时,替换下面的配置,使用redis共享存储验证码
// var store = captcha.NewDefaultRedisStore()
var store = base64Captcha.DefaultMemStore
type BaseApi struct {
}
// @Tags Base
// @Summary 生成验证码
// @Security ApiKeyAuth
@@ -17,8 +23,8 @@ var store = base64Captcha.DefaultMemStore
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"验证码获取成功"}"
// @Router /base/captcha [post]
func Captcha(c *gin.Context) {
//字符,公式,验证码配置
func (b *BaseApi) Captcha(c *gin.Context) {
// 字符,公式,验证码配置
// 生成默认数字的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)
@@ -26,7 +32,7 @@ func Captcha(c *gin.Context) {
global.GVA_LOG.Error("验证码获取失败!", zap.Any("err", err))
response.FailWithMessage("验证码获取失败", c)
} else {
response.OkWithDetailed(response.SysCaptchaResponse{
response.OkWithDetailed(systemRes.SysCaptchaResponse{
CaptchaId: id,
PicPath: b64s,
}, "验证码获取成功", c)
@@ -1,15 +1,18 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system/request"
systemRes "gin-vue-admin/model/system/response"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type CasbinApi struct {
}
// @Tags Casbin
// @Summary 更新角色api权限
// @Security ApiKeyAuth
@@ -18,14 +21,14 @@ import (
// @Param data body request.CasbinInReceive true "权限id, 权限模型列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /casbin/UpdateCasbin [post]
func UpdateCasbin(c *gin.Context) {
func (cas *CasbinApi) UpdateCasbin(c *gin.Context) {
var cmr request.CasbinInReceive
_ = c.ShouldBindJSON(&cmr)
if err := utils.Verify(cmr, utils.AuthorityIdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos); err != nil {
if err := casbinService.UpdateCasbin(cmr.AuthorityId, cmr.CasbinInfos); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
response.FailWithMessage("更新失败", c)
} else {
@@ -41,13 +44,13 @@ func UpdateCasbin(c *gin.Context) {
// @Param data body request.CasbinInReceive true "权限id, 权限模型列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /casbin/getPolicyPathByAuthorityId [post]
func GetPolicyPathByAuthorityId(c *gin.Context) {
func (cas *CasbinApi) GetPolicyPathByAuthorityId(c *gin.Context) {
var casbin request.CasbinInReceive
_ = c.ShouldBindJSON(&casbin)
if err := utils.Verify(casbin, utils.AuthorityIdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
paths := service.GetPolicyPathByAuthorityId(casbin.AuthorityId)
response.OkWithDetailed(response.PolicyPathResponse{Paths: paths}, "获取成功", c)
paths := casbinService.GetPolicyPathByAuthorityId(casbin.AuthorityId)
response.OkWithDetailed(systemRes.PolicyPathResponse{Paths: paths}, "获取成功", c)
}
@@ -1,28 +1,30 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
"gin-vue-admin/model/system/request"
"gin-vue-admin/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 model.SysDictionary true "SysDictionary模型"
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /sysDictionary/createSysDictionary [post]
func CreateSysDictionary(c *gin.Context) {
var dictionary model.SysDictionary
func (s *DictionaryApi) CreateSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
_ = c.ShouldBindJSON(&dictionary)
if err := service.CreateSysDictionary(dictionary); err != nil {
if err := dictionaryService.CreateSysDictionary(dictionary); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
response.FailWithMessage("创建失败", c)
} else {
@@ -35,13 +37,13 @@ func CreateSysDictionary(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysDictionary true "SysDictionary模型"
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysDictionary/deleteSysDictionary [delete]
func DeleteSysDictionary(c *gin.Context) {
var dictionary model.SysDictionary
func (s *DictionaryApi) DeleteSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
_ = c.ShouldBindJSON(&dictionary)
if err := service.DeleteSysDictionary(dictionary); err != nil {
if err := dictionaryService.DeleteSysDictionary(dictionary); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
@@ -54,13 +56,13 @@ func DeleteSysDictionary(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysDictionary true "SysDictionary模型"
// @Param data body system.SysDictionary true "SysDictionary模型"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /sysDictionary/updateSysDictionary [put]
func UpdateSysDictionary(c *gin.Context) {
var dictionary model.SysDictionary
func (s *DictionaryApi) UpdateSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
_ = c.ShouldBindJSON(&dictionary)
if err := service.UpdateSysDictionary(&dictionary); err != nil {
if err := dictionaryService.UpdateSysDictionary(&dictionary); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
response.FailWithMessage("更新失败", c)
} else {
@@ -73,13 +75,13 @@ func UpdateSysDictionary(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysDictionary true "ID或字典英名"
// @Param data body system.SysDictionary true "ID或字典英名"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /sysDictionary/findSysDictionary [get]
func FindSysDictionary(c *gin.Context) {
var dictionary model.SysDictionary
func (s *DictionaryApi) FindSysDictionary(c *gin.Context) {
var dictionary system.SysDictionary
_ = c.ShouldBindQuery(&dictionary)
if err, sysDictionary := service.GetSysDictionary(dictionary.Type, dictionary.ID); err != nil {
if err, sysDictionary := dictionaryService.GetSysDictionary(dictionary.Type, dictionary.ID); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Any("err", err))
response.FailWithMessage("查询失败", c)
} else {
@@ -95,14 +97,14 @@ func FindSysDictionary(c *gin.Context) {
// @Param data body request.SysDictionarySearch true "页码, 每页大小, 搜索条件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysDictionary/getSysDictionaryList [get]
func GetSysDictionaryList(c *gin.Context) {
func (s *DictionaryApi) GetSysDictionaryList(c *gin.Context) {
var pageInfo request.SysDictionarySearch
_ = c.ShouldBindQuery(&pageInfo)
if err := utils.Verify(pageInfo.PageInfo, utils.PageInfoVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, list, total := service.GetSysDictionaryInfoList(pageInfo); err != nil {
if err, list, total := dictionaryService.GetSysDictionaryInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
@@ -1,28 +1,30 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
"gin-vue-admin/model/system/request"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type DictionaryDetailApi struct {
}
// @Tags SysDictionaryDetail
// @Summary 创建SysDictionaryDetail
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysDictionaryDetail true "SysDictionaryDetail模型"
// @Param data body system.SysDictionaryDetail true "SysDictionaryDetail模型"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /sysDictionaryDetail/createSysDictionaryDetail [post]
func CreateSysDictionaryDetail(c *gin.Context) {
var detail model.SysDictionaryDetail
func (s *DictionaryDetailApi) CreateSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
_ = c.ShouldBindJSON(&detail)
if err := service.CreateSysDictionaryDetail(detail); err != nil {
if err := dictionaryDetailService.CreateSysDictionaryDetail(detail); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
response.FailWithMessage("创建失败", c)
} else {
@@ -35,13 +37,13 @@ func CreateSysDictionaryDetail(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysDictionaryDetail true "SysDictionaryDetail模型"
// @Param data body system.SysDictionaryDetail true "SysDictionaryDetail模型"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysDictionaryDetail/deleteSysDictionaryDetail [delete]
func DeleteSysDictionaryDetail(c *gin.Context) {
var detail model.SysDictionaryDetail
func (s *DictionaryDetailApi) DeleteSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
_ = c.ShouldBindJSON(&detail)
if err := service.DeleteSysDictionaryDetail(detail); err != nil {
if err := dictionaryDetailService.DeleteSysDictionaryDetail(detail); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
@@ -54,13 +56,13 @@ func DeleteSysDictionaryDetail(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysDictionaryDetail true "更新SysDictionaryDetail"
// @Param data body system.SysDictionaryDetail true "更新SysDictionaryDetail"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /sysDictionaryDetail/updateSysDictionaryDetail [put]
func UpdateSysDictionaryDetail(c *gin.Context) {
var detail model.SysDictionaryDetail
func (s *DictionaryDetailApi) UpdateSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
_ = c.ShouldBindJSON(&detail)
if err := service.UpdateSysDictionaryDetail(&detail); err != nil {
if err := dictionaryDetailService.UpdateSysDictionaryDetail(&detail); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
response.FailWithMessage("更新失败", c)
} else {
@@ -73,17 +75,17 @@ func UpdateSysDictionaryDetail(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysDictionaryDetail true "用id查询SysDictionaryDetail"
// @Param data body system.SysDictionaryDetail true "用id查询SysDictionaryDetail"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /sysDictionaryDetail/findSysDictionaryDetail [get]
func FindSysDictionaryDetail(c *gin.Context) {
var detail model.SysDictionaryDetail
func (s *DictionaryDetailApi) FindSysDictionaryDetail(c *gin.Context) {
var detail system.SysDictionaryDetail
_ = c.ShouldBindQuery(&detail)
if err := utils.Verify(detail, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, resysDictionaryDetail := service.GetSysDictionaryDetail(detail.ID); err != nil {
if err, resysDictionaryDetail := dictionaryDetailService.GetSysDictionaryDetail(detail.ID); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Any("err", err))
response.FailWithMessage("查询失败", c)
} else {
@@ -99,10 +101,10 @@ func FindSysDictionaryDetail(c *gin.Context) {
// @Param data body request.SysDictionaryDetailSearch true "页码, 每页大小, 搜索条件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysDictionaryDetail/getSysDictionaryDetailList [get]
func GetSysDictionaryDetailList(c *gin.Context) {
func (s *DictionaryDetailApi) GetSysDictionaryDetailList(c *gin.Context) {
var pageInfo request.SysDictionaryDetailSearch
_ = c.ShouldBindQuery(&pageInfo)
if err, list, total := service.GetSysDictionaryDetailInfoList(pageInfo); err != nil {
if err, list, total := dictionaryDetailService.GetSysDictionaryDetailInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
@@ -1,9 +1,8 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
@@ -14,8 +13,8 @@ import (
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
// @Router /email/emailTest [post]
func EmailTest(c *gin.Context) {
if err := service.EmailTest(); err != nil {
func (s *SystemApi) EmailTest(c *gin.Context) {
if err := emailService.EmailTest(); err != nil {
global.GVA_LOG.Error("发送失败!", zap.Any("err", err))
response.FailWithMessage("发送失败", c)
} else {
@@ -1,36 +1,38 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system/request"
"go.uber.org/zap"
"github.com/gin-gonic/gin"
)
type DBApi struct {
}
// @Tags InitDB
// @Summary 初始化用户数据库
// @Produce application/json
// @Param data body request.InitDB true "初始化数据库参数"
// @Success 200 {string} string "{"code":0,"data":{},"msg":"自动创建数据库成功"}"
// @Router /init/initdb [post]
func InitDB(c *gin.Context) {
func (i *DBApi) InitDB(c *gin.Context) {
if global.GVA_DB != nil {
global.GVA_LOG.Error("非法访问")
response.FailWithMessage("非法访问", c)
global.GVA_LOG.Error("已存在数据库配置!")
response.FailWithMessage("已存在数据库配置", c)
return
}
var dbInfo request.InitDB
if err := c.ShouldBindJSON(&dbInfo); err != nil {
global.GVA_LOG.Error("参数校验不通过", zap.Any("err", err))
global.GVA_LOG.Error("参数校验不通过!", zap.Any("err", err))
response.FailWithMessage("参数校验不通过", c)
return
}
if err := service.InitDB(dbInfo); err != nil {
global.GVA_LOG.Error("自动创建数据库失败", zap.Any("err", err))
response.FailWithMessage("自动创建数据库失败,请查看后台日志", c)
if err := initDBService.InitDB(dbInfo); err != nil {
global.GVA_LOG.Error("自动创建数据库失败!", zap.Any("err", err))
response.FailWithMessage("自动创建数据库失败,请查看后台日志,检查后在进行初始化", c)
return
}
response.OkWithData("自动创建数据库成功", c)
@@ -41,18 +43,14 @@ func InitDB(c *gin.Context) {
// @Produce application/json
// @Success 200 {string} string "{"code":0,"data":{},"msg":"探测完成"}"
// @Router /init/checkdb [post]
func CheckDB(c *gin.Context) {
func (i *DBApi) CheckDB(c *gin.Context) {
if global.GVA_DB != nil {
global.GVA_LOG.Info("数据库无需初始化")
response.OkWithDetailed(gin.H{
"needInit": false,
}, "数据库无需初始化", c)
response.OkWithDetailed(gin.H{"needInit": false}, "数据库无需初始化", c)
return
} else {
global.GVA_LOG.Info("前往初始化数据库")
response.OkWithDetailed(gin.H{
"needInit": true,
}, "前往初始化数据库", c)
response.OkWithDetailed(gin.H{"needInit": true}, "前往初始化数据库", c)
return
}
}
@@ -1,14 +1,16 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type JwtApi struct {
}
// @Tags Jwt
// @Summary jwt加入黑名单
// @Security ApiKeyAuth
@@ -16,10 +18,10 @@ import (
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"拉黑成功"}"
// @Router /jwt/jsonInBlacklist [post]
func JsonInBlacklist(c *gin.Context) {
func (j *JwtApi) JsonInBlacklist(c *gin.Context) {
token := c.Request.Header.Get("x-token")
jwt := model.JwtBlacklist{Jwt: token}
if err := service.JsonInBlacklist(jwt); err != nil {
jwt := system.JwtBlacklist{Jwt: token}
if err := jwtService.JsonInBlacklist(jwt); err != nil {
global.GVA_LOG.Error("jwt作废失败!", zap.Any("err", err))
response.FailWithMessage("jwt作废失败", c)
} else {
@@ -1,17 +1,21 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
systemReq "gin-vue-admin/model/system/request"
systemRes "gin-vue-admin/model/system/response"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AuthorityMenuApi struct {
}
// @Tags AuthorityMenu
// @Summary 获取用户动态路由
// @Security ApiKeyAuth
@@ -19,12 +23,15 @@ import (
// @Param data body request.Empty true "空"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /menu/getMenu [post]
func GetMenu(c *gin.Context) {
if err, menus := service.GetMenuTree(getUserAuthorityId(c)); err != nil {
func (a *AuthorityMenuApi) GetMenu(c *gin.Context) {
if err, menus := menuService.GetMenuTree(utils.GetUserAuthorityId(c)); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.SysMenusResponse{Menus: menus}, "获取成功", c)
if menus == nil {
menus = []system.SysMenu{}
}
response.OkWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取成功", c)
}
}
@@ -35,12 +42,12 @@ func GetMenu(c *gin.Context) {
// @Param data body request.Empty true "空"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /menu/getBaseMenuTree [post]
func GetBaseMenuTree(c *gin.Context) {
if err, menus := service.GetBaseMenuTree(); err != nil {
func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) {
if err, menus := menuService.GetBaseMenuTree(); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.SysBaseMenusResponse{Menus: menus}, "获取成功", c)
response.OkWithDetailed(systemRes.SysBaseMenusResponse{Menus: menus}, "获取成功", c)
}
}
@@ -49,17 +56,17 @@ func GetBaseMenuTree(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.AddMenuAuthorityInfo true "角色ID"
// @Param data body systemReq.AddMenuAuthorityInfo true "角色ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"添加成功"}"
// @Router /menu/addMenuAuthority [post]
func AddMenuAuthority(c *gin.Context) {
var authorityMenu request.AddMenuAuthorityInfo
func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) {
var authorityMenu systemReq.AddMenuAuthorityInfo
_ = c.ShouldBindJSON(&authorityMenu)
if err := utils.Verify(authorityMenu, utils.AuthorityIdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.AddMenuAuthority(authorityMenu.Menus, authorityMenu.AuthorityId); err != nil {
if err := menuService.AddMenuAuthority(authorityMenu.Menus, authorityMenu.AuthorityId); err != nil {
global.GVA_LOG.Error("添加失败!", zap.Any("err", err))
response.FailWithMessage("添加失败", c)
} else {
@@ -75,16 +82,16 @@ func AddMenuAuthority(c *gin.Context) {
// @Param data body request.GetAuthorityId true "角色ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /menu/GetMenuAuthority [post]
func GetMenuAuthority(c *gin.Context) {
func (a *AuthorityMenuApi) GetMenuAuthority(c *gin.Context) {
var param request.GetAuthorityId
_ = c.ShouldBindJSON(&param)
if err := utils.Verify(param, utils.AuthorityIdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, menus := service.GetMenuAuthority(&param); err != nil {
if err, menus := menuService.GetMenuAuthority(&param); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithDetailed(response.SysMenusResponse{Menus: menus}, "获取失败", c)
response.FailWithDetailed(systemRes.SysMenusResponse{Menus: menus}, "获取失败", c)
} else {
response.OkWithDetailed(gin.H{"menus": menus}, "获取成功", c)
}
@@ -95,11 +102,11 @@ func GetMenuAuthority(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Param data body system.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"添加成功"}"
// @Router /menu/addBaseMenu [post]
func AddBaseMenu(c *gin.Context) {
var menu model.SysBaseMenu
func (a *AuthorityMenuApi) AddBaseMenu(c *gin.Context) {
var menu system.SysBaseMenu
_ = c.ShouldBindJSON(&menu)
if err := utils.Verify(menu, utils.MenuVerify); err != nil {
response.FailWithMessage(err.Error(), c)
@@ -109,7 +116,7 @@ func AddBaseMenu(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.AddBaseMenu(menu); err != nil {
if err := menuService.AddBaseMenu(menu); err != nil {
global.GVA_LOG.Error("添加失败!", zap.Any("err", err))
response.FailWithMessage("添加失败", c)
@@ -126,14 +133,14 @@ func AddBaseMenu(c *gin.Context) {
// @Param data body request.GetById true "菜单id"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /menu/deleteBaseMenu [post]
func DeleteBaseMenu(c *gin.Context) {
func (a *AuthorityMenuApi) DeleteBaseMenu(c *gin.Context) {
var menu request.GetById
_ = c.ShouldBindJSON(&menu)
if err := utils.Verify(menu, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.DeleteBaseMenu(menu.ID); err != nil {
if err := baseMenuService.DeleteBaseMenu(menu.ID); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
@@ -146,11 +153,11 @@ func DeleteBaseMenu(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Param data body system.SysBaseMenu true "路由path, 父菜单ID, 路由name, 对应前端文件路径, 排序标记"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /menu/updateBaseMenu [post]
func UpdateBaseMenu(c *gin.Context) {
var menu model.SysBaseMenu
func (a *AuthorityMenuApi) UpdateBaseMenu(c *gin.Context) {
var menu system.SysBaseMenu
_ = c.ShouldBindJSON(&menu)
if err := utils.Verify(menu, utils.MenuVerify); err != nil {
response.FailWithMessage(err.Error(), c)
@@ -160,7 +167,7 @@ func UpdateBaseMenu(c *gin.Context) {
response.FailWithMessage(err.Error(), c)
return
}
if err := service.UpdateBaseMenu(menu); err != nil {
if err := baseMenuService.UpdateBaseMenu(menu); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
response.FailWithMessage("更新失败", c)
} else {
@@ -176,18 +183,18 @@ func UpdateBaseMenu(c *gin.Context) {
// @Param data body request.GetById true "菜单id"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /menu/getBaseMenuById [post]
func GetBaseMenuById(c *gin.Context) {
func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) {
var idInfo request.GetById
_ = c.ShouldBindJSON(&idInfo)
if err := utils.Verify(idInfo, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, menu := service.GetBaseMenuById(idInfo.ID); err != nil {
if err, menu := baseMenuService.GetBaseMenuById(idInfo.ID); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.SysBaseMenuResponse{Menu: menu}, "获取成功", c)
response.OkWithDetailed(systemRes.SysBaseMenuResponse{Menu: menu}, "获取成功", c)
}
}
@@ -199,14 +206,14 @@ func GetBaseMenuById(c *gin.Context) {
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /menu/getMenuList [post]
func GetMenuList(c *gin.Context) {
func (a *AuthorityMenuApi) GetMenuList(c *gin.Context) {
var pageInfo request.PageInfo
_ = c.ShouldBindJSON(&pageInfo)
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, menuList, total := service.GetInfoList(); err != nil {
if err, menuList, total := menuService.GetInfoList(); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
@@ -1,28 +1,31 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
systemReq "gin-vue-admin/model/system/request"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type OperationRecordApi struct {
}
// @Tags SysOperationRecord
// @Summary 创建SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "创建SysOperationRecord"
// @Param data body system.SysOperationRecord true "创建SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysOperationRecord/createSysOperationRecord [post]
func CreateSysOperationRecord(c *gin.Context) {
var sysOperationRecord model.SysOperationRecord
func (s *OperationRecordApi) CreateSysOperationRecord(c *gin.Context) {
var sysOperationRecord system.SysOperationRecord
_ = c.ShouldBindJSON(&sysOperationRecord)
if err := service.CreateSysOperationRecord(sysOperationRecord); err != nil {
if err := operationRecordService.CreateSysOperationRecord(sysOperationRecord); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
response.FailWithMessage("创建失败", c)
} else {
@@ -35,13 +38,13 @@ func CreateSysOperationRecord(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "SysOperationRecord模型"
// @Param data body system.SysOperationRecord true "SysOperationRecord模型"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
func DeleteSysOperationRecord(c *gin.Context) {
var sysOperationRecord model.SysOperationRecord
func (s *OperationRecordApi) DeleteSysOperationRecord(c *gin.Context) {
var sysOperationRecord system.SysOperationRecord
_ = c.ShouldBindJSON(&sysOperationRecord)
if err := service.DeleteSysOperationRecord(sysOperationRecord); err != nil {
if err := operationRecordService.DeleteSysOperationRecord(sysOperationRecord); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
@@ -57,10 +60,10 @@ func DeleteSysOperationRecord(c *gin.Context) {
// @Param data body request.IdsReq true "批量删除SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /sysOperationRecord/deleteSysOperationRecordByIds [delete]
func DeleteSysOperationRecordByIds(c *gin.Context) {
func (s *OperationRecordApi) DeleteSysOperationRecordByIds(c *gin.Context) {
var IDS request.IdsReq
_ = c.ShouldBindJSON(&IDS)
if err := service.DeleteSysOperationRecordByIds(IDS); err != nil {
if err := operationRecordService.DeleteSysOperationRecordByIds(IDS); err != nil {
global.GVA_LOG.Error("批量删除失败!", zap.Any("err", err))
response.FailWithMessage("批量删除失败", c)
} else {
@@ -73,17 +76,17 @@ func DeleteSysOperationRecordByIds(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "Id"
// @Param data body system.SysOperationRecord true "Id"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /sysOperationRecord/findSysOperationRecord [get]
func FindSysOperationRecord(c *gin.Context) {
var sysOperationRecord model.SysOperationRecord
func (s *OperationRecordApi) FindSysOperationRecord(c *gin.Context) {
var sysOperationRecord system.SysOperationRecord
_ = c.ShouldBindQuery(&sysOperationRecord)
if err := utils.Verify(sysOperationRecord, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, resysOperationRecord := service.GetSysOperationRecord(sysOperationRecord.ID); err != nil {
if err, resysOperationRecord := operationRecordService.GetSysOperationRecord(sysOperationRecord.ID); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Any("err", err))
response.FailWithMessage("查询失败", c)
} else {
@@ -99,10 +102,10 @@ func FindSysOperationRecord(c *gin.Context) {
// @Param data body request.SysOperationRecordSearch true "页码, 每页大小, 搜索条件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysOperationRecord/getSysOperationRecordList [get]
func GetSysOperationRecordList(c *gin.Context) {
var pageInfo request.SysOperationRecordSearch
func (s *OperationRecordApi) GetSysOperationRecordList(c *gin.Context) {
var pageInfo systemReq.SysOperationRecordSearch
_ = c.ShouldBindQuery(&pageInfo)
if err, list, total := service.GetSysOperationRecordInfoList(pageInfo); err != nil {
if err, list, total := operationRecordService.GetSysOperationRecordInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
@@ -1,28 +1,31 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
systemRes "gin-vue-admin/model/system/response"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type SystemApi struct {
}
// @Tags System
// @Summary 获取配置文件内容
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /system/getSystemConfig [post]
func GetSystemConfig(c *gin.Context) {
if err, config := service.GetSystemConfig(); err != nil {
func (s *SystemApi) GetSystemConfig(c *gin.Context) {
if err, config := systemConfigService.GetSystemConfig(); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.SysConfigResponse{Config: config}, "获取成功", c)
response.OkWithDetailed(systemRes.SysConfigResponse{Config: config}, "获取成功", c)
}
}
@@ -30,13 +33,13 @@ func GetSystemConfig(c *gin.Context) {
// @Summary 设置配置文件内容
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body model.System true "设置配置文件内容"
// @Param data body system.System true "设置配置文件内容"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
// @Router /system/setSystemConfig [post]
func SetSystemConfig(c *gin.Context) {
var sys model.System
func (s *SystemApi) SetSystemConfig(c *gin.Context) {
var sys system.System
_ = c.ShouldBindJSON(&sys)
if err := service.SetSystemConfig(sys); err != nil {
if err := systemConfigService.SetSystemConfig(sys); err != nil {
global.GVA_LOG.Error("设置失败!", zap.Any("err", err))
response.FailWithMessage("设置失败", c)
} else {
@@ -50,15 +53,14 @@ func SetSystemConfig(c *gin.Context) {
// @Produce application/json
// @Success 200 {string} string "{"code":0,"data":{},"msg":"重启系统成功"}"
// @Router /system/reloadSystem [post]
func ReloadSystem(c *gin.Context) {
func (s *SystemApi) ReloadSystem(c *gin.Context) {
err := utils.Reload()
if err != nil {
global.GVA_LOG.Error("重启系统失败!", zap.Any("err", err))
response.FailWithMessage("重启系统失败", c)
return
} else {
response.OkWithMessage("重启系统成功", c)
}
response.OkWithMessage("重启系统成功", c)
return
}
// @Tags System
@@ -67,13 +69,11 @@ func ReloadSystem(c *gin.Context) {
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /system/getServerInfo [post]
func GetServerInfo(c *gin.Context) {
if server, err := service.GetServerInfo(); err != nil {
func (s *SystemApi) GetServerInfo(c *gin.Context) {
if server, err := systemConfigService.GetServerInfo(); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
return
} else {
response.OkWithDetailed(gin.H{"server": server}, "获取成功", c)
}
}
@@ -1,13 +1,15 @@
package v1
package system
import (
"gin-vue-admin/global"
"gin-vue-admin/middleware"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
systemReq "gin-vue-admin/model/system/request"
systemRes "gin-vue-admin/model/system/response"
"gin-vue-admin/utils"
"strconv"
"time"
"github.com/dgrijalva/jwt-go"
@@ -19,23 +21,23 @@ import (
// @Tags Base
// @Summary 用户登录
// @Produce application/json
// @Param data body request.Login true "用户名, 密码, 验证码"
// @Param data body systemReq.Login true "用户名, 密码, 验证码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"登陆成功"}"
// @Router /base/login [post]
func Login(c *gin.Context) {
var L request.Login
_ = c.ShouldBindJSON(&L)
if err := utils.Verify(L, utils.LoginVerify); err != nil {
func (b *BaseApi) Login(c *gin.Context) {
var l systemReq.Login
_ = c.ShouldBindJSON(&l)
if err := utils.Verify(l, utils.LoginVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if store.Verify(L.CaptchaId, L.Captcha, true) {
U := &model.SysUser{Username: L.Username, Password: L.Password}
if err, user := service.Login(U); err != nil {
global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误", zap.Any("err", err))
if store.Verify(l.CaptchaId, l.Captcha, true) {
u := &system.SysUser{Username: l.Username, Password: l.Password}
if err, user := userService.Login(u); err != nil {
global.GVA_LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Any("err", err))
response.FailWithMessage("用户名不存在或者密码错误", c)
} else {
tokenNext(c, *user)
b.tokenNext(c, *user)
}
} else {
response.FailWithMessage("验证码错误", c)
@@ -43,9 +45,9 @@ func Login(c *gin.Context) {
}
// 登录以后签发jwt
func tokenNext(c *gin.Context, user model.SysUser) {
func (b *BaseApi) tokenNext(c *gin.Context, user system.SysUser) {
j := &middleware.JWT{SigningKey: []byte(global.GVA_CONFIG.JWT.SigningKey)} // 唯一签名
claims := request.CustomClaims{
claims := systemReq.CustomClaims{
UUID: user.UUID,
ID: user.ID,
NickName: user.NickName,
@@ -60,44 +62,44 @@ func tokenNext(c *gin.Context, user model.SysUser) {
}
token, err := j.CreateToken(claims)
if err != nil {
global.GVA_LOG.Error("获取token失败", zap.Any("err", err))
global.GVA_LOG.Error("获取token失败!", zap.Any("err", err))
response.FailWithMessage("获取token失败", c)
return
}
if !global.GVA_CONFIG.System.UseMultipoint {
response.OkWithDetailed(response.LoginResponse{
response.OkWithDetailed(systemRes.LoginResponse{
User: user,
Token: token,
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
}, "登录成功", c)
return
}
if err, jwtStr := service.GetRedisJWT(user.Username); err == redis.Nil {
if err := service.SetRedisJWT(token, user.Username); err != nil {
global.GVA_LOG.Error("设置登录状态失败", zap.Any("err", err))
if err, jwtStr := jwtService.GetRedisJWT(user.Username); err == redis.Nil {
if err := jwtService.SetRedisJWT(token, user.Username); err != nil {
global.GVA_LOG.Error("设置登录状态失败!", zap.Any("err", err))
response.FailWithMessage("设置登录状态失败", c)
return
}
response.OkWithDetailed(response.LoginResponse{
response.OkWithDetailed(systemRes.LoginResponse{
User: user,
Token: token,
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
}, "登录成功", c)
} else if err != nil {
global.GVA_LOG.Error("设置登录状态失败", zap.Any("err", err))
global.GVA_LOG.Error("设置登录状态失败!", zap.Any("err", err))
response.FailWithMessage("设置登录状态失败", c)
} else {
var blackJWT model.JwtBlacklist
var blackJWT system.JwtBlacklist
blackJWT.Jwt = jwtStr
if err := service.JsonInBlacklist(blackJWT); err != nil {
if err := jwtService.JsonInBlacklist(blackJWT); err != nil {
response.FailWithMessage("jwt作废失败", c)
return
}
if err := service.SetRedisJWT(token, user.Username); err != nil {
if err := jwtService.SetRedisJWT(token, user.Username); err != nil {
response.FailWithMessage("设置登录状态失败", c)
return
}
response.OkWithDetailed(response.LoginResponse{
response.OkWithDetailed(systemRes.LoginResponse{
User: user,
Token: token,
ExpiresAt: claims.StandardClaims.ExpiresAt * 1000,
@@ -108,23 +110,29 @@ func tokenNext(c *gin.Context, user model.SysUser) {
// @Tags SysUser
// @Summary 用户注册账号
// @Produce application/json
// @Param data body model.SysUser true "用户名, 昵称, 密码, 角色ID"
// @Param data body systemReq.Register true "用户名, 昵称, 密码, 角色ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"注册成功"}"
// @Router /user/register [post]
func Register(c *gin.Context) {
var R request.Register
_ = c.ShouldBindJSON(&R)
if err := utils.Verify(R, utils.RegisterVerify); err != nil {
func (b *BaseApi) Register(c *gin.Context) {
var r systemReq.Register
_ = c.ShouldBindJSON(&r)
if err := utils.Verify(r, utils.RegisterVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
user := &model.SysUser{Username: R.Username, NickName: R.NickName, Password: R.Password, HeaderImg: R.HeaderImg, AuthorityId: R.AuthorityId}
err, userReturn := service.Register(*user)
var authorities []system.SysAuthority
for _, v := range r.AuthorityIds {
authorities = append(authorities, system.SysAuthority{
AuthorityId: v,
})
}
user := &system.SysUser{Username: r.Username, NickName: r.NickName, Password: r.Password, HeaderImg: r.HeaderImg, AuthorityId: r.AuthorityId, Authorities: authorities}
err, userReturn := userService.Register(*user)
if err != nil {
global.GVA_LOG.Error("注册失败", zap.Any("err", err))
response.FailWithDetailed(response.SysUserResponse{User: userReturn}, "注册失败", c)
global.GVA_LOG.Error("注册失败!", zap.Any("err", err))
response.FailWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册失败", c)
} else {
response.OkWithDetailed(response.SysUserResponse{User: userReturn}, "注册成功", c)
response.OkWithDetailed(systemRes.SysUserResponse{User: userReturn}, "注册成功", c)
}
}
@@ -132,19 +140,19 @@ func Register(c *gin.Context) {
// @Summary 用户修改密码
// @Security ApiKeyAuth
// @Produce application/json
// @Param data body request.ChangePasswordStruct true "用户名, 原密码, 新密码"
// @Param data body systemReq.ChangePasswordStruct true "用户名, 原密码, 新密码"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
// @Router /user/changePassword [put]
func ChangePassword(c *gin.Context) {
var user request.ChangePasswordStruct
func (b *BaseApi) ChangePassword(c *gin.Context) {
var user systemReq.ChangePasswordStruct
_ = c.ShouldBindJSON(&user)
if err := utils.Verify(user, utils.ChangePasswordVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
U := &model.SysUser{Username: user.Username, Password: user.Password}
if err, _ := service.ChangePassword(U, user.NewPassword); err != nil {
global.GVA_LOG.Error("修改失败", zap.Any("err", err))
u := &system.SysUser{Username: user.Username, Password: user.Password}
if err, _ := userService.ChangePassword(u, user.NewPassword); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Any("err", err))
response.FailWithMessage("修改失败,原密码与当前账户不符", c)
} else {
response.OkWithMessage("修改成功", c)
@@ -159,15 +167,15 @@ func ChangePassword(c *gin.Context) {
// @Param data body request.PageInfo true "页码, 每页大小"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /user/getUserList [post]
func GetUserList(c *gin.Context) {
func (b *BaseApi) GetUserList(c *gin.Context) {
var pageInfo request.PageInfo
_ = c.ShouldBindJSON(&pageInfo)
if err := utils.Verify(pageInfo, utils.PageInfoVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, list, total := service.GetUserInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败", zap.Any("err", err))
if err, list, total := userService.GetUserInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
@@ -180,22 +188,54 @@ func GetUserList(c *gin.Context) {
}
// @Tags SysUser
// @Summary 设置用户权限
// @Summary 更改用户权限
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SetUserAuth true "用户UUID, 角色ID"
// @Param data body systemReq.SetUserAuth true "用户UUID, 角色ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
// @Router /user/setUserAuthority [post]
func SetUserAuthority(c *gin.Context) {
var sua request.SetUserAuth
func (b *BaseApi) SetUserAuthority(c *gin.Context) {
var sua systemReq.SetUserAuth
_ = c.ShouldBindJSON(&sua)
if UserVerifyErr := utils.Verify(sua, utils.SetUserAuthorityVerify); UserVerifyErr != nil {
response.FailWithMessage(UserVerifyErr.Error(), c)
return
}
if err := service.SetUserAuthority(sua.UUID, sua.AuthorityId); err != nil {
global.GVA_LOG.Error("修改失败", zap.Any("err", err))
userID := utils.GetUserID(c)
uuid := utils.GetUserUuid(c)
if err := userService.SetUserAuthority(userID, uuid, sua.AuthorityId); err != nil {
global.GVA_LOG.Error("修改失败!", zap.Any("err", err))
response.FailWithMessage(err.Error(), c)
} else {
claims := utils.GetUserInfo(c)
j := &middleware.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.Any("err", 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 {string} string "{"success":true,"data":{},"msg":"修改成功"}"
// @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.Any("err", err))
response.FailWithMessage("修改失败", c)
} else {
response.OkWithMessage("修改成功", c)
@@ -210,19 +250,19 @@ func SetUserAuthority(c *gin.Context) {
// @Param data body request.GetById true "用户ID"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /user/deleteUser [delete]
func DeleteUser(c *gin.Context) {
func (b *BaseApi) DeleteUser(c *gin.Context) {
var reqId request.GetById
_ = c.ShouldBindJSON(&reqId)
if err := utils.Verify(reqId, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
jwtId := getUserID(c)
jwtId := utils.GetUserID(c)
if jwtId == uint(reqId.ID) {
response.FailWithMessage("删除失败, 自杀失败", c)
return
}
if err := service.DeleteUser(reqId.ID); err != nil {
if err := userService.DeleteUser(reqId.ID); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
@@ -235,53 +275,37 @@ func DeleteUser(c *gin.Context) {
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysUser true "ID, 用户名, 昵称, 头像链接"
// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"
// @Router /user/setUserInfo [put]
func SetUserInfo(c *gin.Context) {
var user model.SysUser
func (b *BaseApi) SetUserInfo(c *gin.Context) {
var user system.SysUser
_ = c.ShouldBindJSON(&user)
if err := utils.Verify(user, utils.IdVerify); err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if err, ReqUser := service.SetUserInfo(user); err != nil {
global.GVA_LOG.Error("设置失败", zap.Any("err", err))
if err, ReqUser := userService.SetUserInfo(user); err != nil {
global.GVA_LOG.Error("设置失败!", zap.Any("err", err))
response.FailWithMessage("设置失败", c)
} else {
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c)
}
}
// 从Gin的Context中获取从jwt解析出来的用户ID
func getUserID(c *gin.Context) uint {
if claims, exists := c.Get("claims"); !exists {
global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户ID失败, 请检查路由是否使用jwt中间件")
return 0
// @Tags SysUser
// @Summary 获取用户信息
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /user/getUserInfo [get]
func (b *BaseApi) GetUserInfo(c *gin.Context) {
uuid := utils.GetUserUuid(c)
if err, ReqUser := userService.GetUserInfo(uuid); err != nil {
global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
waitUse := claims.(*request.CustomClaims)
return waitUse.ID
}
}
// 从Gin的Context中获取从jwt解析出来的用户UUID
func getUserUuid(c *gin.Context) string {
if claims, exists := c.Get("claims"); !exists {
global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件")
return ""
} else {
waitUse := claims.(*request.CustomClaims)
return waitUse.UUID.String()
}
}
// 从Gin的Context中获取从jwt解析出来的用户角色id
func getUserAuthorityId(c *gin.Context) string {
if claims, exists := c.Get("claims"); !exists {
global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件")
return ""
} else {
waitUse := claims.(*request.CustomClaims)
return waitUse.AuthorityId
response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "获取成功", c)
}
}
+132
View File
@@ -0,0 +1,132 @@
# Gin-Vue-Admin Global Configuration
# jwt configuration
jwt:
signing-key: 'qmPlus'
expires-time: 604800
buffer-time: 86400
# zap logger configuration
zap:
level: 'info'
format: 'console'
prefix: '[GIN-VUE-ADMIN]'
director: 'log'
link-name: 'latest_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'
password: ''
# email configuration
email:
to: 'xxx@qq.com'
port: 465
from: 'xxx@163.com'
host: 'smtp.163.com'
is-ssl: true
secret: 'xxx'
nickname: 'test'
# casbin configuration
casbin:
model-path: './resource/rbac_model.conf'
# system configuration
system:
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函数配置
use-multipoint: false
# captcha configuration
captcha:
key-long: 6
img-width: 240
img-height: 80
# mysql connect configuration
mysql:
path: ''
config: ''
db-name: ''
username: ''
password: ''
max-idle-conns: 10
max-open-conns: 100
log-mode: ""
log-zap: false
# local configuration
local:
path: 'uploads/file'
# autocode configuration
autocode:
transfer-restart: true
root: ""
server: /server
server-api: /api/v1
server-initialize: /initialize
server-model: /model
server-request: /model/request/
server-router: /router
server-service: /service
web: /web/src
web-api: /api
web-flow: /view
web-form: /view
web-table: /view
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu:
zone: 'ZoneHuaDong'
bucket: ''
img-path: ''
use-https: false
access-key: ''
secret-key: ''
use-cdn-domains: false
# aliyun oss configuration
aliyun-oss:
endpoint: 'yourEndpoint'
access-key-id: 'yourAccessKeyId'
access-key-secret: 'yourAccessKeySecret'
bucket-name: 'yourBucketName'
bucket-url: 'yourBucketUrl'
# 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: 'gin-vue-admin'
# excel configuration
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: 需要清理的表名
# compareField: 需要比较时间的字段
# interval: 时间间隔, 具体配置详看 time.ParseDuration() 中字符串表示 且不能为负数
# 2160h = 24 * 30 * 3 -> 三个月
{ tableName: "sys_operation_records" , compareField: "created_at", interval: "2160h" },
#{ tableName: "log2" , compareField: "created_at", interval: "2160h" }
]
+7 -5
View File
@@ -53,6 +53,7 @@ captcha:
img-height: 80
# mysql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://www.gin-vue-admin.com/docs/first)
mysql:
path: ''
config: ''
@@ -73,12 +74,12 @@ autocode:
transfer-restart: true
root: ""
server: /server
server-api: /api/v1
server-api: /api/v1/autocode
server-initialize: /initialize
server-model: /model
server-request: /model/request/
server-router: /router
server-service: /service
server-model: /model/autocode
server-request: /model/autocode/request/
server-router: /router/autocode
server-service: /service/autocode
web: /web/src
web-api: /api
web-flow: /view
@@ -103,6 +104,7 @@ aliyun-oss:
access-key-secret: 'yourAccessKeySecret'
bucket-name: 'yourBucketName'
bucket-url: 'yourBucketUrl'
base-path: 'yourBasePath'
# tencent cos configuration
tencent-cos:
+2 -2
View File
@@ -8,8 +8,8 @@ type Mysql struct {
Password string `mapstructure:"password" json:"password" yaml:"password"` // 数据库密码
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"` // 空闲中的最大连接数
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"` // 打开到数据库的最大连接数
LogMode bool `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志
LogZap string `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"`
LogMode string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志
LogZap bool `mapstructure:"log-zap" json:"logZap" yaml:"log-zap"` // 是否通过zap写入日志文件
}
func (m *Mysql) Dsn() string {
+1
View File
@@ -20,6 +20,7 @@ type AliyunOSS struct {
AccessKeySecret string `mapstructure:"access-key-secret" json:"accessKeySecret" yaml:"access-key-secret"`
BucketName string `mapstructure:"bucket-name" json:"bucketName" yaml:"bucket-name"`
BucketUrl string `mapstructure:"bucket-url" json:"bucketUrl" yaml:"bucket-url"`
BasePath string `mapstructure:"base-path" json:"basePath" yaml:"base-path"`
}
type TencentCOS struct {
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
+1 -1
View File
@@ -29,7 +29,7 @@ func RunWindowsServer() {
fmt.Printf(`
欢迎使用 Gin-Vue-Admin
当前版本:V2.4.2
当前版本:V2.4.4
加群方式:微信号:shouzi_1994 QQ群:622360840
默认自动化文档地址:http://127.0.0.1%s/swagger/index.html
默认前端文件运行地址:http://127.0.0.1:8080
+1063 -608
View File
File diff suppressed because it is too large Load Diff
+1062 -606
View File
File diff suppressed because it is too large Load Diff
+724 -437
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -3,11 +3,13 @@ package global
import (
"gin-vue-admin/utils/timer"
"golang.org/x/sync/singleflight"
"go.uber.org/zap"
"gin-vue-admin/config"
"github.com/go-redis/redis"
"github.com/go-redis/redis/v8"
"github.com/spf13/viper"
"gorm.io/gorm"
)
@@ -18,6 +20,7 @@ var (
GVA_CONFIG config.Server
GVA_VP *viper.Viper
//GVA_LOG *oplogging.Logger
GVA_LOG *zap.Logger
GVA_Timer timer.Timer = timer.NewTimerTask()
GVA_LOG *zap.Logger
GVA_Timer timer.Timer = timer.NewTimerTask()
GVA_Concurrency_Control = &singleflight.Group{}
)
+13 -10
View File
@@ -10,33 +10,34 @@ require (
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/casbin/casbin/v2 v2.11.0
github.com/casbin/gorm-adapter/v3 v3.0.2
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
github.com/fsnotify/fsnotify v1.4.9
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
github.com/gin-gonic/gin v1.6.3
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/go-openapi/spec v0.19.7 // indirect
github.com/go-openapi/swag v0.19.8 // indirect
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-playground/validator/v10 v10.3.0 // indirect
github.com/go-redis/redis v6.15.7+incompatible
github.com/go-redis/redis/v8 v8.11.0
github.com/go-sql-driver/mysql v1.5.0
github.com/golang/protobuf v1.4.2 // indirect
github.com/gookit/color v1.3.1
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
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.3.0+incompatible
github.com/lestrrat-go/strftime v1.0.3 // indirect
github.com/mailru/easyjson v0.7.1 // 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/onsi/ginkgo v1.7.0 // indirect
github.com/onsi/gomega v1.4.3 // indirect
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/qiniu/api.v7/v7 v7.4.1
github.com/robfig/cron/v3 v3.0.1
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/satori/go.uuid v1.2.0
github.com/shirou/gopsutil v3.21.1+incompatible
github.com/spf13/afero v1.2.2 // indirect
@@ -44,17 +45,19 @@ require (
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/swaggo/gin-swagger v1.2.0
github.com/swaggo/swag v1.6.7
github.com/swaggo/gin-swagger v1.3.0
github.com/swaggo/swag v1.7.0
github.com/tebeka/strftime v0.1.3 // indirect
github.com/tencentyun/cos-go-sdk-v5 v0.7.19
github.com/unrolled/secure v1.0.7
go.uber.org/zap v1.10.0
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
golang.org/x/tools v0.0.0-20200324003944-a576cf524670 // indirect
golang.org/x/net v0.0.0-20210716203947-853a461950ff // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
golang.org/x/tools v0.1.5 // indirect
google.golang.org/protobuf v1.24.0 // indirect
gopkg.in/ini.v1 v1.55.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
gorm.io/driver/mysql v1.0.1
gorm.io/gorm v1.20.7
)
+24 -28
View File
@@ -3,7 +3,9 @@ package initialize
import (
"gin-vue-admin/global"
"gin-vue-admin/initialize/internal"
"gin-vue-admin/model"
"gin-vue-admin/model/autocode"
"gin-vue-admin/model/example"
"gin-vue-admin/model/system"
"os"
"go.uber.org/zap"
@@ -34,22 +36,23 @@ func Gorm() *gorm.DB {
func MysqlTables(db *gorm.DB) {
err := db.AutoMigrate(
model.SysUser{},
model.SysAuthority{},
model.SysApi{},
model.SysBaseMenu{},
model.SysBaseMenuParameter{},
model.JwtBlacklist{},
model.SysDictionary{},
model.SysDictionaryDetail{},
model.ExaFileUploadAndDownload{},
model.ExaFile{},
model.ExaFileChunk{},
model.ExaSimpleUploader{},
model.ExaCustomer{},
model.SysOperationRecord{},
system.SysUser{},
system.SysAuthority{},
system.SysApi{},
system.SysBaseMenu{},
system.SysBaseMenuParameter{},
system.JwtBlacklist{},
system.SysDictionary{},
system.SysDictionaryDetail{},
example.ExaFileUploadAndDownload{},
example.ExaFile{},
example.ExaFileChunk{},
example.ExaSimpleUploader{},
example.ExaCustomer{},
system.SysOperationRecord{},
system.SysAutoCodeHistory{},
// Code generated by gin-vue-admin Begin; DO NOT EDIT.
autocode.AutoCodeExample{},
// Code generated by gin-vue-admin End; DO NOT EDIT.
)
if err != nil {
@@ -59,7 +62,6 @@ func MysqlTables(db *gorm.DB) {
global.GVA_LOG.Info("register table success")
}
//
//@author: SliverHorn
//@function: GormMysql
//@description: 初始化Mysql数据库
@@ -79,7 +81,7 @@ func GormMysql() *gorm.DB {
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据版本自动配置
}
if db, err := gorm.Open(mysql.New(mysqlConfig), gormConfig(m.LogMode)); err != nil {
if db, err := gorm.Open(mysql.New(mysqlConfig), gormConfig()); err != nil {
//global.GVA_LOG.Error("MySQL启动异常", zap.Any("err", err))
//os.Exit(0)
//return nil
@@ -98,9 +100,9 @@ func GormMysql() *gorm.DB {
//@param: mod bool
//@return: *gorm.Config
func gormConfig(mod bool) *gorm.Config {
var config = &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
switch global.GVA_CONFIG.Mysql.LogZap {
func gormConfig() *gorm.Config {
config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
switch global.GVA_CONFIG.Mysql.LogMode {
case "silent", "Silent":
config.Logger = internal.Default.LogMode(logger.Silent)
case "error", "Error":
@@ -109,14 +111,8 @@ func gormConfig(mod bool) *gorm.Config {
config.Logger = internal.Default.LogMode(logger.Warn)
case "info", "Info":
config.Logger = internal.Default.LogMode(logger.Info)
case "zap", "Zap":
config.Logger = internal.Default.LogMode(logger.Info)
default:
if mod {
config.Logger = internal.Default.LogMode(logger.Info)
break
}
config.Logger = internal.Default.LogMode(logger.Silent)
config.Logger = internal.Default.LogMode(logger.Info)
}
return config
}
+21 -51
View File
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"gin-vue-admin/global"
"go.uber.org/zap"
"gorm.io/gorm/logger"
"gorm.io/gorm/utils"
"io/ioutil"
@@ -13,11 +12,6 @@ import (
"time"
)
// writer log writer interface
type writer interface {
Printf(string, ...interface{})
}
type config struct {
SlowThreshold time.Duration
Colorful bool
@@ -34,27 +28,27 @@ var (
Recorder = traceRecorder{Interface: Default, BeginAt: time.Now()}
)
func New(writer writer, config config) logger.Interface {
func New(writer logger.Writer, config config) logger.Interface {
var (
infoStr = "%s\n[info] "
warnStr = "%s\n[warn] "
errStr = "%s\n[error] "
traceStr = "%s\n[%.3fms] [rows:%v] %s"
traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s"
traceErrStr = "%s %s\n[%.3fms] [rows:%v] %s"
traceStr = "%s\n[%.3fms] [rows:%v] %s\n"
traceWarnStr = "%s %s\n[%.3fms] [rows:%v] %s\n"
traceErrStr = "%s %s\n[%.3fms] [rows:%v] %s\n"
)
if config.Colorful {
infoStr = logger.Green + "%s\n" + logger.Reset + logger.Green + "[info] " + logger.Reset
warnStr = logger.BlueBold + "%s\n" + logger.Reset + logger.Magenta + "[warn] " + logger.Reset
errStr = logger.Magenta + "%s\n" + logger.Reset + logger.Red + "[error] " + logger.Reset
traceStr = logger.Green + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
traceWarnStr = logger.Green + "%s " + logger.Yellow + "%s\n" + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s" + logger.Reset
traceErrStr = logger.RedBold + "%s " + logger.MagentaBold + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s"
traceStr = logger.Green + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s\n"
traceWarnStr = logger.Green + "%s " + logger.Yellow + "%s\n" + logger.Reset + logger.RedBold + "[%.3fms] " + logger.Yellow + "[rows:%v]" + logger.Magenta + " %s\n" + logger.Reset
traceErrStr = logger.RedBold + "%s " + logger.MagentaBold + "%s\n" + logger.Reset + logger.Yellow + "[%.3fms] " + logger.BlueBold + "[rows:%v]" + logger.Reset + " %s\n"
}
return &customLogger{
writer: writer,
return &_logger{
Writer: writer,
config: config,
infoStr: infoStr,
warnStr: warnStr,
@@ -65,43 +59,43 @@ func New(writer writer, config config) logger.Interface {
}
}
type customLogger struct {
writer
type _logger struct {
config
logger.Writer
infoStr, warnStr, errStr string
traceStr, traceErrStr, traceWarnStr string
}
// LogMode log mode
func (c *customLogger) LogMode(level logger.LogLevel) logger.Interface {
func (c *_logger) LogMode(level logger.LogLevel) logger.Interface {
newLogger := *c
newLogger.LogLevel = level
return &newLogger
}
// Info print info
func (c *customLogger) Info(ctx context.Context, message string, data ...interface{}) {
func (c *_logger) Info(ctx context.Context, message string, data ...interface{}) {
if c.LogLevel >= logger.Info {
c.Printf(c.infoStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
}
}
// Warn print warn messages
func (c *customLogger) Warn(ctx context.Context, message string, data ...interface{}) {
func (c *_logger) Warn(ctx context.Context, message string, data ...interface{}) {
if c.LogLevel >= logger.Warn {
c.Printf(c.warnStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
}
}
// Error print error messages
func (c *customLogger) Error(ctx context.Context, message string, data ...interface{}) {
func (c *_logger) Error(ctx context.Context, message string, data ...interface{}) {
if c.LogLevel >= logger.Error {
c.Printf(c.errStr+message, append([]interface{}{utils.FileWithLineNum()}, data...)...)
}
}
// Trace print sql message
func (c *customLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
func (c *_logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if c.LogLevel > 0 {
elapsed := time.Since(begin)
switch {
@@ -131,35 +125,11 @@ func (c *customLogger) Trace(ctx context.Context, begin time.Time, fc func() (st
}
}
func (c *customLogger) Printf(message string, data ...interface{}) {
if global.GVA_CONFIG.Mysql.LogZap != "" {
switch len(data) {
case 0:
global.GVA_LOG.Info(message)
case 1:
global.GVA_LOG.Info("gorm", zap.Any("src", data[0]))
case 2:
global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]))
case 3:
global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]))
case 4:
global.GVA_LOG.Info("gorm", zap.Any("src", data[0]), zap.Any("duration", data[1]), zap.Any("rows", data[2]), zap.Any("sql", data[3]))
}
return
}
switch len(data) {
case 0:
c.writer.Printf(message, "")
case 1:
c.writer.Printf(message, data[0])
case 2:
c.writer.Printf(message, data[0], data[1])
case 3:
c.writer.Printf(message, data[0], data[1], data[2])
case 4:
c.writer.Printf(message, data[0], data[1], data[2], data[3])
case 5:
c.writer.Printf(message, data[0], data[1], data[2], data[3], data[4])
func (c *_logger) Printf(message string, data ...interface{}) {
if global.GVA_CONFIG.Mysql.LogZap {
global.GVA_LOG.Info(fmt.Sprintf(message, data...))
} else {
c.Writer.Printf(message, data...)
}
}
+4 -2
View File
@@ -1,8 +1,10 @@
package initialize
import (
"context"
"gin-vue-admin/global"
"github.com/go-redis/redis"
"github.com/go-redis/redis/v8"
"go.uber.org/zap"
)
@@ -13,7 +15,7 @@ func Redis() {
Password: redisCfg.Password, // no password set
DB: redisCfg.DB, // use default DB
})
pong, err := client.Ping().Result()
pong, err := client.Ping(context.Background()).Result()
if err != nil {
global.GVA_LOG.Error("redis connect ping failed, err:", zap.Any("err", err))
} else {
+24 -18
View File
@@ -25,32 +25,38 @@ func Routers() *gin.Engine {
Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
global.GVA_LOG.Info("register swagger handler")
// 方便统一添加路由组前缀 多服务器上线使用
//获取路由组实例
systemRouter := router.RouterGroupApp.System
exampleRouter := router.RouterGroupApp.Example
autocodeRouter := router.RouterGroupApp.Autocode
PublicGroup := Router.Group("")
{
router.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权
router.InitInitRouter(PublicGroup) // 自动初始化相关
systemRouter.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权
systemRouter.InitInitRouter(PublicGroup) // 自动初始化相关
}
PrivateGroup := Router.Group("")
PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
{
router.InitApiRouter(PrivateGroup) // 注册功能api路由
router.InitJwtRouter(PrivateGroup) // jwt相关路由
router.InitUserRouter(PrivateGroup) // 注册用户路由
router.InitMenuRouter(PrivateGroup) // 注册menu路由
router.InitEmailRouter(PrivateGroup) // 邮件相关路由
router.InitSystemRouter(PrivateGroup) // system相关路由
router.InitCasbinRouter(PrivateGroup) // 权限相关路由
router.InitCustomerRouter(PrivateGroup) // 客户路由
router.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码
router.InitAuthorityRouter(PrivateGroup) // 注册角色路由
router.InitSimpleUploaderRouter(PrivateGroup) // 断点续传(插件版)
router.InitSysDictionaryRouter(PrivateGroup) // 字典管理
router.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
router.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
router.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
router.InitExcelRouter(PrivateGroup) // 表格导入导出
systemRouter.InitApiRouter(PrivateGroup) // 注册功能api路由
systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由
systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由
systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由
systemRouter.InitEmailRouter(PrivateGroup) // 邮件相关路由
systemRouter.InitSystemRouter(PrivateGroup) // system相关路由
systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由
systemRouter.InitAutoCodeRouter(PrivateGroup) // 创建自动化代码
systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由
systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理
systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录
systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
exampleRouter.InitExcelRouter(PrivateGroup) // 表格导入导出
exampleRouter.InitSimpleUploaderRouter(PrivateGroup) // 断点续传(插件版)
exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由
// Code generated by gin-vue-admin Begin; DO NOT EDIT.
autocodeRouter.InitSysAutoCodeExampleRouter(PrivateGroup)
// Code generated by gin-vue-admin End; DO NOT EDIT.
}
global.GVA_LOG.Info("router register success")
-1
View File
@@ -10,7 +10,6 @@ import (
func Timer() {
if global.GVA_CONFIG.Timer.Start {
for _, detail := range global.GVA_CONFIG.Timer.Detail {
fmt.Println(detail)
go func(detail config.Detail) {
global.GVA_Timer.AddTaskByFunc("ClearDB", global.GVA_CONFIG.Timer.Spec, func() {
err := utils.ClearTable(global.GVA_DB, detail.TableName, detail.CompareField, detail.Interval)
+5
View File
@@ -6,6 +6,11 @@ import (
"gin-vue-admin/initialize"
)
//go:generate go env -w GO111MODULE=on
//go:generate go env -w GOPROXY=https://goproxy.cn,direct
//go:generate go mod tidy
//go:generate go mod download
// @title Swagger Example API
// @version 0.0.1
// @description This is a sample Server pets
+5 -3
View File
@@ -2,12 +2,14 @@ package middleware
import (
"gin-vue-admin/global"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system/request"
"gin-vue-admin/service"
"github.com/gin-gonic/gin"
)
var casbinService = service.ServiceGroupApp.SystemServiceGroup.CasbinService
// 拦截器
func CasbinHandler() gin.HandlerFunc {
return func(c *gin.Context) {
@@ -19,7 +21,7 @@ func CasbinHandler() gin.HandlerFunc {
act := c.Request.Method
// 获取用户的角色
sub := waitUse.AuthorityId
e := service.Casbin()
e := casbinService.Casbin()
// 判断策略中是否存在
success, _ := e.Enforce(sub, obj, act)
if global.GVA_CONFIG.System.Env == "develop" || success {
+6 -4
View File
@@ -2,8 +2,8 @@ package middleware
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/system"
"gin-vue-admin/model/system/request"
"gin-vue-admin/service"
"gin-vue-admin/utils"
"github.com/gin-gonic/gin"
@@ -13,6 +13,8 @@ import (
"time"
)
var userService = service.ServiceGroupApp.SystemServiceGroup.UserService
func ErrorToEmail() gin.HandlerFunc {
return func(c *gin.Context) {
var username string
@@ -21,14 +23,14 @@ func ErrorToEmail() gin.HandlerFunc {
username = waitUse.Username
} else {
id, _ := strconv.Atoi(c.Request.Header.Get("x-user-id"))
err, user := service.FindUserById(id)
err, user := userService.FindUserById(id)
if err != nil {
username = "Unknown"
}
username = user.Username
}
body, _ := ioutil.ReadAll(c.Request.Body)
record := model.SysOperationRecord{
record := system.SysOperationRecord{
Ip: c.ClientIP(),
Method: c.Request.Method,
Path: c.Request.URL.Path,
+23 -12
View File
@@ -3,17 +3,20 @@ package middleware
import (
"errors"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/model/common/response"
"gin-vue-admin/model/system"
"gin-vue-admin/model/system/request"
"gin-vue-admin/service"
"strconv"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"strconv"
"time"
)
var jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService
func JWTAuth() gin.HandlerFunc {
return func(c *gin.Context) {
// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
@@ -23,7 +26,7 @@ func JWTAuth() gin.HandlerFunc {
c.Abort()
return
}
if service.IsBlacklist(token) {
if jwtService.IsBlacklist(token) {
response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
c.Abort()
return
@@ -41,26 +44,26 @@ func JWTAuth() gin.HandlerFunc {
c.Abort()
return
}
if err, _ = service.FindUserByUuid(claims.UUID.String()); err != nil {
_ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: token})
if err, _ = userService.FindUserByUuid(claims.UUID.String()); err != nil {
_ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: token})
response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
c.Abort()
}
if claims.ExpiresAt-time.Now().Unix() < claims.BufferTime {
claims.ExpiresAt = time.Now().Unix() + global.GVA_CONFIG.JWT.ExpiresTime
newToken, _ := j.CreateToken(*claims)
newToken, _ := j.CreateTokenByOldToken(token, *claims)
newClaims, _ := j.ParseToken(newToken)
c.Header("new-token", newToken)
c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt, 10))
if global.GVA_CONFIG.System.UseMultipoint {
err, RedisJwtToken := service.GetRedisJWT(newClaims.Username)
err, RedisJwtToken := jwtService.GetRedisJWT(newClaims.Username)
if err != nil {
global.GVA_LOG.Error("get redis jwt failed", zap.Any("err", err))
} else { // 当之前的取成功时才进行拉黑操作
_ = service.JsonInBlacklist(model.JwtBlacklist{Jwt: RedisJwtToken})
_ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: RedisJwtToken})
}
// 无论如何都要记录当前的活跃状态
_ = service.SetRedisJWT(newToken, newClaims.Username)
_ = jwtService.SetRedisJWT(newToken, newClaims.Username)
}
}
c.Set("claims", claims)
@@ -91,6 +94,14 @@ func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) {
return token.SignedString(j.SigningKey)
}
// CreateTokenByOldToken 旧token 换新token 使用归并回源避免并发问题
func (j *JWT) CreateTokenByOldToken(oldToken string, claims request.CustomClaims) (string, error) {
v, err, _ := global.GVA_Concurrency_Control.Do("JWT:"+oldToken, func() (interface{}, error) {
return j.CreateToken(claims)
})
return v.(string), err
}
// 解析 token
func (j *JWT) ParseToken(tokenString string) (*request.CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
+1 -1
View File
@@ -2,7 +2,7 @@ package middleware
import (
"gin-vue-admin/global"
"gin-vue-admin/model/response"
"gin-vue-admin/model/common/response"
"github.com/gin-gonic/gin"
)
+6 -4
View File
@@ -3,8 +3,8 @@ package middleware
import (
"bytes"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/system"
"gin-vue-admin/model/system/request"
"gin-vue-admin/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
@@ -14,6 +14,8 @@ import (
"time"
)
var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService
func OperationRecord() gin.HandlerFunc {
return func(c *gin.Context) {
var body []byte
@@ -37,7 +39,7 @@ func OperationRecord() gin.HandlerFunc {
}
userId = id
}
record := model.SysOperationRecord{
record := system.SysOperationRecord{
Ip: c.ClientIP(),
Method: c.Request.Method,
Path: c.Request.URL.Path,
@@ -65,7 +67,7 @@ func OperationRecord() gin.HandlerFunc {
record.Latency = latency
record.Resp = writer.body.String()
if err := service.CreateSysOperationRecord(record); err != nil {
if err := operationRecordService.CreateSysOperationRecord(record); err != nil {
global.GVA_LOG.Error("create operation record error:", zap.Any("err", err))
}
}
+12
View File
@@ -0,0 +1,12 @@
// 自动生成模板SysDictionaryDetail
package autocode
import (
"gin-vue-admin/global"
)
// 如果含有time.Time 请自行import time包
type AutoCodeExample struct {
global.GVA_MODEL
AutoCodeExampleField string `json:"autoCodeExampleField" form:"autoCodeExampleField" gorm:"column:auto_code_example_field;comment:仅作示例条目无实际作用"` // 展示值
}
@@ -0,0 +1,13 @@
// 自动生成模板SysDictionaryDetail
package request
import (
"gin-vue-admin/model/autocode"
"gin-vue-admin/model/common/request"
)
// 如果含有time.Time 请自行import time包
type AutoCodeExampleSearch struct {
autocode.AutoCodeExample
request.PageInfo
}
-14
View File
@@ -1,14 +0,0 @@
package model
import (
"gin-vue-admin/global"
)
type ExaCustomer struct {
global.GVA_MODEL
CustomerName string `json:"customerName" form:"customerName" gorm:"comment:客户名"` // 客户名
CustomerPhoneData string `json:"customerPhoneData" form:"customerPhoneData" gorm:"comment:客户手机号"` // 客户手机号
SysUserID uint `json:"sysUserId" form:"sysUserId" gorm:"comment:管理ID"` // 管理ID
SysUserAuthorityID string `json:"sysUserAuthorityID" form:"sysUserAuthorityID" gorm:"comment:管理角色ID"` // 管理角色ID
SysUser SysUser `json:"sysUser" form:"sysUser" gorm:"comment:管理详情"` // 管理详情
}
-6
View File
@@ -1,6 +0,0 @@
package model
type ExcelInfo struct {
FileName string `json:"fileName"` // 文件名
InfoList []SysBaseMenu `json:"infoList"`
}
@@ -1,4 +1,4 @@
package model
package example
import (
"gin-vue-admin/global"
+15
View File
@@ -0,0 +1,15 @@
package example
import (
"gin-vue-admin/global"
"gin-vue-admin/model/system"
)
type ExaCustomer struct {
global.GVA_MODEL
CustomerName string `json:"customerName" form:"customerName" gorm:"comment:客户名"` // 客户名
CustomerPhoneData string `json:"customerPhoneData" form:"customerPhoneData" gorm:"comment:客户手机号"` // 客户手机号
SysUserID uint `json:"sysUserId" form:"sysUserId" gorm:"comment:管理ID"` // 管理ID
SysUserAuthorityID string `json:"sysUserAuthorityID" form:"sysUserAuthorityID" gorm:"comment:管理角色ID"` // 管理角色ID
SysUser system.SysUser `json:"sysUser" form:"sysUser" gorm:"comment:管理详情"` // 管理详情
}
+8
View File
@@ -0,0 +1,8 @@
package example
import "gin-vue-admin/model/system"
type ExcelInfo struct {
FileName string `json:"fileName"` // 文件名
InfoList []system.SysBaseMenu `json:"infoList"`
}
@@ -1,4 +1,4 @@
package model
package example
import (
"gin-vue-admin/global"
@@ -1,4 +1,4 @@
package model
package example
type ExaSimpleUploader struct {
ChunkNumber string `json:"chunkNumber" gorm:"comment:当前切片标记"`
@@ -1,11 +1,11 @@
package response
import "gin-vue-admin/model"
import "gin-vue-admin/model/example"
type FilePathResponse struct {
FilePath string `json:"filePath"`
}
type FileResponse struct {
File model.ExaFile `json:"file"`
File example.ExaFile `json:"file"`
}
@@ -0,0 +1,7 @@
package response
import "gin-vue-admin/model/example"
type ExaCustomerResponse struct {
Customer example.ExaCustomer `json:"customer"`
}
@@ -0,0 +1,7 @@
package response
import "gin-vue-admin/model/example"
type ExaFileResponse struct {
File example.ExaFileUploadAndDownload `json:"file"`
}
-13
View File
@@ -1,13 +0,0 @@
package request
// Casbin info structure
type CasbinInfo struct {
Path string `json:"path"` // 路径
Method string `json:"method"` // 方法
}
// Casbin structure for input parameters
type CasbinInReceive struct {
AuthorityId string `json:"authorityId"` // 权限id
CasbinInfos []CasbinInfo `json:"casbinInfos"`
}
-8
View File
@@ -1,8 +0,0 @@
package request
import "gin-vue-admin/model"
type SysDictionarySearch struct {
model.SysDictionary
PageInfo
}
@@ -1,8 +0,0 @@
package request
import "gin-vue-admin/model"
type SysDictionaryDetailSearch struct {
model.SysDictionaryDetail
PageInfo
}
-9
View File
@@ -1,9 +0,0 @@
package request
import "gin-vue-admin/model"
// Add menu authority info structure
type AddMenuAuthorityInfo struct {
Menus []model.SysBaseMenu
AuthorityId string // 角色ID
}
@@ -1,8 +0,0 @@
package request
import "gin-vue-admin/model"
type SysOperationRecordSearch struct {
model.SysOperationRecord
PageInfo
}
-7
View File
@@ -1,7 +0,0 @@
package response
import "gin-vue-admin/model"
type ExaCustomerResponse struct {
Customer model.ExaCustomer `json:"customer"`
}
@@ -1,7 +0,0 @@
package response
import "gin-vue-admin/model"
type ExaFileResponse struct {
File model.ExaFileUploadAndDownload `json:"file"`
}
-11
View File
@@ -1,11 +0,0 @@
package response
import "gin-vue-admin/model"
type SysAPIResponse struct {
Api model.SysApi `json:"api"`
}
type SysAPIListResponse struct {
Apis []model.SysApi `json:"apis"`
}
-12
View File
@@ -1,12 +0,0 @@
package response
import "gin-vue-admin/model"
type SysAuthorityResponse struct {
Authority model.SysAuthority `json:"authority"`
}
type SysAuthorityCopyResponse struct {
Authority model.SysAuthority `json:"authority"`
OldAuthorityId string `json:"oldAuthorityId"` // 旧角色ID
}
-15
View File
@@ -1,15 +0,0 @@
package response
import "gin-vue-admin/model"
type SysMenusResponse struct {
Menus []model.SysMenu `json:"menus"`
}
type SysBaseMenusResponse struct {
Menus []model.SysBaseMenu `json:"menus"`
}
type SysBaseMenuResponse struct {
Menu model.SysBaseMenu `json:"menu"`
}
-15
View File
@@ -1,15 +0,0 @@
package response
import (
"gin-vue-admin/model"
)
type SysUserResponse struct {
User model.SysUser `json:"user"`
}
type LoginResponse struct {
User model.SysUser `json:"user"`
Token string `json:"token"`
ExpiresAt int64 `json:"expiresAt"`
}
-36
View File
@@ -1,36 +0,0 @@
package model
import (
"gin-vue-admin/global"
)
type SysBaseMenu struct {
global.GVA_MODEL
MenuLevel uint `json:"-"`
ParentId string `json:"parentId" gorm:"comment:父菜单ID"` // 父菜单ID
Path string `json:"path" gorm:"comment:路由path"` // 路由path
Name string `json:"name" gorm:"comment:路由name"` // 路由name
Hidden bool `json:"hidden" gorm:"comment:是否在列表隐藏"` // 是否在列表隐藏
Component string `json:"component" gorm:"comment:对应前端文件路径"` // 对应前端文件路径
Sort int `json:"sort" gorm:"comment:排序标记"` // 排序标记
Meta `json:"meta" gorm:"comment:附加属性"` // 附加属性
SysAuthoritys []SysAuthority `json:"authoritys" gorm:"many2many:sys_authority_menus;"`
Children []SysBaseMenu `json:"children" gorm:"-"`
Parameters []SysBaseMenuParameter `json:"parameters"`
}
type Meta struct {
KeepAlive bool `json:"keepAlive" gorm:"comment:是否缓存"` // 是否缓存
DefaultMenu bool `json:"defaultMenu" gorm:"comment:是否是基础路由(开发中)"` // 是否是基础路由(开发中)
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
}
type SysBaseMenuParameter struct {
global.GVA_MODEL
SysBaseMenuID uint
Type string `json:"type" gorm:"comment:地址栏携带参数为params还是query"` // 地址栏携带参数为params还是query
Key string `json:"key" gorm:"comment:地址栏携带参数的key"` // 地址栏携带参数的key
Value string `json:"value" gorm:"comment:地址栏携带参数的值"` // 地址栏携带参数的值
}
-17
View File
@@ -1,17 +0,0 @@
package model
import (
"gin-vue-admin/global"
"github.com/satori/go.uuid"
)
type SysUser struct {
global.GVA_MODEL
UUID uuid.UUID `json:"uuid" gorm:"comment:用户UUID"` // 用户UUID
Username string `json:"userName" gorm:"comment:用户登录名"` // 用户登录名
Password string `json:"-" gorm:"comment:用户登录密码"` // 用户登录密码
NickName string `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
HeaderImg string `json:"headerImg" gorm:"default:http://qmplusimg.henrongyi.top/head.png;comment:用户头像"` // 用户头像
Authority SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"`
AuthorityId string `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID
}
@@ -1,11 +1,14 @@
package request
import "gin-vue-admin/model"
import (
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/system"
)
// api分页条件查询及排序结构体
type SearchApiParams struct {
model.SysApi
PageInfo
system.SysApi
request.PageInfo
OrderKey string `json:"orderKey"` // 排序
Desc bool `json:"desc"` // 排序方式:升序false(默认)|降序true
}
@@ -1,5 +1,15 @@
package request
import "gin-vue-admin/model/common/request"
type SysAutoHistory struct {
request.PageInfo
}
type AutoHistoryByID struct {
ID uint `json:"id"`
}
type DBReq struct {
Database string `json:"database" gorm:"column:database"`
}
+26
View File
@@ -0,0 +1,26 @@
package request
// Casbin info structure
type CasbinInfo struct {
Path string `json:"path"` // 路径
Method string `json:"method"` // 方法
}
// Casbin structure for input parameters
type CasbinInReceive struct {
AuthorityId string `json:"authorityId"` // 权限id
CasbinInfos []CasbinInfo `json:"casbinInfos"`
}
func DefaultCasbin() []CasbinInfo {
return []CasbinInfo{
{Path: "/menu/getMenu", Method: "POST"},
{Path: "/jwt/jsonInBlacklist", Method: "POST"},
{Path: "/base/login", Method: "POST"},
{Path: "/user/register", Method: "POST"},
{Path: "/user/changePassword", Method: "POST"},
{Path: "/user/setUserAuthority", Method: "POST"},
{Path: "/user/setUserInfo", Method: "PUT"},
{Path: "/user/getUserInfo", Method: "GET"},
}
}
@@ -0,0 +1,11 @@
package request
import (
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/system"
)
type SysDictionarySearch struct {
system.SysDictionary
request.PageInfo
}
@@ -0,0 +1,11 @@
package request
import (
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/system"
)
type SysDictionaryDetailSearch struct {
system.SysDictionaryDetail
request.PageInfo
}
+27
View File
@@ -0,0 +1,27 @@
package request
import (
"gin-vue-admin/global"
"gin-vue-admin/model/system"
)
// Add menu authority info structure
type AddMenuAuthorityInfo struct {
Menus []system.SysBaseMenu
AuthorityId string // 角色ID
}
func DefaultMenu() []system.SysBaseMenu {
return []system.SysBaseMenu{{
GVA_MODEL: global.GVA_MODEL{ID: 1},
ParentId: "0",
Path: "dashboard",
Name: "dashboard",
Component: "view/dashboard/index.vue",
Sort: 1,
Meta: system.Meta{
Title: "仪表盘",
Icon: "setting",
},
}}
}
@@ -0,0 +1,11 @@
package request
import (
"gin-vue-admin/model/common/request"
"gin-vue-admin/model/system"
)
type SysOperationRecordSearch struct {
system.SysOperationRecord
request.PageInfo
}
@@ -1,14 +1,13 @@
package request
import uuid "github.com/satori/go.uuid"
// User register structure
type Register struct {
Username string `json:"userName"`
Password string `json:"passWord"`
NickName string `json:"nickName" gorm:"default:'QMPlusUser'"`
HeaderImg string `json:"headerImg" gorm:"default:'http://www.henrongyi.top/avatar/lufu.jpg'"`
AuthorityId string `json:"authorityId" gorm:"default:888"`
Username string `json:"userName"`
Password string `json:"passWord"`
NickName string `json:"nickName" gorm:"default:'QMPlusUser'"`
HeaderImg string `json:"headerImg" gorm:"default:'http://www.henrongyi.top/avatar/lufu.jpg'"`
AuthorityId string `json:"authorityId" gorm:"default:888"`
AuthorityIds []string `json:"authorityIds"`
}
// User login structure
@@ -28,6 +27,11 @@ type ChangePasswordStruct struct {
// Modify user's auth structure
type SetUserAuth struct {
UUID uuid.UUID `json:"uuid"` // 用户UUID
AuthorityId string `json:"authorityId"` // 角色ID
AuthorityId string `json:"authorityId"` // 角色ID
}
// Modify user's auth structure
type SetUserAuthorities struct {
ID uint
AuthorityIds []string `json:"authorityIds"` // 角色ID
}
+11
View File
@@ -0,0 +1,11 @@
package response
import "gin-vue-admin/model/system"
type SysAPIResponse struct {
Api system.SysApi `json:"api"`
}
type SysAPIListResponse struct {
Apis []system.SysApi `json:"apis"`
}
@@ -0,0 +1,12 @@
package response
import "gin-vue-admin/model/system"
type SysAuthorityResponse struct {
Authority system.SysAuthority `json:"authority"`
}
type SysAuthorityCopyResponse struct {
Authority system.SysAuthority `json:"authority"`
OldAuthorityId string `json:"oldAuthorityId"` // 旧角色ID
}

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