Kaynağa Gözat

gfast v3.2.1

tiger1103 3 yıl önce
işleme
d1f102f157
100 değiştirilmiş dosya ile 6203 ekleme ve 0 silme
  1. 29 0
      .gitignore
  2. 201 0
      LICENSE
  3. 166 0
      README.MD
  4. 19 0
      api/v1/common/captcha.go
  5. 20 0
      api/v1/common/req.go
  6. 21 0
      api/v1/common/res.go
  7. 57 0
      api/v1/system/personal.go
  8. 112 0
      api/v1/system/sys_auth_rule.go
  9. 71 0
      api/v1/system/sys_config.go
  10. 71 0
      api/v1/system/sys_dept.go
  11. 93 0
      api/v1/system/sys_dict_data.go
  12. 79 0
      api/v1/system/sys_dict_type.go
  13. 66 0
      api/v1/system/sys_init.go
  14. 38 0
      api/v1/system/sys_login.go
  15. 47 0
      api/v1/system/sys_login_log.go
  16. 11 0
      api/v1/system/sys_monitor.go
  17. 65 0
      api/v1/system/sys_oper_log.go
  18. 61 0
      api/v1/system/sys_post.go
  19. 81 0
      api/v1/system/sys_role.go
  20. 133 0
      api/v1/system/sys_user.go
  21. 40 0
      api/v1/system/sys_user_online.go
  22. 24 0
      go.mod
  23. 307 0
      go.sum
  24. 10 0
      hack/config.yaml
  25. 13 0
      internal/app/boot/boot.go
  26. 21 0
      internal/app/common/consts/cache.go
  27. 8 0
      internal/app/common/consts/consts.go
  28. 11 0
      internal/app/common/consts/upload.go
  29. 19 0
      internal/app/common/controller/base.go
  30. 32 0
      internal/app/common/controller/captcha.go
  31. 24 0
      internal/app/common/dao/casbin_rule.go
  32. 84 0
      internal/app/common/dao/internal/casbin_rule.go
  33. 90 0
      internal/app/common/dao/internal/sys_config.go
  34. 98 0
      internal/app/common/dao/internal/sys_dict_data.go
  35. 88 0
      internal/app/common/dao/internal/sys_dict_type.go
  36. 24 0
      internal/app/common/dao/sys_config.go
  37. 24 0
      internal/app/common/dao/sys_dict_data.go
  38. 24 0
      internal/app/common/dao/sys_dict_type.go
  39. 45 0
      internal/app/common/logic/cache/cache.go
  40. 69 0
      internal/app/common/logic/captcha/captcha.go
  41. 14 0
      internal/app/common/logic/logic.go
  42. 31 0
      internal/app/common/logic/middleware/middleware.go
  43. 178 0
      internal/app/common/logic/sysConfig/sys_config.go
  44. 173 0
      internal/app/common/logic/sysDictData/sys_dict_data.go
  45. 186 0
      internal/app/common/logic/sysDictType/sys_dict_type.go
  46. 21 0
      internal/app/common/model/do/casbin_rule.go
  47. 25 0
      internal/app/common/model/do/sys_config.go
  48. 29 0
      internal/app/common/model/do/sys_dict_data.go
  49. 24 0
      internal/app/common/model/do/sys_dict_type.go
  50. 16 0
      internal/app/common/model/entity/casbin_rule.go
  51. 23 0
      internal/app/common/model/entity/sys_config.go
  52. 27 0
      internal/app/common/model/entity/sys_dict_data.go
  53. 22 0
      internal/app/common/model/entity/sys_dict_type.go
  54. 8 0
      internal/app/common/model/sys_config.go
  55. 21 0
      internal/app/common/model/sys_dict_data.go
  56. 19 0
      internal/app/common/model/sys_dict_type.go
  57. 32 0
      internal/app/common/model/token.go
  58. 28 0
      internal/app/common/router/router.go
  59. 29 0
      internal/app/common/service/cache.go
  60. 28 0
      internal/app/common/service/captcha.go
  61. 220 0
      internal/app/common/service/casbin.go
  62. 27 0
      internal/app/common/service/middleware.go
  63. 37 0
      internal/app/common/service/sys_config.go
  64. 34 0
      internal/app/common/service/sys_dict_data.go
  65. 36 0
      internal/app/common/service/sys_dict_type.go
  66. 29 0
      internal/app/system/consts/cache.go
  67. 5 0
      internal/app/system/consts/consts.go
  68. 13 0
      internal/app/system/consts/context.go
  69. 22 0
      internal/app/system/controller/base.go
  70. 34 0
      internal/app/system/controller/personal.go
  71. 79 0
      internal/app/system/controller/sys_auth_rule.go
  72. 51 0
      internal/app/system/controller/sys_config.go
  73. 60 0
      internal/app/system/controller/sys_dept.go
  74. 55 0
      internal/app/system/controller/sys_dict_data.go
  75. 57 0
      internal/app/system/controller/sys_dict_type.go
  76. 112 0
      internal/app/system/controller/sys_login.go
  77. 35 0
      internal/app/system/controller/sys_login_log.go
  78. 142 0
      internal/app/system/controller/sys_monitor.go
  79. 43 0
      internal/app/system/controller/sys_oper_log.go
  80. 44 0
      internal/app/system/controller/sys_post.go
  81. 62 0
      internal/app/system/controller/sys_role.go
  82. 102 0
      internal/app/system/controller/sys_user.go
  83. 28 0
      internal/app/system/controller/sys_user_online.go
  84. 114 0
      internal/app/system/dao/internal/sys_auth_rule.go
  85. 98 0
      internal/app/system/dao/internal/sys_dept.go
  86. 102 0
      internal/app/system/dao/internal/sys_job.go
  87. 79 0
      internal/app/system/dao/internal/sys_job_log.go
  88. 90 0
      internal/app/system/dao/internal/sys_login_log.go
  89. 99 0
      internal/app/system/dao/internal/sys_oper_log.go
  90. 92 0
      internal/app/system/dao/internal/sys_post.go
  91. 86 0
      internal/app/system/dao/internal/sys_role.go
  92. 75 0
      internal/app/system/dao/internal/sys_role_dept.go
  93. 112 0
      internal/app/system/dao/internal/sys_user.go
  94. 87 0
      internal/app/system/dao/internal/sys_user_online.go
  95. 74 0
      internal/app/system/dao/internal/sys_user_post.go
  96. 107 0
      internal/app/system/dao/internal/tools_gen_table.go
  97. 151 0
      internal/app/system/dao/internal/tools_gen_table_column.go
  98. 24 0
      internal/app/system/dao/sys_auth_rule.go
  99. 27 0
      internal/app/system/dao/sys_dept.go
  100. 29 0
      internal/app/system/dao/sys_job.go

+ 29 - 0
.gitignore

@@ -0,0 +1,29 @@
+.buildpath
+.hgignore.swp
+.project
+.orig
+.swp
+.idea/
+.settings/
+.vscode/
+vendor/
+composer.lock
+gitpush.sh
+pkg/
+bin/
+cbuild
+**/.DS_Store
+.vscode/
+.test/
+main
+output/
+manifest/output/
+*.exe
+tmp/
+resource/data/gen_sql
+resource/log/
+resource/public/big_file
+resource/public/upload_file
+manifest/config/config.yaml
+GFastV3
+/manifest/config/db.yaml

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 166 - 0
README.MD

@@ -0,0 +1,166 @@
+# GFast-V3
+<div align="center">
+	<img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/gfastlogo.png">
+    <p>
+        <h1>GFast V3.2</h1>
+    </p>
+    <p align="center">
+        <a href="https://goframe.org/pages/viewpage.action?pageId=1114119" target="_blank">
+	        <img src="https://img.shields.io/badge/goframe-2.0-green" alt="goframe">
+	    </a>
+	    <a href="https://v3.vuejs.org/" target="_blank">
+	        <img src="https://img.shields.io/badge/vue.js-vue3.x-green" alt="vue">
+	    </a>
+	    <a href="https://element-plus.gitee.io/#/zh-CN/component/changelog" target="_blank">
+	        <img src="https://img.shields.io/badge/element--plus-%3E1.0.0-blue" alt="element plus">
+	    </a>
+		<a href="https://www.tslang.cn/" target="_blank">
+	        <img src="https://img.shields.io/badge/typescript-%3E4.0.0-blue" alt="typescript">
+	    </a>
+		<a href="https://vitejs.dev/" target="_blank">
+		    <img src="https://img.shields.io/badge/vite-%3E2.0.0-yellow" alt="vite">
+		</a>
+		<a href="https://gitee.com/lyt-top/vue-next-admin/blob/master/LICENSE" target="_blank">
+		    <img src="https://img.shields.io/badge/license-MIT-success" alt="license">
+		</a>
+	</p>
+</div>
+
+
+
+## 平台简介
+* 基于全新Go Frame 2.3+Vue3+Element Plus开发的全栈前后端分离的管理系统
+* 前端采用vue-next-admin 、Vue、Element UI。
+* 本项目由<a href="http://www.qjit.cn/" target="_blank"><b>奇讯科技</b></a>团队开发。
+* 如您想购买云服务器请先领取阿里云优惠券:[点我进入](https://www.aliyun.com/minisite/goods?userCode=fcor2omk ),腾讯云优惠券:[点我领取](https://cloud.tencent.com/act/cps/redirect?redirect=1062&cps_key=20b1c3842f74986b2894e2c5fcde7ea2&from=console )
+
+## 特征
+* 高生产率:几分钟即可搭建一个后台管理系统
+* 模块化:单应用多系统的模式,将一个完整的应用拆分为多个系统,后续扩展更加便捷,增加代码复用性。
+* 插件化: 可通过插件的方式扩展系统功能
+* 认证机制:采用gtoken的用户状态认证及casbin的权限认证
+* 路由模式:得利于goframe2.0提供了规范化的路由注册方式,无需注解自动生成api文档 
+* 面向接口开发 
+
+
+## 内置功能
+
+1.  用户管理:用户是系统操作者,该功能主要完成系统用户配置。
+2.  部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
+3.  岗位管理:配置系统用户所属担任职务。
+4.  菜单管理:配置系统菜单,操作权限,按钮权限标识等。
+5.  角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
+6.  字典管理:对系统中经常使用的一些较为固定的数据进行维护。
+7.  参数管理:对系统动态配置常用参数。
+8.  操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
+9. 登录日志:系统登录日志记录查询包含登录异常。
+10. 在线用户:当前系统中活跃用户状态监控。
+11. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
+12. 代码生成:前后端代码的生成。
+13. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
+14. 在线构建器:拖动表单元素生成相应的HTML代码。
+15. 文件上传,缓存标签等。
+
+> 项目使用模块化与插件化的方式开发,目前正在升级的插件有:cms系统、万能模型、微信管理、工单系统、问答系统、工作流引擎...,同时也欢迎大家把写好的插件上传到商城,我们来帮您实现技术变现,获取收益!
+
+> GFast开源以来得到了大家的很多支持,如果您愿意为GFast贡献代码或提供建议,请加微信:qixun007(备注:gfast)
+
+## 演示地址
+[http://v3.g-fast.cn/sys](http://v3.g-fast.cn/sys)
+账号:demo  密码:123456
+## 配置
+项目数据库文件 `resource/data/db.sql` 创建数据库导入后修改配置 `manifest/config/config.yaml.bak` 复制改为`manifest/config/config.yaml`  
+
+其中gfToken配置
+```yaml
+gfToken:
+  cacheKey: "gfToken_"   #缓存前缀
+  timeOut: 10800         #token超时时间(秒)
+  maxRefresh: 5400       #token自动刷新时间(秒)
+  multiLogin: true       #是否允许一个账号多人同时登录
+  encryptKey: "49c54195e750b04e74a8429b17896586"    #加密key (32位)
+  cacheModel: "redis"    #存储引擎 (memory使用内存|redis使用redis)
+  excludePaths:          #排除不做登录验证的路由地址
+    - "/api/v1/system/login"
+```
+
+项目为前后端分离,前端地址:
+
+github地址:[https://github.com/tiger1103/gfast-ui](https://github.com/tiger1103/gfast-ui)
+
+gitee地址:[https://gitee.com/tiger1103/gfast-ui](https://gitee.com/tiger1103/gfast-ui)
+
+## 文档地址
+> [http://doc.g-fast.cn/docs/gfast32](http://doc.g-fast.cn/docs/gfast32)
+
+## 相关视频
+[https://space.bilibili.com/254192571/channel/seriesdetail?sid=223204](https://space.bilibili.com/254192571/channel/seriesdetail?sid=223204)
+
+## 演示图
+
+<table>
+    <tr>
+        <td><img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/cje01e1blsg80hagzj.png"/></td>
+        <td><img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/cje01gckl91kjetl0d.png"/></td>
+    </tr>
+    <tr>
+        <td><img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/cje01gckl91ky1lm3d.png"/></td>
+        <td><img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/cje01kkmk7sc1txfvz.png"/></td>
+    </tr>
+    <tr>
+        <td><img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/cje01kkmkfi4syoydw.png"/></td>
+        <td><img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/cje01s04zq2470mx3r.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/cje01kkmkfi4tquojj.png"/></td>
+        <td><img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/cje01s04zq245k17ta.png"/></td>
+    </tr>
+</table>
+
+## 感谢(排名不分先后)
+> gf框架 [https://github.com/gogf/gf](https://github.com/gogf/gf)
+>
+> vue-next-admin [https://gitee.com/lyt-top/vue-next-admin](https://gitee.com/lyt-top/vue-next-admin)
+>
+> swaggo [https://github.com/swaggo/swag](https://github.com/swaggo/swag)
+>
+>gtoken [https://github.com/goflyfox/gtoken](https://github.com/goflyfox/gtoken)
+>
+>casbin [https://github.com/casbin/casbin](https://github.com/casbin/casbin)
+
+
+PHP开源工作流引擎tpflow   [https://gitee.com/ntdgg/tpflow](https://gitee.com/ntdgg/tpflow)
+
+CCflow 国内最优秀的开源流程引擎  [https://gitee.com/opencc/ccflow](https://gitee.com/opencc/ccflow)
+
+## 交流QQ群
+
+> <img src="https://yxh-1301841944.cos.ap-chongqing.myqcloud.com/gfast/2022-04-19/qqcode.png"/>  
+
+> 感谢你使用GFast,公司团队精力时间有限,因此我们不再提供免费的技术服务,目前Gfast QQ交流群有部分用户进行了捐赠,捐赠后请联系作者进vip用户群,vip群中问题将得到优先解答,同时也会根据您的需求进行分析和优先安排,vip群也会提供Gfast的其它福利。
+> 同时您也可以联系我们,雇佣我们团队为您干活,谢谢合作!
+>快来加入群聊【Gfast框架交流群】(1群:865697297-已满,2群:444129379),发现精彩内容,记得备注加群来意。
+
+## 免责声明:
+> 1、Gfast仅限自己学习使用,一切商业行为与Gfast无关。
+
+> 2、用户不得利用Gfast从事非法行为,用户应当合法合规的使用,发现用户在使用产品时有任何的非法行为,Gfast有权配合有关机关进行调查或向政府部门举报,Gfast不承担用户因非法行为造成的任何法律责任,一切法律责任由用户自行承担,如因用户使用造成第三方损害的,用户应当依法予以赔偿。
+
+> 3、所有与使用Gfast相关的资源直接风险均由用户承担。
+
+
+## 商用说明
+> 商用注意事项
+如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。
+
+* GFast快速开发平台采用Apache-2.0技术协议
+* 二次开发如用于商业性质或开源竞品请不要删除和修改GFast源码头部的版权与作者声明及出处
+* 允许进行商用,但是不允许二次开源出来并进行收费
+* 我们已经申请了相关的软件著作权和相关登记(证书号:软著登字第7511736号)
+* 如果您在自己的项目中使用了我们项目中的扩展或模块,请在项目介绍中进行明确说明
+
+## 支持开源
+如果您喜爱gfast,请给常熬夜的作者来杯咖啡吧!<a href="https://ys0abw.yuque.com/ys0abw/ephcr9/zo38ua" target="_blank"> 点我送咖啡</a>
+
+## [感谢JetBrains提供的免费GoLand](https://jb.gg/OpenSource)
+[![avatar](https://camo.githubusercontent.com/323657c6e81419b8e151e9da4c71f409e3fcc65d630535170c59fe4807dbc905/68747470733a2f2f676f6672616d652e6f72672f646f776e6c6f61642f7468756d626e61696c732f313131343131392f6a6574627261696e732e706e67)](https://jb.gg/OpenSource)

+ 19 - 0
api/v1/common/captcha.go

@@ -0,0 +1,19 @@
+/*
+* @desc:验证码参数
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/2 17:47
+ */
+
+package common
+
+import "github.com/gogf/gf/v2/frame/g"
+
+type CaptchaReq struct {
+	g.Meta `path:"/get" tags:"验证码" method:"get" summary:"获取验证码"`
+}
+type CaptchaRes struct {
+	g.Meta `mime:"application/json"`
+	Key    string `json:"key"`
+	Img    string `json:"img"`
+}

+ 20 - 0
api/v1/common/req.go

@@ -0,0 +1,20 @@
+/*
+* @desc:公共接口相关
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/30 9:28
+ */
+
+package common
+
+// PageReq 公共请求参数
+type PageReq struct {
+	DateRange []string `p:"dateRange"` //日期范围
+	PageNum   int      `p:"pageNum"`   //当前页码
+	PageSize  int      `p:"pageSize"`  //每页数
+	OrderBy   string   //排序方式
+}
+
+type Author struct {
+	Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"`
+}

+ 21 - 0
api/v1/common/res.go

@@ -0,0 +1,21 @@
+/*
+* @desc:返回响应公共参数
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/10/27 16:30
+ */
+
+package common
+
+import "github.com/gogf/gf/v2/frame/g"
+
+// EmptyRes 不响应任何数据
+type EmptyRes struct {
+	g.Meta `mime:"application/json"`
+}
+
+// ListRes 列表公共返回
+type ListRes struct {
+	CurrentPage int         `json:"currentPage"`
+	Total       interface{} `json:"total"`
+}

+ 57 - 0
api/v1/system/personal.go

@@ -0,0 +1,57 @@
+/*
+* @desc:xxxx功能描述
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/11/3 10:04
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+)
+
+type PersonalInfoReq struct {
+	g.Meta `path:"/personal/getPersonalInfo" tags:"用户管理" method:"get" summary:"登录用户信息"`
+	commonApi.Author
+}
+
+type PersonalInfoRes struct {
+	g.Meta   `mime:"application/json"`
+	User     *entity.SysUser `json:"user"`
+	Roles    []string        `json:"roles"`
+	DeptName string          `json:"deptName"`
+}
+
+// SetPersonalReq 添加修改用户公用请求字段
+type SetPersonalReq struct {
+	Nickname  string `p:"nickname" v:"required#用户昵称不能为空"`
+	Mobile    string `p:"mobile" v:"required|phone#手机号不能为空|手机号格式错误"`
+	Remark    string `p:"remark"`
+	Sex       int    `p:"sex"`
+	UserEmail string `p:"userEmail" v:"required|email#邮箱不能为空|邮箱格式错误"`
+	Describe  string `p:"describe"` //签名
+	Avatar    string `p:"avatar"`   //签名
+
+}
+
+// PersonalEditReq 修改个人
+type PersonalEditReq struct {
+	g.Meta `path:"/personal/edit" tags:"用户管理" method:"put" summary:"修改个人资料"`
+	*SetPersonalReq
+	commonApi.Author
+}
+
+type PersonalEditRes struct {
+}
+
+type PersonalResetPwdReq struct {
+	g.Meta   `path:"/personal/resetPwd" tags:"用户管理" method:"put" summary:"重置个人密码"`
+	Password string `p:"password" v:"required|password#密码不能为空|密码以字母开头,只能包含字母、数字和下划线,长度在6~18之间"`
+	commonApi.Author
+}
+
+type PersonalResetPwdRes struct {
+}

+ 112 - 0
api/v1/system/sys_auth_rule.go

@@ -0,0 +1,112 @@
+/*
+* @desc:菜单api
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/18 10:27
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+)
+
+type RuleSearchReq struct {
+	g.Meta `path:"/menu/list" tags:"菜单管理" method:"get" summary:"菜单列表"`
+	commonApi.Author
+	Title     string `p:"menuName" `
+	Component string `p:"component"`
+}
+
+type RuleListRes struct {
+	g.Meta `mime:"application/json"`
+	Rules  []*model.SysAuthRuleTreeRes `json:"rules"`
+}
+
+type RuleAddReq struct {
+	g.Meta `path:"/menu/add" tags:"菜单管理" method:"post" summary:"添加菜单"`
+	commonApi.Author
+	MenuType  uint   `p:"menuType"  v:"min:0|max:2#菜单类型最小值为:min|菜单类型最大值为:max"`
+	Pid       uint   `p:"parentId"  v:"min:0"`
+	Name      string `p:"name" v:"required#请填写规则名称"`
+	Title     string `p:"menuName" v:"required|length:1,100#请填写标题|标题长度在:min到:max位"`
+	Icon      string `p:"icon"`
+	Weigh     int    `p:"menuSort" `
+	Condition string `p:"condition" `
+	Remark    string `p:"remark" `
+	IsHide    uint   `p:"isHide"`
+	Path      string `p:"path"`
+	Redirect  string `p:"redirect"` // 路由重定向
+	Roles     []uint `p:"roles"`    // 角色ids
+	Component string `p:"component" v:"required-if:menuType,1#组件路径不能为空"`
+	IsLink    uint   `p:"isLink"`
+	IsIframe  uint   `p:"isIframe"`
+	IsCached  uint   `p:"isKeepAlive"`
+	IsAffix   uint   `p:"isAffix"`
+	LinkUrl   string `p:"linkUrl"`
+}
+
+type RuleAddRes struct {
+}
+
+type RuleGetParamsReq struct {
+	g.Meta `path:"/menu/getParams" tags:"菜单管理" method:"get" summary:"获取添加、编辑菜单相关参数"`
+	commonApi.Author
+}
+
+type RuleGetParamsRes struct {
+	g.Meta `mime:"application/json"`
+	Roles  []*entity.SysRole           `json:"roles"`
+	Menus  []*model.SysAuthRuleInfoRes `json:"menus"`
+}
+
+type RuleInfoReq struct {
+	g.Meta `path:"/menu/get" tags:"菜单管理" method:"get" summary:"获取菜单信息"`
+	commonApi.Author
+	Id uint `p:"required#菜单id必须"`
+}
+
+type RuleInfoRes struct {
+	g.Meta  `mime:"application/json"`
+	Rule    *entity.SysAuthRule `json:"rule"`
+	RoleIds []uint              `json:"roleIds"`
+}
+
+type RuleUpdateReq struct {
+	g.Meta `path:"/menu/update" tags:"菜单管理" method:"put" summary:"修改菜单"`
+	commonApi.Author
+	Id        uint   `p:"id" v:"required#id必须"`
+	MenuType  uint   `p:"menuType"  v:"min:0|max:2#菜单类型最小值为:min|菜单类型最大值为:max"`
+	Pid       uint   `p:"parentId"  v:"min:0"`
+	Name      string `p:"name" v:"required#请填写规则名称"`
+	Title     string `p:"menuName" v:"required|length:1,100#请填写标题|标题长度在:min到:max位"`
+	Icon      string `p:"icon"`
+	Weigh     int    `p:"menuSort" `
+	Condition string `p:"condition" `
+	Remark    string `p:"remark" `
+	IsHide    uint   `p:"isHide"`
+	Path      string `p:"path"`
+	Redirect  string `p:"redirect"` // 路由重定向
+	Roles     []uint `p:"roles"`    // 角色ids
+	Component string `p:"component" v:"required-if:menuType,1#组件路径不能为空"`
+	IsLink    uint   `p:"isLink"`
+	IsIframe  uint   `p:"isIframe"`
+	IsCached  uint   `p:"isKeepAlive"`
+	IsAffix   uint   `p:"isAffix"`
+	LinkUrl   string `p:"linkUrl"`
+}
+
+type RuleUpdateRes struct {
+}
+
+type RuleDeleteReq struct {
+	g.Meta `path:"/menu/delete" tags:"菜单管理" method:"delete" summary:"删除菜单"`
+	commonApi.Author
+	Ids []int `p:"ids" v:"required#菜单id必须"`
+}
+
+type RuleDeleteRes struct {
+}

+ 71 - 0
api/v1/system/sys_config.go

@@ -0,0 +1,71 @@
+/*
+* @desc:系统参数配置
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/18 21:11
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	commonEntity "github.com/tiger1103/gfast/v3/internal/app/common/model/entity"
+)
+
+type ConfigSearchReq struct {
+	g.Meta     `path:"/config/list" tags:"系统参数管理" method:"get" summary:"系统参数列表"`
+	ConfigName string `p:"configName"` //参数名称
+	ConfigKey  string `p:"configKey"`  //参数键名
+	ConfigType string `p:"configType"` //状态
+	commonApi.PageReq
+}
+
+type ConfigSearchRes struct {
+	g.Meta `mime:"application/json"`
+	List   []*commonEntity.SysConfig `json:"list"`
+	commonApi.ListRes
+}
+
+type ConfigReq struct {
+	ConfigName  string `p:"configName"  v:"required#参数名称不能为空"`
+	ConfigKey   string `p:"configKey"  v:"required#参数键名不能为空"`
+	ConfigValue string `p:"configValue"  v:"required#参数键值不能为空"`
+	ConfigType  int    `p:"configType"    v:"required|in:0,1#系统内置不能为空|系统内置类型只能为0或1"`
+	Remark      string `p:"remark"`
+}
+
+type ConfigAddReq struct {
+	g.Meta `path:"/config/add" tags:"系统参数管理" method:"post" summary:"添加系统参数"`
+	*ConfigReq
+}
+
+type ConfigAddRes struct {
+}
+
+type ConfigGetReq struct {
+	g.Meta `path:"/config/get" tags:"系统参数管理" method:"get" summary:"获取系统参数"`
+	Id     int `p:"id"`
+}
+
+type ConfigGetRes struct {
+	g.Meta `mime:"application/json"`
+	Data   *commonEntity.SysConfig `json:"data"`
+}
+
+type ConfigEditReq struct {
+	g.Meta   `path:"/config/edit" tags:"系统参数管理" method:"put" summary:"修改系统参数"`
+	ConfigId int64 `p:"configId" v:"required|min:1#主键ID不能为空|主键ID参数错误"`
+	*ConfigReq
+}
+
+type ConfigEditRes struct {
+}
+
+type ConfigDeleteReq struct {
+	g.Meta `path:"/config/delete" tags:"系统参数管理" method:"delete" summary:"删除系统参数"`
+	Ids    []int `p:"ids"`
+}
+
+type ConfigDeleteRes struct {
+}

+ 71 - 0
api/v1/system/sys_dept.go

@@ -0,0 +1,71 @@
+/*
+* @desc:部门管理参数
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/4/6 15:07
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+)
+
+type DeptSearchReq struct {
+	g.Meta   `path:"/dept/list" tags:"部门管理" method:"get" summary:"部门列表"`
+	DeptName string `p:"deptName"`
+	Status   string `p:"status"`
+}
+
+type DeptSearchRes struct {
+	g.Meta   `mime:"application/json"`
+	DeptList []*entity.SysDept `json:"deptList"`
+}
+
+type DeptAddReq struct {
+	g.Meta   `path:"/dept/add" tags:"部门管理" method:"post" summary:"添加部门"`
+	ParentID int    `p:"parentId"  v:"required#父级不能为空"`
+	DeptName string `p:"deptName"  v:"required#部门名称不能为空"`
+	OrderNum int    `p:"orderNum"  v:"required#排序不能为空"`
+	Leader   string `p:"leader"`
+	Phone    string `p:"phone"`
+	Email    string `p:"email"  v:"email#邮箱格式不正确"`
+	Status   uint   `p:"status"  v:"required#状态必须"`
+}
+
+type DeptAddRes struct {
+}
+
+type DeptEditReq struct {
+	g.Meta   `path:"/dept/edit" tags:"部门管理" method:"put" summary:"修改部门"`
+	DeptId   int    `p:"deptId" v:"required#deptId不能为空"`
+	ParentID int    `p:"parentId"  v:"required#父级不能为空"`
+	DeptName string `p:"deptName"  v:"required#部门名称不能为空"`
+	OrderNum int    `p:"orderNum"  v:"required#排序不能为空"`
+	Leader   string `p:"leader"`
+	Phone    string `p:"phone"`
+	Email    string `p:"email"  v:"email#邮箱格式不正确"`
+	Status   uint   `p:"status"  v:"required#状态必须"`
+}
+
+type DeptEditRes struct {
+}
+
+type DeptDeleteReq struct {
+	g.Meta `path:"/dept/delete" tags:"部门管理" method:"delete" summary:"删除部门"`
+	Id     uint64 `p:"id" v:"required#id不能为空"`
+}
+
+type DeptDeleteRes struct {
+}
+
+type DeptTreeSelectReq struct {
+	g.Meta `path:"/dept/treeSelect" tags:"部门管理" method:"get" summary:"获取部门树形菜单"`
+}
+
+type DeptTreeSelectRes struct {
+	g.Meta `mime:"application/json"`
+	Deps   []*model.SysDeptTreeRes `json:"deps"`
+}

+ 93 - 0
api/v1/system/sys_dict_data.go

@@ -0,0 +1,93 @@
+/*
+* @desc:字典数据api
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/18 11:59
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	commonModel "github.com/tiger1103/gfast/v3/internal/app/common/model"
+	commonEntity "github.com/tiger1103/gfast/v3/internal/app/common/model/entity"
+)
+
+// GetDictReq 获取字典信息请求参数
+type GetDictReq struct {
+	g.Meta `path:"/dict/data/getDictData" tags:"字典管理" method:"get" summary:"获取字典数据公共方法"`
+	commonApi.Author
+	DictType     string `p:"dictType" v:"required#字典类型不能为空"`
+	DefaultValue string `p:"defaultValue"`
+}
+
+// GetDictRes 完整的一个字典信息
+type GetDictRes struct {
+	g.Meta `mime:"application/json"`
+	Info   *commonModel.DictTypeRes   `json:"info"`
+	Values []*commonModel.DictDataRes `json:"values"`
+}
+
+// DictDataSearchReq 分页请求参数
+type DictDataSearchReq struct {
+	g.Meta    `path:"/dict/data/list" tags:"字典管理" method:"get" summary:"字典数据列表"`
+	DictType  string `p:"dictType"`  //字典类型
+	DictLabel string `p:"dictLabel"` //字典标签
+	Status    string `p:"status"`    //状态
+	commonApi.PageReq
+}
+
+// DictDataSearchRes 字典数据结果
+type DictDataSearchRes struct {
+	g.Meta `mime:"application/json"`
+	List   []*commonEntity.SysDictData `json:"list"`
+	commonApi.ListRes
+}
+
+type DictDataReq struct {
+	DictLabel string `p:"dictLabel"  v:"required#字典标签不能为空"`
+	DictValue string `p:"dictValue"  v:"required#字典键值不能为空"`
+	DictType  string `p:"dictType"  v:"required#字典类型不能为空"`
+	DictSort  int    `p:"dictSort"  v:"integer#排序只能为整数"`
+	CssClass  string `p:"cssClass"`
+	ListClass string `p:"listClass"`
+	IsDefault int    `p:"isDefault" v:"required|in:0,1#系统默认不能为空|默认值只能为0或1"`
+	Status    int    `p:"status"    v:"required|in:0,1#状态不能为空|状态只能为0或1"`
+	Remark    string `p:"remark"`
+}
+
+type DictDataAddReq struct {
+	g.Meta `path:"/dict/data/add" tags:"字典管理" method:"post" summary:"添加字典数据"`
+	*DictDataReq
+}
+
+type DictDataAddRes struct {
+}
+
+type DictDataGetReq struct {
+	g.Meta   `path:"/dict/data/get" tags:"字典管理" method:"get" summary:"获取字典数据"`
+	DictCode uint `p:"dictCode"`
+}
+
+type DictDataGetRes struct {
+	g.Meta `mime:"application/json"`
+	Dict   *commonEntity.SysDictData `json:"dict"`
+}
+
+type DictDataEditReq struct {
+	g.Meta   `path:"/dict/data/edit" tags:"字典管理" method:"put" summary:"修改字典数据"`
+	DictCode int `p:"dictCode" v:"required|min:1#主键ID不能为空|主键ID不能小于1"`
+	*DictDataReq
+}
+
+type DictDataEditRes struct {
+}
+
+type DictDataDeleteReq struct {
+	g.Meta `path:"/dict/data/delete" tags:"字典管理" method:"delete" summary:"删除字典数据"`
+	Ids    []int `p:"ids"`
+}
+
+type DictDataDeleteRes struct {
+}

+ 79 - 0
api/v1/system/sys_dict_type.go

@@ -0,0 +1,79 @@
+/*
+* @desc:字典类型
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/14 21:30
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	commonModel "github.com/tiger1103/gfast/v3/internal/app/common/model"
+	commonEntity "github.com/tiger1103/gfast/v3/internal/app/common/model/entity"
+)
+
+type DictTypeSearchReq struct {
+	g.Meta   `path:"/dict/type/list" tags:"字典管理" method:"get" summary:"字典类型列表"`
+	DictName string `p:"dictName"` //字典名称
+	DictType string `p:"dictType"` //字典类型
+	Status   string `p:"status"`   //字典状态
+	commonApi.PageReq
+}
+
+type DictTypeSearchRes struct {
+	g.Meta       `mime:"application/json"`
+	DictTypeList []*commonModel.SysDictTypeInfoRes `json:"dictTypeList"`
+	commonApi.ListRes
+}
+
+type DictTypeAddReq struct {
+	g.Meta   `path:"/dict/type/add" tags:"字典管理" method:"post" summary:"添加字典类型"`
+	DictName string `p:"dictName"  v:"required#字典名称不能为空"`
+	DictType string `p:"dictType"  v:"required#字典类型不能为空"`
+	Status   uint   `p:"status"  v:"required|in:0,1#状态不能为空|状态只能为0或1"`
+	Remark   string `p:"remark"`
+}
+
+type DictTypeAddRes struct {
+}
+
+type DictTypeGetReq struct {
+	g.Meta `path:"/dict/type/get" tags:"字典管理" method:"get" summary:"获取字典类型"`
+	DictId uint `p:"dictId" v:"required#类型id不能为空"`
+}
+
+type DictTypeGetRes struct {
+	g.Meta   `mime:"application/json"`
+	DictType *commonEntity.SysDictType `json:"dictType"`
+}
+
+type DictTypeEditReq struct {
+	g.Meta   `path:"/dict/type/edit" tags:"字典管理" method:"put" summary:"修改字典类型"`
+	DictId   int64  `p:"dictId" v:"required|min:1#主键ID不能为空|主键ID必须为大于0的值"`
+	DictName string `p:"dictName"  v:"required#字典名称不能为空"`
+	DictType string `p:"dictType"  v:"required#字典类型不能为空"`
+	Status   uint   `p:"status"  v:"required|in:0,1#状态不能为空|状态只能为0或1"`
+	Remark   string `p:"remark"`
+}
+
+type DictTypeEditRes struct {
+}
+
+type DictTypeDeleteReq struct {
+	g.Meta  `path:"/dict/type/delete" tags:"字典管理" method:"delete" summary:"删除字典类型"`
+	DictIds []int `p:"dictIds" v:"required#字典类型id不能为空"`
+}
+
+type DictTypeDeleteRes struct {
+}
+
+type DictTypeAllReq struct {
+	g.Meta `path:"/dict/type/optionSelect" tags:"字典管理" method:"get" summary:"获取字典选择框列表"`
+}
+
+type DictTYpeAllRes struct {
+	g.Meta   `mime:"application/json"`
+	DictType []*commonEntity.SysDictType `json:"dictType"`
+}

+ 66 - 0
api/v1/system/sys_init.go

@@ -0,0 +1,66 @@
+package system
+
+import (
+	"fmt"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+)
+
+type DbInitIsInitReq struct {
+	g.Meta `path:"/dbInit/isInit" tags:"系统初始化" method:"get" summary:"系统初始化"`
+}
+
+type DbInitIsInitRes bool
+
+type DbInitGetEnvInfoReq struct {
+	g.Meta `path:"/dbInit/getEnvInfo" tags:"系统初始化" method:"get" summary:"获取环境信息"`
+}
+
+type DbInitGetEnvInfoRes g.Map
+
+type DbInitCreateDbReq struct {
+	g.Meta       `path:"/dbInit/createDb" tags:"系统初始化" method:"post" summary:"创建配置文件"`
+	DbHost       string `json:"dbHost" p:"dbHost" v:"required#数据库地址必须"`
+	DbPort       int    `json:"dbPort" p:"dbPort" v:"required#数据库端口必须"`
+	DbUser       string `json:"dbUser" p:"dbUser" v:"required#数据库用户名称必须"`
+	DbPass       string `json:"dbPass"`
+	DbName       string `json:"dbName" p:"dbName" v:"required#数据库名称必须"`
+	DbCharset    string `json:"dbCharset" p:"dbCharset" v:"required#数据库编码必须"`
+	RedisAddress string `json:"redisAddress" p:"redisAddress" v:"required#Redis地址必须"`
+	RedisPort    int    `json:"redisPort" p:"redisPort" v:"required#Redis端口必须"`
+	RedisDb      int    `json:"redisDb" p:"redisDb" v:"required#Redis索引必须"`
+	RedisPass    string `json:"redisPass"`
+}
+
+type DbInitCreateDbRes bool
+
+func (req *DbInitCreateDbReq) ToDbInitConfig() *model.DbInitConfig {
+	return &model.DbInitConfig{
+		Database: model.Database{
+			Default: model.DbDefault{
+				Host:        req.DbHost,
+				Port:        req.DbPort,
+				User:        req.DbUser,
+				Pass:        req.DbPass,
+				Name:        req.DbName,
+				Type:        "mysql",
+				Role:        "master",
+				Debug:       true,
+				Charset:     req.DbCharset,
+				DryRun:      false,
+				MaxIdle:     10,
+				MaxOpen:     10,
+				MaxLifetime: 10,
+			},
+		},
+		Redis: model.Redis{
+			Default: model.RedisDefault{
+				Address:     fmt.Sprintf("%s:%d", req.RedisAddress, req.RedisPort),
+				Db:          req.RedisDb,
+				Pass:        req.RedisPass,
+				IdleTimeout: 600,
+				MaxActive:   100,
+			},
+		},
+	}
+}

+ 38 - 0
api/v1/system/sys_login.go

@@ -0,0 +1,38 @@
+/*
+* @desc:登录
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/27 21:51
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+)
+
+type UserLoginReq struct {
+	g.Meta     `path:"/login" tags:"登录" method:"post" summary:"用户登录"`
+	Username   string `p:"username" v:"required#用户名不能为空"`
+	Password   string `p:"password" v:"required#密码不能为空"`
+	VerifyCode string `p:"verifyCode" v:"required#验证码不能为空"`
+	VerifyKey  string `p:"verifyKey"`
+}
+
+type UserLoginRes struct {
+	g.Meta      `mime:"application/json"`
+	UserInfo    *model.LoginUserRes `json:"userInfo"`
+	Token       string              `json:"token"`
+	MenuList    []*model.UserMenus  `json:"menuList"`
+	Permissions []string            `json:"permissions"`
+}
+
+type UserLoginOutReq struct {
+	g.Meta `path:"/logout" tags:"登录" method:"get" summary:"退出登录"`
+	commonApi.Author
+}
+
+type UserLoginOutRes struct {
+}

+ 47 - 0
api/v1/system/sys_login_log.go

@@ -0,0 +1,47 @@
+/*
+* @desc:登录日志
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/24 22:09
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+)
+
+// LoginLogSearchReq 查询列表请求参数
+type LoginLogSearchReq struct {
+	g.Meta        `path:"/loginLog/list" tags:"登录日志管理" method:"get" summary:"日志列表"`
+	LoginName     string `p:"userName"`      //登陆名
+	Status        string `p:"status"`        //状态
+	Ipaddr        string `p:"ipaddr"`        //登录地址
+	SortName      string `p:"orderByColumn"` //排序字段
+	SortOrder     string `p:"isAsc"`         //排序方式
+	LoginLocation string `p:"loginLocation"` //登录地点
+	commonApi.PageReq
+}
+
+type LoginLogSearchRes struct {
+	g.Meta `mime:"application/json"`
+	commonApi.ListRes
+	List []*entity.SysLoginLog `json:"list"`
+}
+
+type LoginLogDelReq struct {
+	g.Meta `path:"/loginLog/delete" tags:"登录日志管理" method:"delete" summary:"删除日志"`
+	Ids    []int `p:"ids" v:"required#ids必须"`
+}
+
+type LoginLogDelRes struct {
+}
+
+type LoginLogClearReq struct {
+	g.Meta `path:"/loginLog/clear" tags:"登录日志管理" method:"delete" summary:"清除日志"`
+}
+
+type LoginLogClearRes struct {
+}

+ 11 - 0
api/v1/system/sys_monitor.go

@@ -0,0 +1,11 @@
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+type MonitorSearchReq struct {
+	g.Meta `path:"/monitor/server" tags:"服务监控" method:"get" summary:"服务监控"`
+}
+
+type MonitorSearchRes g.Map

+ 65 - 0
api/v1/system/sys_oper_log.go

@@ -0,0 +1,65 @@
+/*
+* @desc:操作日志
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/12/21 14:37
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+)
+
+// SysOperLogSearchReq 分页请求参数
+type SysOperLogSearchReq struct {
+	g.Meta        `path:"/operLog/list" tags:"操作日志" method:"get" summary:"操作日志列表"`
+	Title         string `p:"title"`         //系统模块
+	RequestMethod string `p:"requestMethod"` //请求方式
+	OperName      string `p:"operName"`      //操作人员
+	commonApi.PageReq
+	commonApi.Author
+}
+
+// SysOperLogSearchRes 列表返回结果
+type SysOperLogSearchRes struct {
+	g.Meta `mime:"application/json"`
+	commonApi.ListRes
+	List []*model.SysOperLogListRes `json:"list"`
+}
+
+// SysOperLogGetReq 获取一条数据请求
+type SysOperLogGetReq struct {
+	g.Meta `path:"/operLog/get" tags:"操作日志" method:"get" summary:"获取操作日志信息"`
+	commonApi.Author
+	OperId uint64 `p:"operId" v:"required#主键必须"` //通过主键获取
+}
+
+// SysOperLogGetRes 获取一条数据结果
+type SysOperLogGetRes struct {
+	g.Meta `mime:"application/json"`
+	*model.SysOperLogInfoRes
+}
+
+// SysOperLogDeleteReq 删除数据请求
+type SysOperLogDeleteReq struct {
+	g.Meta `path:"/operLog/delete" tags:"操作日志" method:"delete" summary:"删除操作日志"`
+	commonApi.Author
+	OperIds []uint64 `p:"operIds" v:"required#主键必须"` //通过主键删除
+}
+
+// SysOperLogDeleteRes 删除数据返回
+type SysOperLogDeleteRes struct {
+	commonApi.EmptyRes
+}
+
+type SysOperLogClearReq struct {
+	g.Meta `path:"/operLog/clear" tags:"操作日志" method:"delete" summary:"清除日志"`
+	commonApi.Author
+}
+
+type SysOperLogClearRes struct {
+	commonApi.EmptyRes
+}

+ 61 - 0
api/v1/system/sys_post.go

@@ -0,0 +1,61 @@
+/*
+* @desc:岗位相关参数
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/7 23:09
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+)
+
+type PostSearchReq struct {
+	g.Meta   `path:"/post/list" tags:"岗位管理" method:"get" summary:"岗位列表"`
+	PostCode string `p:"postCode"` //岗位编码
+	PostName string `p:"postName"` //岗位名称
+	Status   string `p:"status"`   //状态
+	commonApi.PageReq
+}
+
+type PostSearchRes struct {
+	g.Meta `mime:"application/json"`
+	commonApi.ListRes
+	PostList []*entity.SysPost `json:"postList"`
+}
+
+type PostAddReq struct {
+	g.Meta   `path:"/post/add" tags:"岗位管理" method:"post" summary:"添加岗位"`
+	PostCode string `p:"postCode" v:"required#岗位编码不能为空"`
+	PostName string `p:"postName" v:"required#岗位名称不能为空"`
+	PostSort int    `p:"postSort" v:"required#岗位排序不能为空"`
+	Status   uint   `p:"status" v:"required#状态不能为空"`
+	Remark   string `p:"remark"`
+}
+
+type PostAddRes struct {
+}
+
+type PostEditReq struct {
+	g.Meta   `path:"/post/edit" tags:"岗位管理" method:"put" summary:"修改岗位"`
+	PostId   int64  `p:"postId" v:"required#id必须"`
+	PostCode string `p:"postCode" v:"required#岗位编码不能为空"`
+	PostName string `p:"postName" v:"required#岗位名称不能为空"`
+	PostSort int    `p:"postSort" v:"required#岗位排序不能为空"`
+	Status   uint   `p:"status" v:"required#状态不能为空"`
+	Remark   string `p:"remark"`
+}
+
+type PostEditRes struct {
+}
+
+type PostDeleteReq struct {
+	g.Meta `path:"/post/delete" tags:"岗位管理" method:"delete" summary:"删除岗位"`
+	Ids    []int `p:"ids"`
+}
+
+type PostDeleteRes struct {
+}

+ 81 - 0
api/v1/system/sys_role.go

@@ -0,0 +1,81 @@
+/*
+* @desc:角色api
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/30 9:16
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+)
+
+type RoleListReq struct {
+	g.Meta   `path:"/role/list" tags:"角色管理" method:"get" summary:"角色列表"`
+	RoleName string `p:"roleName"`   //参数名称
+	Status   string `p:"roleStatus"` //状态
+	commonApi.PageReq
+}
+
+type RoleListRes struct {
+	g.Meta `mime:"application/json"`
+	commonApi.ListRes
+	List []*entity.SysRole `json:"list"`
+}
+
+type RoleGetParamsReq struct {
+	g.Meta `path:"/role/getParams" tags:"角色管理" method:"get" summary:"角色编辑参数"`
+}
+
+type RoleGetParamsRes struct {
+	g.Meta `mime:"application/json"`
+	Menu   []*model.SysAuthRuleInfoRes `json:"menu"`
+}
+
+type RoleAddReq struct {
+	g.Meta    `path:"/role/add" tags:"角色管理" method:"post" summary:"添加角色"`
+	Name      string `p:"name" v:"required#角色名称不能为空"`
+	Status    uint   `p:"status"    `
+	ListOrder uint   `p:"listOrder" `
+	Remark    string `p:"remark"    `
+	MenuIds   []uint `p:"menuIds"`
+}
+
+type RoleAddRes struct {
+}
+
+type RoleGetReq struct {
+	g.Meta `path:"/role/get" tags:"角色管理" method:"get" summary:"获取角色信息"`
+	Id     uint `p:"id" v:"required#角色id不能为空""`
+}
+
+type RoleGetRes struct {
+	g.Meta  `mime:"application/json"`
+	Role    *entity.SysRole `json:"role"`
+	MenuIds []int           `json:"menuIds"`
+}
+
+type RoleEditReq struct {
+	g.Meta    `path:"/role/edit" tags:"角色管理" method:"put" summary:"修改角色"`
+	Id        int64  `p:"id" v:"required#角色id必须"`
+	Name      string `p:"name" v:"required#角色名称不能为空"`
+	Status    uint   `p:"status"    `
+	ListOrder uint   `p:"listOrder" `
+	Remark    string `p:"remark"    `
+	MenuIds   []uint `p:"menuIds"`
+}
+
+type RoleEditRes struct {
+}
+
+type RoleDeleteReq struct {
+	g.Meta `path:"/role/delete" tags:"角色管理" method:"delete" summary:"删除角色"`
+	Ids    []int64 `p:"ids" v:"required#角色id不能为空"`
+}
+
+type RoleDeleteRes struct {
+}

+ 133 - 0
api/v1/system/sys_user.go

@@ -0,0 +1,133 @@
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+)
+
+type UserMenusReq struct {
+	g.Meta `path:"/user/getUserMenus" tags:"用户管理" method:"get" summary:"获取用户菜单"`
+	commonApi.Author
+}
+
+type UserMenusRes struct {
+	g.Meta      `mime:"application/json"`
+	MenuList    []*model.UserMenus `json:"menuList"`
+	Permissions []string           `json:"permissions"`
+}
+
+// UserSearchReq 用户搜索请求参数
+type UserSearchReq struct {
+	g.Meta   `path:"/user/list" tags:"用户管理" method:"get" summary:"用户列表"`
+	DeptId   string `p:"deptId"` //部门id
+	Mobile   string `p:"mobile"`
+	Status   string `p:"status"`
+	KeyWords string `p:"keyWords"`
+	commonApi.PageReq
+	commonApi.Author
+}
+
+type UserSearchRes struct {
+	g.Meta   `mime:"application/json"`
+	UserList []*model.SysUserRoleDeptRes `json:"userList"`
+	commonApi.ListRes
+}
+
+type UserGetParamsReq struct {
+	g.Meta `path:"/user/params" tags:"用户管理" method:"get" summary:"用户维护参数获取"`
+}
+
+type UserGetParamsRes struct {
+	g.Meta   `mime:"application/json"`
+	RoleList []*entity.SysRole `json:"roleList"`
+	Posts    []*entity.SysPost `json:"posts"`
+}
+
+// SetUserReq 添加修改用户公用请求字段
+type SetUserReq struct {
+	DeptId   uint64  `p:"deptId" v:"required#用户部门不能为空"` //所属部门
+	Email    string  `p:"email" v:"email#邮箱格式错误"`       //邮箱
+	NickName string  `p:"nickName" v:"required#用户昵称不能为空"`
+	Mobile   string  `p:"mobile" v:"required|phone#手机号不能为空|手机号格式错误"`
+	PostIds  []int64 `p:"postIds"`
+	Remark   string  `p:"remark"`
+	RoleIds  []int64 `p:"roleIds"`
+	Sex      int     `p:"sex"`
+	Status   uint    `p:"status"`
+	IsAdmin  int     `p:"isAdmin"` // 是否后台管理员 1 是  0   否
+}
+
+// UserAddReq 添加用户参数
+type UserAddReq struct {
+	g.Meta `path:"/user/add" tags:"用户管理" method:"post" summary:"添加用户"`
+	*SetUserReq
+	UserName string `p:"userName" v:"required#用户账号不能为空"`
+	Password string `p:"password" v:"required|password#密码不能为空|密码以字母开头,只能包含字母、数字和下划线,长度在6~18之间"`
+	UserSalt string
+}
+
+type UserAddRes struct {
+}
+
+// UserEditReq 修改用户参数
+type UserEditReq struct {
+	g.Meta `path:"/user/edit" tags:"用户管理" method:"put" summary:"修改用户"`
+	*SetUserReq
+	UserId int64 `p:"userId" v:"required#用户id不能为空"`
+}
+
+type UserEditRes struct {
+}
+
+type UserGetEditReq struct {
+	g.Meta `path:"/user/getEdit" tags:"用户管理" method:"get" summary:"获取用户信息"`
+	Id     uint64 `p:"id"`
+}
+
+type UserGetEditRes struct {
+	g.Meta         `mime:"application/json"`
+	User           *entity.SysUser `json:"user"`
+	CheckedRoleIds []uint          `json:"checkedRoleIds"`
+	CheckedPosts   []int64         `json:"checkedPosts"`
+}
+
+// UserResetPwdReq 重置用户密码状态参数
+type UserResetPwdReq struct {
+	g.Meta   `path:"/user/resetPwd" tags:"用户管理" method:"put" summary:"重置用户密码"`
+	Id       uint64 `p:"userId" v:"required#用户id不能为空"`
+	Password string `p:"password" v:"required|password#密码不能为空|密码以字母开头,只能包含字母、数字和下划线,长度在6~18之间"`
+}
+
+type UserResetPwdRes struct {
+}
+
+// UserStatusReq 设置用户状态参数
+type UserStatusReq struct {
+	g.Meta     `path:"/user/setStatus" tags:"用户管理" method:"put" summary:"设置用户状态"`
+	Id         uint64 `p:"userId" v:"required#用户id不能为空"`
+	UserStatus uint   `p:"status" v:"required#用户状态不能为空"`
+}
+
+type UserStatusRes struct {
+}
+
+type UserDeleteReq struct {
+	g.Meta `path:"/user/delete" tags:"用户管理" method:"delete" summary:"删除用户"`
+	Ids    []int `p:"ids"  v:"required#ids不能为空"`
+}
+
+type UserDeleteRes struct {
+}
+
+type UserGetByIdsReq struct {
+	g.Meta `path:"/user/getUsers" tags:"用户管理" method:"get" summary:"同时获取多个用户"`
+	commonApi.Author
+	Ids []int `p:"ids" v:"required#ids不能为空"`
+}
+
+type UserGetByIdsRes struct {
+	g.Meta `mime:"application/json"`
+	List   []*model.SysUserSimpleRes `json:"list"`
+}

+ 40 - 0
api/v1/system/sys_user_online.go

@@ -0,0 +1,40 @@
+/*
+* @desc:在线用户
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2023/1/10 16:57
+ */
+
+package system
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	commonApi "github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+)
+
+// SysUserOnlineSearchReq 列表搜索参数
+type SysUserOnlineSearchReq struct {
+	g.Meta   `path:"/online/list" tags:"在线用户管理" method:"get" summary:"列表"`
+	Username string `p:"userName"`
+	Ip       string `p:"ipaddr"`
+	commonApi.PageReq
+	commonApi.Author
+}
+
+// SysUserOnlineSearchRes 列表结果
+type SysUserOnlineSearchRes struct {
+	g.Meta `mime:"application/json"`
+	commonApi.ListRes
+	List []*entity.SysUserOnline `json:"list"`
+}
+
+type SysUserOnlineForceLogoutReq struct {
+	g.Meta `path:"/online/forceLogout" tags:"在线用户管理" method:"delete" summary:"强制用户退出登录"`
+	commonApi.Author
+	Ids []int `p:"ids" v:"required#ids不能为空"`
+}
+
+type SysUserOnlineForceLogoutRes struct {
+	commonApi.EmptyRes
+}

+ 24 - 0
go.mod

@@ -0,0 +1,24 @@
+module github.com/tiger1103/gfast/v3
+
+go 1.16
+
+require (
+	github.com/casbin/casbin/v2 v2.42.0
+	github.com/go-sql-driver/mysql v1.7.0 // indirect
+	github.com/gogf/gf/contrib/drivers/mysql/v2 v2.2.5
+	github.com/gogf/gf/contrib/nosql/redis/v2 v2.3.0
+	github.com/gogf/gf/v2 v2.3.1
+	github.com/mattn/go-colorable v0.1.13 // indirect
+	github.com/mattn/go-runewidth v0.0.14 // indirect
+	github.com/mojocn/base64Captcha v1.3.5
+	github.com/mssola/user_agent v0.5.3
+	github.com/qiniu/go-sdk/v7 v7.13.0
+	github.com/rivo/uniseg v0.4.3 // indirect
+	github.com/shirou/gopsutil v3.21.11+incompatible
+	github.com/tencentyun/cos-go-sdk-v5 v0.7.34
+	github.com/tiger1103/gfast-cache v1.0.0
+	github.com/tiger1103/gfast-token v1.0.3
+	github.com/tklauser/go-sysconf v0.3.10 // indirect
+	github.com/yusufpapurcu/wmi v1.2.2 // indirect
+	golang.org/x/net v0.4.0 // indirect
+)

+ 307 - 0
go.sum

@@ -0,0 +1,307 @@
+github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
+github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
+github.com/casbin/casbin/v2 v2.42.0 h1:EA0aE5PZnFSYY6WulzTScOo4YO6xrGAAZkXRLs8p2ME=
+github.com/casbin/casbin/v2 v2.42.0/go.mod h1:sEL80qBYTbd+BPeL4iyvwYzFT3qwLaESq5aFKVLbLfA=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I=
+github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
+github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
+github.com/clbanning/mxj/v2 v2.5.7 h1:7q5lvUpaPF/WOkqgIDiwjBJaznaLCCBd78pi8ZyAnE0=
+github.com/clbanning/mxj/v2 v2.5.7/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
+github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
+github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
+github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
+github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
+github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
+github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
+github.com/gogf/gf/contrib/drivers/mysql/v2 v2.2.5 h1:lbktAfOabQV9ZzLdEUK6DkELnq2hcHLd8gAD1a6HfSQ=
+github.com/gogf/gf/contrib/drivers/mysql/v2 v2.2.5/go.mod h1:z+/0qiOwMroAnj5ESuobTv0l5P83rf+XR3r6Fj8WJyk=
+github.com/gogf/gf/contrib/nosql/redis/v2 v2.3.0 h1:r2q8MLwF6yUIEm6Hhwsfo/ixaJTKluTXSjU8rSeXo3c=
+github.com/gogf/gf/contrib/nosql/redis/v2 v2.3.0/go.mod h1:V9o2BF9ovJnaZhHImHAanqUgjX4kI51lgU45u5rPqvw=
+github.com/gogf/gf/v2 v2.0.0/go.mod h1:apktt6TleWtCIwpz63vBqUnw8MX8gWKoZyxgDpXFtgM=
+github.com/gogf/gf/v2 v2.3.0/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y=
+github.com/gogf/gf/v2 v2.3.1 h1:uptCJK47N6KSRwTBnFAqBWYnYa/OXBkZ0OlhO9CK7bQ=
+github.com/gogf/gf/v2 v2.3.1/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y=
+github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
+github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
+github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0=
+github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
+github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
+github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
+github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
+github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
+github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
+github.com/mssola/user_agent v0.5.3 h1:lBRPML9mdFuIZgI2cmlQ+atbpJdLdeVl2IDodjBR578=
+github.com/mssola/user_agent v0.5.3/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
+github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
+github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
+github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
+github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
+github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
+github.com/qiniu/go-sdk/v7 v7.13.0 h1:0bWRh/oAC2cArUILZLuWN+s9hPep1JYch5sA2Mfxq7A=
+github.com/qiniu/go-sdk/v7 v7.13.0/go.mod h1:btsaOc8CA3hdVloULfFdDgDc+g4f3TDZEFsDY0BLE+w=
+github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
+github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
+github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
+github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
+github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4=
+github.com/tencentyun/cos-go-sdk-v5 v0.7.34 h1:xm+Pg+6m486y4eugRI7/E4WasbVmpY1hp9QBSRErgp8=
+github.com/tencentyun/cos-go-sdk-v5 v0.7.34/go.mod h1:4dCEtLHGh8QPxHEkgq+nFaky7yZxQuYwgSJM87icDaw=
+github.com/tiger1103/gfast-cache v1.0.0 h1:+amboC6uu4AvkUnDz4DECcsBTp5HW+O98k8guJtrDlA=
+github.com/tiger1103/gfast-cache v1.0.0/go.mod h1:l+e5vdUHmqK0Th5VBOCSxXORbm8MwZQMXDkn+KA+amE=
+github.com/tiger1103/gfast-token v1.0.3 h1:6uPGGuhxlLODV9tDS1djhWHUSaIYtVNyOqibHTITCt4=
+github.com/tiger1103/gfast-token v1.0.3/go.mod h1:yjTBd86Gi2tOrgNBZe60QKyMprJVFSg3zUmQDEkD/Lw=
+github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
+github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
+github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
+github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
+github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
+go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=
+go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0=
+go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI=
+go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
+go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=
+go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU=
+go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU=
+go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
+go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=
+go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0=
+go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/image v0.0.0-20190501045829-6d32002ffd75 h1:TbGuee8sSq15Iguxu4deQ7+Bqq/d2rsQejGcEtADAMQ=
+golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
+golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
+golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
+golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 10 - 0
hack/config.yaml

@@ -0,0 +1,10 @@
+# CLI.
+gfcli:
+  gen:
+    dao:
+      - link:            "mysql:gfast3:gfast333@tcp(127.0.0.1:3306)/gfast-v32"
+        tables:          "sys_role_dept"
+        removePrefix:    "gf_"
+        descriptionTag:  true
+        noModelComment:  true
+        path: "./internal/app/system"

+ 13 - 0
internal/app/boot/boot.go

@@ -0,0 +1,13 @@
+/*
+* @desc:启动
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/9/23 15:55
+ */
+
+package boot
+
+import (
+	_ "github.com/tiger1103/gfast/v3/internal/app/common/logic"
+	_ "github.com/tiger1103/gfast/v3/internal/app/system/logic"
+)

+ 21 - 0
internal/app/common/consts/cache.go

@@ -0,0 +1,21 @@
+/*
+* @desc:缓存相关
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/9 11:25
+ */
+
+package consts
+
+const (
+	CacheModelMem   = "memory"
+	CacheModelRedis = "redis"
+
+	// CacheSysDict 字典缓存菜单KEY
+	CacheSysDict = "sysDict"
+
+	// CacheSysDictTag 字典缓存标签
+	CacheSysDictTag = "sysDictTag"
+	// CacheSysConfigTag 系统参数配置
+	CacheSysConfigTag = "sysConfigTag"
+)

+ 8 - 0
internal/app/common/consts/consts.go

@@ -0,0 +1,8 @@
+/*
+* @desc:常量
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/30 11:54
+ */
+
+package consts

+ 11 - 0
internal/app/common/consts/upload.go

@@ -0,0 +1,11 @@
+package consts
+
+const (
+	UploadPath        = "upload_file"
+	ImgTypeKey        = "sys.uploadFile.imageType"
+	ImgSizeKey        = "sys.uploadFile.imageSize"
+	FileTypeKey       = "sys.uploadFile.fileType"
+	FileSizeKey       = "sys.uploadFile.fileSize"
+	CheckFileTypeImg  = "img"  // 文件类型(图片)
+	CheckFileTypeFile = "file" // 文件类型(任意)
+)

+ 19 - 0
internal/app/common/controller/base.go

@@ -0,0 +1,19 @@
+/*
+* @desc:
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/4 18:19
+ */
+
+package controller
+
+import (
+	"github.com/gogf/gf/v2/net/ghttp"
+)
+
+type BaseController struct {
+}
+
+// Init 自动执行的初始化方法
+func (c *BaseController) Init(r *ghttp.Request) {
+}

+ 32 - 0
internal/app/common/controller/captcha.go

@@ -0,0 +1,32 @@
+/*
+* @desc:验证码获取
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/2 17:45
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/common"
+	"github.com/tiger1103/gfast/v3/internal/app/common/service"
+)
+
+var Captcha = captchaController{}
+
+type captchaController struct {
+}
+
+// Get 获取验证码
+func (c *captchaController) Get(ctx context.Context, req *common.CaptchaReq) (res *common.CaptchaRes, err error) {
+	var (
+		idKeyC, base64stringC string
+	)
+	idKeyC, base64stringC, err = service.Captcha().GetVerifyImgString(ctx)
+	res = &common.CaptchaRes{
+		Key: idKeyC,
+		Img: base64stringC,
+	}
+	return
+}

+ 24 - 0
internal/app/common/dao/casbin_rule.go

@@ -0,0 +1,24 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"github.com/tiger1103/gfast/v3/internal/app/common/dao/internal"
+)
+
+// casbinRuleDao is the data access object for table casbin_rule.
+// You can define custom methods on it to extend its functionality as you wish.
+type casbinRuleDao struct {
+	*internal.CasbinRuleDao
+}
+
+var (
+	// CasbinRule is globally public accessible object for table casbin_rule operations.
+	CasbinRule = casbinRuleDao{
+		internal.NewCasbinRuleDao(),
+	}
+)
+
+// Fill with you ideas below.

+ 84 - 0
internal/app/common/dao/internal/casbin_rule.go

@@ -0,0 +1,84 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// CasbinRuleDao is the data access object for table casbin_rule.
+type CasbinRuleDao struct {
+	table   string            // table is the underlying table name of the DAO.
+	group   string            // group is the database configuration group name of current DAO.
+	columns CasbinRuleColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// CasbinRuleColumns defines and stores column names for table casbin_rule.
+type CasbinRuleColumns struct {
+	Ptype string //
+	V0    string //
+	V1    string //
+	V2    string //
+	V3    string //
+	V4    string //
+	V5    string //
+}
+
+// casbinRuleColumns holds the columns for table casbin_rule.
+var casbinRuleColumns = CasbinRuleColumns{
+	Ptype: "ptype",
+	V0:    "v0",
+	V1:    "v1",
+	V2:    "v2",
+	V3:    "v3",
+	V4:    "v4",
+	V5:    "v5",
+}
+
+// NewCasbinRuleDao creates and returns a new DAO object for table data access.
+func NewCasbinRuleDao() *CasbinRuleDao {
+	return &CasbinRuleDao{
+		group:   "default",
+		table:   "casbin_rule",
+		columns: casbinRuleColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *CasbinRuleDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *CasbinRuleDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *CasbinRuleDao) Columns() CasbinRuleColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *CasbinRuleDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *CasbinRuleDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *CasbinRuleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 90 - 0
internal/app/common/dao/internal/sys_config.go

@@ -0,0 +1,90 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-18 21:09:17
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysConfigDao is the data access object for table sys_config.
+type SysConfigDao struct {
+	table   string           // table is the underlying table name of the DAO.
+	group   string           // group is the database configuration group name of current DAO.
+	columns SysConfigColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysConfigColumns defines and stores column names for table sys_config.
+type SysConfigColumns struct {
+	ConfigId    string // 参数主键
+	ConfigName  string // 参数名称
+	ConfigKey   string // 参数键名
+	ConfigValue string // 参数键值
+	ConfigType  string // 系统内置(Y是 N否)
+	CreateBy    string // 创建者
+	UpdateBy    string // 更新者
+	Remark      string // 备注
+	CreatedAt   string // 创建时间
+	UpdatedAt   string // 修改时间
+}
+
+// sysConfigColumns holds the columns for table sys_config.
+var sysConfigColumns = SysConfigColumns{
+	ConfigId:    "config_id",
+	ConfigName:  "config_name",
+	ConfigKey:   "config_key",
+	ConfigValue: "config_value",
+	ConfigType:  "config_type",
+	CreateBy:    "create_by",
+	UpdateBy:    "update_by",
+	Remark:      "remark",
+	CreatedAt:   "created_at",
+	UpdatedAt:   "updated_at",
+}
+
+// NewSysConfigDao creates and returns a new DAO object for table data access.
+func NewSysConfigDao() *SysConfigDao {
+	return &SysConfigDao{
+		group:   "default",
+		table:   "sys_config",
+		columns: sysConfigColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysConfigDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysConfigDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysConfigDao) Columns() SysConfigColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysConfigDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysConfigDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysConfigDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 98 - 0
internal/app/common/dao/internal/sys_dict_data.go

@@ -0,0 +1,98 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-16 16:32:52
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysDictDataDao is the data access object for table sys_dict_data.
+type SysDictDataDao struct {
+	table   string             // table is the underlying table name of the DAO.
+	group   string             // group is the database configuration group name of current DAO.
+	columns SysDictDataColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysDictDataColumns defines and stores column names for table sys_dict_data.
+type SysDictDataColumns struct {
+	DictCode  string // 字典编码
+	DictSort  string // 字典排序
+	DictLabel string // 字典标签
+	DictValue string // 字典键值
+	DictType  string // 字典类型
+	CssClass  string // 样式属性(其他样式扩展)
+	ListClass string // 表格回显样式
+	IsDefault string // 是否默认(1是 0否)
+	Status    string // 状态(0正常 1停用)
+	CreateBy  string // 创建者
+	UpdateBy  string // 更新者
+	Remark    string // 备注
+	CreatedAt string // 创建时间
+	UpdatedAt string // 修改时间
+}
+
+// sysDictDataColumns holds the columns for table sys_dict_data.
+var sysDictDataColumns = SysDictDataColumns{
+	DictCode:  "dict_code",
+	DictSort:  "dict_sort",
+	DictLabel: "dict_label",
+	DictValue: "dict_value",
+	DictType:  "dict_type",
+	CssClass:  "css_class",
+	ListClass: "list_class",
+	IsDefault: "is_default",
+	Status:    "status",
+	CreateBy:  "create_by",
+	UpdateBy:  "update_by",
+	Remark:    "remark",
+	CreatedAt: "created_at",
+	UpdatedAt: "updated_at",
+}
+
+// NewSysDictDataDao creates and returns a new DAO object for table data access.
+func NewSysDictDataDao() *SysDictDataDao {
+	return &SysDictDataDao{
+		group:   "default",
+		table:   "sys_dict_data",
+		columns: sysDictDataColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysDictDataDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysDictDataDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysDictDataDao) Columns() SysDictDataColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysDictDataDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysDictDataDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysDictDataDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 88 - 0
internal/app/common/dao/internal/sys_dict_type.go

@@ -0,0 +1,88 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-16 16:32:52
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysDictTypeDao is the data access object for table sys_dict_type.
+type SysDictTypeDao struct {
+	table   string             // table is the underlying table name of the DAO.
+	group   string             // group is the database configuration group name of current DAO.
+	columns SysDictTypeColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysDictTypeColumns defines and stores column names for table sys_dict_type.
+type SysDictTypeColumns struct {
+	DictId    string // 字典主键
+	DictName  string // 字典名称
+	DictType  string // 字典类型
+	Status    string // 状态(0正常 1停用)
+	CreateBy  string // 创建者
+	UpdateBy  string // 更新者
+	Remark    string // 备注
+	CreatedAt string // 创建日期
+	UpdatedAt string // 修改日期
+}
+
+// sysDictTypeColumns holds the columns for table sys_dict_type.
+var sysDictTypeColumns = SysDictTypeColumns{
+	DictId:    "dict_id",
+	DictName:  "dict_name",
+	DictType:  "dict_type",
+	Status:    "status",
+	CreateBy:  "create_by",
+	UpdateBy:  "update_by",
+	Remark:    "remark",
+	CreatedAt: "created_at",
+	UpdatedAt: "updated_at",
+}
+
+// NewSysDictTypeDao creates and returns a new DAO object for table data access.
+func NewSysDictTypeDao() *SysDictTypeDao {
+	return &SysDictTypeDao{
+		group:   "default",
+		table:   "sys_dict_type",
+		columns: sysDictTypeColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysDictTypeDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysDictTypeDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysDictTypeDao) Columns() SysDictTypeColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysDictTypeDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysDictTypeDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysDictTypeDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 24 - 0
internal/app/common/dao/sys_config.go

@@ -0,0 +1,24 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"github.com/tiger1103/gfast/v3/internal/app/common/dao/internal"
+)
+
+// sysConfigDao is the data access object for table sys_config.
+// You can define custom methods on it to extend its functionality as you wish.
+type sysConfigDao struct {
+	*internal.SysConfigDao
+}
+
+var (
+	// SysConfig is globally public accessible object for table sys_config operations.
+	SysConfig = sysConfigDao{
+		internal.NewSysConfigDao(),
+	}
+)
+
+// Fill with you ideas below.

+ 24 - 0
internal/app/common/dao/sys_dict_data.go

@@ -0,0 +1,24 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"github.com/tiger1103/gfast/v3/internal/app/common/dao/internal"
+)
+
+// sysDictDataDao is the data access object for table sys_dict_data.
+// You can define custom methods on it to extend its functionality as you wish.
+type sysDictDataDao struct {
+	*internal.SysDictDataDao
+}
+
+var (
+	// SysDictData is globally public accessible object for table sys_dict_data operations.
+	SysDictData = sysDictDataDao{
+		internal.NewSysDictDataDao(),
+	}
+)
+
+// Fill with you ideas below.

+ 24 - 0
internal/app/common/dao/sys_dict_type.go

@@ -0,0 +1,24 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"github.com/tiger1103/gfast/v3/internal/app/common/dao/internal"
+)
+
+// sysDictTypeDao is the data access object for table sys_dict_type.
+// You can define custom methods on it to extend its functionality as you wish.
+type sysDictTypeDao struct {
+	*internal.SysDictTypeDao
+}
+
+var (
+	// SysDictType is globally public accessible object for table sys_dict_type operations.
+	SysDictType = sysDictTypeDao{
+		internal.NewSysDictTypeDao(),
+	}
+)
+
+// Fill with you ideas below.

+ 45 - 0
internal/app/common/logic/cache/cache.go

@@ -0,0 +1,45 @@
+/*
+* @desc:缓存处理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/9/27 16:33
+ */
+
+package cache
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gctx"
+	"github.com/tiger1103/gfast-cache/cache"
+	"github.com/tiger1103/gfast/v3/internal/app/common/consts"
+	"github.com/tiger1103/gfast/v3/internal/app/common/service"
+)
+
+func init() {
+	service.RegisterCache(New())
+}
+
+func New() *sCache {
+	var (
+		ctx            = gctx.New()
+		cacheContainer *cache.GfCache
+	)
+	prefix := g.Cfg().MustGet(ctx, "system.cache.prefix").String()
+	model := g.Cfg().MustGet(ctx, "system.cache.model").String()
+	if model == consts.CacheModelRedis {
+		// redis
+		cacheContainer = cache.NewRedis(prefix)
+	} else {
+		// memory
+		cacheContainer = cache.New(prefix)
+	}
+	return &sCache{
+		GfCache: cacheContainer,
+		prefix:  prefix,
+	}
+}
+
+type sCache struct {
+	*cache.GfCache
+	prefix string
+}

+ 69 - 0
internal/app/common/logic/captcha/captcha.go

@@ -0,0 +1,69 @@
+/*
+* @desc:验证码处理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/9/28 9:01
+ */
+
+package captcha
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/text/gstr"
+	"github.com/mojocn/base64Captcha"
+	"github.com/tiger1103/gfast/v3/internal/app/common/service"
+)
+
+func init() {
+	service.RegisterCaptcha(New())
+}
+
+func New() *sCaptcha {
+	return &sCaptcha{
+		driver: &base64Captcha.DriverString{
+			Height:          80,
+			Width:           240,
+			NoiseCount:      50,
+			ShowLineOptions: 20,
+			Length:          4,
+			Source:          "abcdefghjkmnpqrstuvwxyz23456789",
+			Fonts:           []string{"chromohv.ttf"},
+		},
+		store: base64Captcha.DefaultMemStore,
+	}
+}
+
+type sCaptcha struct {
+	driver *base64Captcha.DriverString
+	store  base64Captcha.Store
+}
+
+var (
+	captcha = sCaptcha{
+		driver: &base64Captcha.DriverString{
+			Height:          80,
+			Width:           240,
+			NoiseCount:      50,
+			ShowLineOptions: 20,
+			Length:          4,
+			Source:          "abcdefghjkmnpqrstuvwxyz23456789",
+			Fonts:           []string{"chromohv.ttf"},
+		},
+		store: base64Captcha.DefaultMemStore,
+	}
+)
+
+// GetVerifyImgString 获取字母数字混合验证码
+func (s *sCaptcha) GetVerifyImgString(ctx context.Context) (idKeyC string, base64stringC string, err error) {
+	driver := s.driver.ConvertFonts()
+	c := base64Captcha.NewCaptcha(driver, s.store)
+	idKeyC, base64stringC, err = c.Generate()
+	return
+}
+
+// VerifyString 验证输入的验证码是否正确
+func (s *sCaptcha) VerifyString(id, answer string) bool {
+	c := base64Captcha.NewCaptcha(s.driver, s.store)
+	answer = gstr.ToLower(answer)
+	return c.Verify(id, answer, true)
+}

+ 14 - 0
internal/app/common/logic/logic.go

@@ -0,0 +1,14 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package logic
+
+import (
+	_ "github.com/tiger1103/gfast/v3/internal/app/common/logic/cache"
+	_ "github.com/tiger1103/gfast/v3/internal/app/common/logic/captcha"
+	_ "github.com/tiger1103/gfast/v3/internal/app/common/logic/middleware"
+	_ "github.com/tiger1103/gfast/v3/internal/app/common/logic/sysConfig"
+	_ "github.com/tiger1103/gfast/v3/internal/app/common/logic/sysDictData"
+	_ "github.com/tiger1103/gfast/v3/internal/app/common/logic/sysDictType"
+)

+ 31 - 0
internal/app/common/logic/middleware/middleware.go

@@ -0,0 +1,31 @@
+/*
+* @desc:中间件处理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/9/28 9:08
+ */
+
+package middleware
+
+import (
+	"github.com/gogf/gf/v2/net/ghttp"
+	"github.com/tiger1103/gfast/v3/internal/app/common/service"
+)
+
+func init() {
+	service.RegisterMiddleware(New())
+}
+
+func New() *sMiddleware {
+	return &sMiddleware{}
+}
+
+type sMiddleware struct{}
+
+func (s *sMiddleware) MiddlewareCORS(r *ghttp.Request) {
+	corsOptions := r.Response.DefaultCORSOptions()
+	// you can set options
+	//corsOptions.AllowDomain = []string{"goframe.org", "baidu.com"}
+	r.Response.CORS(corsOptions)
+	r.Middleware.Next()
+}

+ 178 - 0
internal/app/common/logic/sysConfig/sys_config.go

@@ -0,0 +1,178 @@
+/*
+* @desc:配置参数管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/9/28 9:13
+ */
+
+package sysConfig
+
+import (
+	"context"
+	"errors"
+	"github.com/gogf/gf/v2/errors/gerror"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/util/gconv"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/common/consts"
+	"github.com/tiger1103/gfast/v3/internal/app/common/dao"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model/do"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model/entity"
+	"github.com/tiger1103/gfast/v3/internal/app/common/service"
+	systemConsts "github.com/tiger1103/gfast/v3/internal/app/system/consts"
+	"github.com/tiger1103/gfast/v3/library/liberr"
+)
+
+func init() {
+	service.RegisterSysConfig(New())
+}
+
+func New() *sSysConfig {
+	return &sSysConfig{}
+}
+
+type sSysConfig struct {
+}
+
+// List 系统参数列表
+func (s *sSysConfig) List(ctx context.Context, req *system.ConfigSearchReq) (res *system.ConfigSearchRes, err error) {
+	res = new(system.ConfigSearchRes)
+	err = g.Try(ctx, func(ctx context.Context) {
+		m := dao.SysConfig.Ctx(ctx)
+		if req != nil {
+			if req.ConfigName != "" {
+				m = m.Where("config_name like ?", "%"+req.ConfigName+"%")
+			}
+			if req.ConfigType != "" {
+				m = m.Where("config_type = ", gconv.Int(req.ConfigType))
+			}
+			if req.ConfigKey != "" {
+				m = m.Where("config_key like ?", "%"+req.ConfigKey+"%")
+			}
+			if len(req.DateRange) > 0 {
+				m = m.Where("created_at >= ? AND created_at<=?", req.DateRange[0], req.DateRange[1])
+			}
+		}
+		res.Total, err = m.Count()
+		liberr.ErrIsNil(ctx, err, "获取数据失败")
+		if req.PageNum == 0 {
+			req.PageNum = 1
+		}
+		res.CurrentPage = req.PageNum
+		if req.PageSize == 0 {
+			req.PageSize = systemConsts.PageSize
+		}
+		err = m.Page(req.PageNum, req.PageSize).Order("config_id asc").Scan(&res.List)
+		liberr.ErrIsNil(ctx, err, "获取数据失败")
+	})
+	return
+}
+
+func (s *sSysConfig) Add(ctx context.Context, req *system.ConfigAddReq, userId uint64) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		err = s.CheckConfigKeyUnique(ctx, req.ConfigKey)
+		liberr.ErrIsNil(ctx, err)
+		_, err = dao.SysConfig.Ctx(ctx).Insert(do.SysConfig{
+			ConfigName:  req.ConfigName,
+			ConfigKey:   req.ConfigKey,
+			ConfigValue: req.ConfigValue,
+			ConfigType:  req.ConfigType,
+			CreateBy:    userId,
+			Remark:      req.Remark,
+		})
+		liberr.ErrIsNil(ctx, err, "添加系统参数失败")
+		//清除缓存
+		service.Cache().RemoveByTag(ctx, consts.CacheSysConfigTag)
+	})
+	return
+}
+
+// CheckConfigKeyUnique 验证参数键名是否存在
+func (s *sSysConfig) CheckConfigKeyUnique(ctx context.Context, configKey string, configId ...int64) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		data := (*entity.SysConfig)(nil)
+		m := dao.SysConfig.Ctx(ctx).Fields(dao.SysConfig.Columns().ConfigId).Where(dao.SysConfig.Columns().ConfigKey, configKey)
+		if len(configId) > 0 {
+			m = m.Where(dao.SysConfig.Columns().ConfigId+" != ?", configId[0])
+		}
+		err = m.Scan(&data)
+		liberr.ErrIsNil(ctx, err, "校验失败")
+		if data != nil {
+			liberr.ErrIsNil(ctx, errors.New("参数键名重复"))
+		}
+	})
+	return
+}
+
+// Get 获取系统参数
+func (s *sSysConfig) Get(ctx context.Context, id int) (res *system.ConfigGetRes, err error) {
+	res = new(system.ConfigGetRes)
+	err = g.Try(ctx, func(ctx context.Context) {
+		err = dao.SysConfig.Ctx(ctx).WherePri(id).Scan(&res.Data)
+		liberr.ErrIsNil(ctx, err, "获取系统参数失败")
+	})
+	return
+}
+
+// Edit 修改系统参数
+func (s *sSysConfig) Edit(ctx context.Context, req *system.ConfigEditReq, userId uint64) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		err = s.CheckConfigKeyUnique(ctx, req.ConfigKey, req.ConfigId)
+		liberr.ErrIsNil(ctx, err)
+		_, err = dao.SysConfig.Ctx(ctx).WherePri(req.ConfigId).Update(do.SysConfig{
+			ConfigName:  req.ConfigName,
+			ConfigKey:   req.ConfigKey,
+			ConfigValue: req.ConfigValue,
+			ConfigType:  req.ConfigType,
+			UpdateBy:    userId,
+			Remark:      req.Remark,
+		})
+		liberr.ErrIsNil(ctx, err, "修改系统参数失败")
+		//清除缓存
+		service.Cache().RemoveByTag(ctx, consts.CacheSysConfigTag)
+	})
+	return
+}
+
+// Delete 删除系统参数
+func (s *sSysConfig) Delete(ctx context.Context, ids []int) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		_, err = dao.SysConfig.Ctx(ctx).Delete(dao.SysConfig.Columns().ConfigId+" in (?)", ids)
+		liberr.ErrIsNil(ctx, err, "删除失败")
+		//清除缓存
+		service.Cache().RemoveByTag(ctx, consts.CacheSysConfigTag)
+	})
+	return
+}
+
+// GetConfigByKey 通过key获取参数(从缓存获取)
+func (s *sSysConfig) GetConfigByKey(ctx context.Context, key string) (config *entity.SysConfig, err error) {
+	if key == "" {
+		err = gerror.New("参数key不能为空")
+		return
+	}
+	cache := service.Cache()
+	cf := cache.Get(ctx, consts.CacheSysConfigTag+key)
+	if cf != nil && !cf.IsEmpty() {
+		err = gconv.Struct(cf, &config)
+		return
+	}
+	config, err = s.GetByKey(ctx, key)
+	if err != nil {
+		return
+	}
+	if config != nil {
+		cache.Set(ctx, consts.CacheSysConfigTag+key, config, 0, consts.CacheSysConfigTag)
+	}
+	return
+}
+
+// GetByKey 通过key获取参数(从数据库获取)
+func (s *sSysConfig) GetByKey(ctx context.Context, key string) (config *entity.SysConfig, err error) {
+	err = dao.SysConfig.Ctx(ctx).Where("config_key", key).Scan(&config)
+	if err != nil {
+		g.Log().Error(ctx, err)
+		err = gerror.New("获取配置失败")
+	}
+	return
+}

+ 173 - 0
internal/app/common/logic/sysDictData/sys_dict_data.go

@@ -0,0 +1,173 @@
+/*
+* @desc:字典数据管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/9/28 9:22
+ */
+
+package sysDictData
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/text/gstr"
+	"github.com/gogf/gf/v2/util/gconv"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/common/consts"
+	"github.com/tiger1103/gfast/v3/internal/app/common/dao"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model/do"
+	"github.com/tiger1103/gfast/v3/internal/app/common/service"
+	systemConsts "github.com/tiger1103/gfast/v3/internal/app/system/consts"
+	"github.com/tiger1103/gfast/v3/library/liberr"
+)
+
+func init() {
+	service.RegisterSysDictData(New())
+}
+
+func New() *sSysDictData {
+	return &sSysDictData{}
+}
+
+type sSysDictData struct {
+}
+
+// GetDictWithDataByType 通过字典键类型获取选项
+func (s *sSysDictData) GetDictWithDataByType(ctx context.Context, req *system.GetDictReq) (dict *system.GetDictRes,
+	err error) {
+	cache := service.Cache()
+	cacheKey := consts.CacheSysDict + "_" + req.DictType
+	//从缓存获取
+	iDict := cache.GetOrSetFuncLock(ctx, cacheKey, func(ctx context.Context) (value interface{}, err error) {
+		err = g.Try(ctx, func(ctx context.Context) {
+			//从数据库获取
+			dict = &system.GetDictRes{}
+			//获取类型数据
+			err = dao.SysDictType.Ctx(ctx).Where(dao.SysDictType.Columns().DictType, req.DictType).
+				Where(dao.SysDictType.Columns().Status, 1).Fields(model.DictTypeRes{}).Scan(&dict.Info)
+			liberr.ErrIsNil(ctx, err, "获取字典类型失败")
+			err = dao.SysDictData.Ctx(ctx).Fields(model.DictDataRes{}).
+				Where(dao.SysDictData.Columns().DictType, req.DictType).
+				Order(dao.SysDictData.Columns().DictSort + " asc," +
+					dao.SysDictData.Columns().DictCode + " asc").
+				Scan(&dict.Values)
+			liberr.ErrIsNil(ctx, err, "获取字典数据失败")
+		})
+		value = dict
+		return
+	}, 0, consts.CacheSysDictTag)
+	if iDict != nil {
+		err = gconv.Struct(iDict, &dict)
+		if err != nil {
+			return
+		}
+	}
+	//设置给定的默认值
+	for _, v := range dict.Values {
+		if req.DefaultValue != "" {
+			if gstr.Equal(req.DefaultValue, v.DictValue) {
+				v.IsDefault = 1
+			} else {
+				v.IsDefault = 0
+			}
+		}
+	}
+	return
+}
+
+// List 获取字典数据
+func (s *sSysDictData) List(ctx context.Context, req *system.DictDataSearchReq) (res *system.DictDataSearchRes, err error) {
+	res = new(system.DictDataSearchRes)
+	err = g.Try(ctx, func(ctx context.Context) {
+		m := dao.SysDictData.Ctx(ctx)
+		if req != nil {
+			if req.DictLabel != "" {
+				m = m.Where(dao.SysDictData.Columns().DictLabel+" like ?", "%"+req.DictLabel+"%")
+			}
+			if req.Status != "" {
+				m = m.Where(dao.SysDictData.Columns().Status+" = ", gconv.Int(req.Status))
+			}
+			if req.DictType != "" {
+				m = m.Where(dao.SysDictData.Columns().DictType+" = ?", req.DictType)
+			}
+			res.Total, err = m.Count()
+			liberr.ErrIsNil(ctx, err, "获取字典数据失败")
+			if req.PageNum == 0 {
+				req.PageNum = 1
+			}
+			res.CurrentPage = req.PageNum
+		}
+		if req.PageSize == 0 {
+			req.PageSize = systemConsts.PageSize
+		}
+		err = m.Page(req.PageNum, req.PageSize).Order(dao.SysDictData.Columns().DictSort + " asc," +
+			dao.SysDictData.Columns().DictCode + " asc").Scan(&res.List)
+		liberr.ErrIsNil(ctx, err, "获取字典数据失败")
+	})
+	return
+}
+
+func (s *sSysDictData) Add(ctx context.Context, req *system.DictDataAddReq, userId uint64) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		_, err = dao.SysDictData.Ctx(ctx).Insert(do.SysDictData{
+			DictSort:  req.DictSort,
+			DictLabel: req.DictLabel,
+			DictValue: req.DictValue,
+			DictType:  req.DictType,
+			CssClass:  req.CssClass,
+			ListClass: req.ListClass,
+			IsDefault: req.IsDefault,
+			Status:    req.Status,
+			CreateBy:  userId,
+			Remark:    req.Remark,
+		})
+		liberr.ErrIsNil(ctx, err, "添加字典数据失败")
+		//清除缓存
+		service.Cache().RemoveByTag(ctx, consts.CacheSysDictTag)
+	})
+	return
+}
+
+// Get 获取字典数据
+func (s *sSysDictData) Get(ctx context.Context, dictCode uint) (res *system.DictDataGetRes, err error) {
+	res = new(system.DictDataGetRes)
+	err = g.Try(ctx, func(ctx context.Context) {
+		err = dao.SysDictData.Ctx(ctx).WherePri(dictCode).Scan(&res.Dict)
+		liberr.ErrIsNil(ctx, err, "获取字典数据失败")
+	})
+	return
+}
+
+// Edit 修改字典数据
+func (s *sSysDictData) Edit(ctx context.Context, req *system.DictDataEditReq, userId uint64) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		_, err = dao.SysDictData.Ctx(ctx).WherePri(req.DictCode).Update(do.SysDictData{
+			DictSort:  req.DictSort,
+			DictLabel: req.DictLabel,
+			DictValue: req.DictValue,
+			DictType:  req.DictType,
+			CssClass:  req.CssClass,
+			ListClass: req.ListClass,
+			IsDefault: req.IsDefault,
+			Status:    req.Status,
+			UpdateBy:  userId,
+			Remark:    req.Remark,
+		})
+		liberr.ErrIsNil(ctx, err, "修改字典数据失败")
+		//清除缓存
+		service.Cache().RemoveByTag(ctx, consts.CacheSysDictTag)
+	})
+	return
+}
+
+// Delete 删除字典数据
+func (s *sSysDictData) Delete(ctx context.Context, ids []int) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		_, err = dao.SysDictData.Ctx(ctx).Where(dao.SysDictData.Columns().DictCode+" in(?)", ids).Delete()
+		liberr.ErrIsNil(ctx, err, "删除字典数据失败")
+		//清除缓存
+		service.Cache().RemoveByTag(ctx, consts.CacheSysDictTag)
+	})
+	return
+}

+ 186 - 0
internal/app/common/logic/sysDictType/sys_dict_type.go

@@ -0,0 +1,186 @@
+/*
+* @desc:字典类型管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/9/28 9:26
+ */
+
+package sysDictType
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/container/garray"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/errors/gerror"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/util/gconv"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/common/consts"
+	"github.com/tiger1103/gfast/v3/internal/app/common/dao"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model/do"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model/entity"
+	"github.com/tiger1103/gfast/v3/internal/app/common/service"
+	systemConsts "github.com/tiger1103/gfast/v3/internal/app/system/consts"
+	"github.com/tiger1103/gfast/v3/library/liberr"
+)
+
+func init() {
+	service.RegisterSysDictType(New())
+}
+
+func New() *sSysDictType {
+	return &sSysDictType{}
+}
+
+type sSysDictType struct {
+}
+
+// List 字典类型列表
+func (s *sSysDictType) List(ctx context.Context, req *system.DictTypeSearchReq) (res *system.DictTypeSearchRes, err error) {
+	res = new(system.DictTypeSearchRes)
+	err = g.Try(ctx, func(ctx context.Context) {
+		m := dao.SysDictType.Ctx(ctx)
+		if req.DictName != "" {
+			m = m.Where(dao.SysDictType.Columns().DictName+" like ?", "%"+req.DictName+"%")
+		}
+		if req.DictType != "" {
+			m = m.Where(dao.SysDictType.Columns().DictType+" like ?", "%"+req.DictType+"%")
+		}
+		if req.Status != "" {
+			m = m.Where(dao.SysDictType.Columns().Status+" = ", gconv.Int(req.Status))
+		}
+		res.Total, err = m.Count()
+		liberr.ErrIsNil(ctx, err, "获取字典类型失败")
+		if req.PageNum == 0 {
+			req.PageNum = 1
+		}
+		res.CurrentPage = req.PageNum
+		if req.PageSize == 0 {
+			req.PageSize = systemConsts.PageSize
+		}
+		err = m.Fields(model.SysDictTypeInfoRes{}).Page(req.PageNum, req.PageSize).
+			Order(dao.SysDictType.Columns().DictId + " asc").Scan(&res.DictTypeList)
+		liberr.ErrIsNil(ctx, err, "获取字典类型失败")
+	})
+	return
+}
+
+// Add 添加字典类型
+func (s *sSysDictType) Add(ctx context.Context, req *system.DictTypeAddReq, userId uint64) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		err = s.ExistsDictType(ctx, req.DictType)
+		liberr.ErrIsNil(ctx, err)
+		_, err = dao.SysDictType.Ctx(ctx).Insert(do.SysDictType{
+			DictName: req.DictName,
+			DictType: req.DictType,
+			Status:   req.Status,
+			CreateBy: userId,
+			Remark:   req.Remark,
+		})
+		liberr.ErrIsNil(ctx, err, "添加字典类型失败")
+		//清除缓存
+		service.Cache().RemoveByTag(ctx, consts.CacheSysDictTag)
+	})
+	return
+}
+
+// Edit 修改字典类型
+func (s *sSysDictType) Edit(ctx context.Context, req *system.DictTypeEditReq, userId uint64) (err error) {
+	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
+		err = g.Try(ctx, func(ctx context.Context) {
+			err = s.ExistsDictType(ctx, req.DictType, req.DictId)
+			liberr.ErrIsNil(ctx, err)
+			dictType := (*entity.SysDictType)(nil)
+			e := dao.SysDictType.Ctx(ctx).Fields(dao.SysDictType.Columns().DictType).WherePri(req.DictId).Scan(&dictType)
+			liberr.ErrIsNil(ctx, e, "获取字典类型失败")
+			liberr.ValueIsNil(dictType, "字典类型不存在")
+			//修改字典类型
+			_, e = dao.SysDictType.Ctx(ctx).TX(tx).WherePri(req.DictId).Update(do.SysDictType{
+				DictName: req.DictName,
+				DictType: req.DictType,
+				Status:   req.Status,
+				UpdateBy: userId,
+				Remark:   req.Remark,
+			})
+			liberr.ErrIsNil(ctx, e, "修改字典类型失败")
+			//修改字典数据
+			_, e = dao.SysDictData.Ctx(ctx).TX(tx).Data(do.SysDictData{DictType: req.DictType}).
+				Where(dao.SysDictData.Columns().DictType, dictType.DictType).Update()
+			liberr.ErrIsNil(ctx, e, "修改字典数据失败")
+			//清除缓存
+			service.Cache().RemoveByTag(ctx, consts.CacheSysDictTag)
+		})
+		return err
+	})
+	return
+}
+
+func (s *sSysDictType) Get(ctx context.Context, req *system.DictTypeGetReq) (dictType *entity.SysDictType, err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		err = dao.SysDictType.Ctx(ctx).Where(dao.SysDictType.Columns().DictId, req.DictId).Scan(&dictType)
+		liberr.ErrIsNil(ctx, err, "获取字典类型失败")
+	})
+	return
+}
+
+// ExistsDictType 检查类型是否已经存在
+func (s *sSysDictType) ExistsDictType(ctx context.Context, dictType string, dictId ...int64) (err error) {
+	err = g.Try(ctx, func(ctx context.Context) {
+		m := dao.SysDictType.Ctx(ctx).Fields(dao.SysDictType.Columns().DictId).
+			Where(dao.SysDictType.Columns().DictType, dictType)
+		if len(dictId) > 0 {
+			m = m.Where(dao.SysDictType.Columns().DictId+" !=? ", dictId[0])
+		}
+		res, e := m.One()
+		liberr.ErrIsNil(ctx, e, "sql err")
+		if !res.IsEmpty() {
+			liberr.ErrIsNil(ctx, gerror.New("字典类型已存在"))
+		}
+	})
+	return
+}
+
+// Delete 删除字典类型
+func (s *sSysDictType) Delete(ctx context.Context, dictIds []int) (err error) {
+	err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
+		err = g.Try(ctx, func(ctx context.Context) {
+			discs := ([]*entity.SysDictType)(nil)
+			err = dao.SysDictType.Ctx(ctx).Fields(dao.SysDictType.Columns().DictType).
+				Where(dao.SysDictType.Columns().DictId+" in (?) ", dictIds).Scan(&discs)
+			liberr.ErrIsNil(ctx, err, "删除失败")
+			types := garray.NewStrArray()
+			for _, dt := range discs {
+				types.Append(dt.DictType)
+			}
+			if types.Len() > 0 {
+				_, err = dao.SysDictType.Ctx(ctx).TX(tx).Delete(dao.SysDictType.Columns().DictId+" in (?) ", dictIds)
+				liberr.ErrIsNil(ctx, err, "删除类型失败")
+				_, err = dao.SysDictData.Ctx(ctx).TX(tx).Delete(dao.SysDictData.Columns().DictType+" in (?) ", types.Slice())
+				liberr.ErrIsNil(ctx, err, "删除字典数据失败")
+			}
+			//清除缓存
+			service.Cache().RemoveByTag(ctx, consts.CacheSysDictTag)
+		})
+		return err
+	})
+	return
+}
+
+// GetAllDictType 获取所有正常状态下的字典类型
+func (s *sSysDictType) GetAllDictType(ctx context.Context) (list []*entity.SysDictType, err error) {
+	cache := service.Cache()
+	//从缓存获取
+	data := cache.Get(ctx, consts.CacheSysDict+"_dict_type_all")
+	if !data.IsNil() {
+		err = data.Structs(&list)
+		return
+	}
+	err = g.Try(ctx, func(ctx context.Context) {
+		err = dao.SysDictType.Ctx(ctx).Where("status", 1).Order("dict_id ASC").Scan(&list)
+		liberr.ErrIsNil(ctx, err, "获取字典类型数据出错")
+		//缓存
+		cache.Set(ctx, consts.CacheSysDict+"_dict_type_all", list, 0, consts.CacheSysDictTag)
+	})
+	return
+}

+ 21 - 0
internal/app/common/model/do/casbin_rule.go

@@ -0,0 +1,21 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package do
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// CasbinRule is the golang structure of table casbin_rule for DAO operations like Where/Data.
+type CasbinRule struct {
+	g.Meta `orm:"table:casbin_rule, do:true"`
+	Ptype  interface{} //
+	V0     interface{} //
+	V1     interface{} //
+	V2     interface{} //
+	V3     interface{} //
+	V4     interface{} //
+	V5     interface{} //
+}

+ 25 - 0
internal/app/common/model/do/sys_config.go

@@ -0,0 +1,25 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-18 21:09:17
+// =================================================================================
+
+package do
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gtime"
+)
+
+// SysConfig is the golang structure of table sys_config for DAO operations like Where/Data.
+type SysConfig struct {
+	g.Meta      `orm:"table:sys_config, do:true"`
+	ConfigId    interface{} // 参数主键
+	ConfigName  interface{} // 参数名称
+	ConfigKey   interface{} // 参数键名
+	ConfigValue interface{} // 参数键值
+	ConfigType  interface{} // 系统内置(Y是 N否)
+	CreateBy    interface{} // 创建者
+	UpdateBy    interface{} // 更新者
+	Remark      interface{} // 备注
+	CreatedAt   *gtime.Time // 创建时间
+	UpdatedAt   *gtime.Time // 修改时间
+}

+ 29 - 0
internal/app/common/model/do/sys_dict_data.go

@@ -0,0 +1,29 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-16 16:32:52
+// =================================================================================
+
+package do
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gtime"
+)
+
+// SysDictData is the golang structure of table sys_dict_data for DAO operations like Where/Data.
+type SysDictData struct {
+	g.Meta    `orm:"table:sys_dict_data, do:true"`
+	DictCode  interface{} // 字典编码
+	DictSort  interface{} // 字典排序
+	DictLabel interface{} // 字典标签
+	DictValue interface{} // 字典键值
+	DictType  interface{} // 字典类型
+	CssClass  interface{} // 样式属性(其他样式扩展)
+	ListClass interface{} // 表格回显样式
+	IsDefault interface{} // 是否默认(1是 0否)
+	Status    interface{} // 状态(0正常 1停用)
+	CreateBy  interface{} // 创建者
+	UpdateBy  interface{} // 更新者
+	Remark    interface{} // 备注
+	CreatedAt *gtime.Time // 创建时间
+	UpdatedAt *gtime.Time // 修改时间
+}

+ 24 - 0
internal/app/common/model/do/sys_dict_type.go

@@ -0,0 +1,24 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-16 16:32:52
+// =================================================================================
+
+package do
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/os/gtime"
+)
+
+// SysDictType is the golang structure of table sys_dict_type for DAO operations like Where/Data.
+type SysDictType struct {
+	g.Meta    `orm:"table:sys_dict_type, do:true"`
+	DictId    interface{} // 字典主键
+	DictName  interface{} // 字典名称
+	DictType  interface{} // 字典类型
+	Status    interface{} // 状态(0正常 1停用)
+	CreateBy  interface{} // 创建者
+	UpdateBy  interface{} // 更新者
+	Remark    interface{} // 备注
+	CreatedAt *gtime.Time // 创建日期
+	UpdatedAt *gtime.Time // 修改日期
+}

+ 16 - 0
internal/app/common/model/entity/casbin_rule.go

@@ -0,0 +1,16 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package entity
+
+// CasbinRule is the golang structure for table casbin_rule.
+type CasbinRule struct {
+	Ptype string `json:"ptype" description:""`
+	V0    string `json:"v0"    description:""`
+	V1    string `json:"v1"    description:""`
+	V2    string `json:"v2"    description:""`
+	V3    string `json:"v3"    description:""`
+	V4    string `json:"v4"    description:""`
+	V5    string `json:"v5"    description:""`
+}

+ 23 - 0
internal/app/common/model/entity/sys_config.go

@@ -0,0 +1,23 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-18 21:09:17
+// =================================================================================
+
+package entity
+
+import (
+	"github.com/gogf/gf/v2/os/gtime"
+)
+
+// SysConfig is the golang structure for table sys_config.
+type SysConfig struct {
+	ConfigId    uint        `json:"configId"    description:"参数主键"`
+	ConfigName  string      `json:"configName"  description:"参数名称"`
+	ConfigKey   string      `json:"configKey"   description:"参数键名"`
+	ConfigValue string      `json:"configValue" description:"参数键值"`
+	ConfigType  int         `json:"configType"  description:"系统内置(Y是 N否)"`
+	CreateBy    uint        `json:"createBy"    description:"创建者"`
+	UpdateBy    uint        `json:"updateBy"    description:"更新者"`
+	Remark      string      `json:"remark"      description:"备注"`
+	CreatedAt   *gtime.Time `json:"createdAt"   description:"创建时间"`
+	UpdatedAt   *gtime.Time `json:"updatedAt"   description:"修改时间"`
+}

+ 27 - 0
internal/app/common/model/entity/sys_dict_data.go

@@ -0,0 +1,27 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-16 16:32:52
+// =================================================================================
+
+package entity
+
+import (
+	"github.com/gogf/gf/v2/os/gtime"
+)
+
+// SysDictData is the golang structure for table sys_dict_data.
+type SysDictData struct {
+	DictCode  int64       `json:"dictCode"  description:"字典编码"`
+	DictSort  int         `json:"dictSort"  description:"字典排序"`
+	DictLabel string      `json:"dictLabel" description:"字典标签"`
+	DictValue string      `json:"dictValue" description:"字典键值"`
+	DictType  string      `json:"dictType"  description:"字典类型"`
+	CssClass  string      `json:"cssClass"  description:"样式属性(其他样式扩展)"`
+	ListClass string      `json:"listClass" description:"表格回显样式"`
+	IsDefault int         `json:"isDefault" description:"是否默认(1是 0否)"`
+	Status    int         `json:"status"    description:"状态(0正常 1停用)"`
+	CreateBy  uint64      `json:"createBy"  description:"创建者"`
+	UpdateBy  uint64      `json:"updateBy"  description:"更新者"`
+	Remark    string      `json:"remark"    description:"备注"`
+	CreatedAt *gtime.Time `json:"createdAt" description:"创建时间"`
+	UpdatedAt *gtime.Time `json:"updatedAt" description:"修改时间"`
+}

+ 22 - 0
internal/app/common/model/entity/sys_dict_type.go

@@ -0,0 +1,22 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-16 16:32:52
+// =================================================================================
+
+package entity
+
+import (
+	"github.com/gogf/gf/v2/os/gtime"
+)
+
+// SysDictType is the golang structure for table sys_dict_type.
+type SysDictType struct {
+	DictId    uint64      `json:"dictId"    description:"字典主键"`
+	DictName  string      `json:"dictName"  description:"字典名称"`
+	DictType  string      `json:"dictType"  description:"字典类型"`
+	Status    uint        `json:"status"    description:"状态(0正常 1停用)"`
+	CreateBy  uint        `json:"createBy"  description:"创建者"`
+	UpdateBy  uint        `json:"updateBy"  description:"更新者"`
+	Remark    string      `json:"remark"    description:"备注"`
+	CreatedAt *gtime.Time `json:"createdAt" description:"创建日期"`
+	UpdatedAt *gtime.Time `json:"updatedAt" description:"修改日期"`
+}

+ 8 - 0
internal/app/common/model/sys_config.go

@@ -0,0 +1,8 @@
+/*
+* @desc:xxxx功能描述
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/18 11:56
+ */
+
+package model

+ 21 - 0
internal/app/common/model/sys_dict_data.go

@@ -0,0 +1,21 @@
+/*
+* @desc:字典数据
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/18 11:56
+ */
+
+package model
+
+type DictTypeRes struct {
+	DictName string `json:"name"`
+	Remark   string `json:"remark"`
+}
+
+// DictDataRes 字典数据
+type DictDataRes struct {
+	DictValue string `json:"key"`
+	DictLabel string `json:"value"`
+	IsDefault int    `json:"isDefault"`
+	Remark    string `json:"remark"`
+}

+ 19 - 0
internal/app/common/model/sys_dict_type.go

@@ -0,0 +1,19 @@
+/*
+* @desc:字典类型
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/18 11:56
+ */
+
+package model
+
+import "github.com/gogf/gf/v2/os/gtime"
+
+type SysDictTypeInfoRes struct {
+	DictId    uint64      `orm:"dict_id,primary"  json:"dictId"`    // 字典主键
+	DictName  string      `orm:"dict_name"        json:"dictName"`  // 字典名称
+	DictType  string      `orm:"dict_type,unique" json:"dictType"`  // 字典类型
+	Status    uint        `orm:"status"           json:"status"`    // 状态(0正常 1停用)
+	Remark    string      `orm:"remark"           json:"remark"`    // 备注
+	CreatedAt *gtime.Time `orm:"created_at"       json:"createdAt"` // 创建日期
+}

+ 32 - 0
internal/app/common/model/token.go

@@ -0,0 +1,32 @@
+/*
+* @desc:token options
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/8 16:02
+ */
+
+package model
+
+import (
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+type TokenOptions struct {
+	//  server name
+	ServerName string `json:"serverName"`
+	// 缓存key (每创建一个实例CacheKey必须不相同)
+	CacheKey string `json:"cacheKey"`
+	// 超时时间 默认10天(秒)
+	Timeout int64 `json:"timeout"`
+	// 缓存刷新时间 默认5天(秒)
+	// 处理携带token的请求时当前时间大于超时时间并小于缓存刷新时间时token将自动刷新即重置token存活时间
+	// MaxRefresh值为0时,token将不会自动刷新
+	MaxRefresh int64 `json:"maxRefresh"`
+	// 是否允许多点登录
+	MultiLogin bool `json:"multiLogin"`
+	// Token加密key 32位
+	EncryptKey []byte `json:"encryptKey"`
+	// 拦截排除地址
+	ExcludePaths g.SliceStr `json:"excludePaths"`
+	CacheModel   string     `json:"cacheModel"`
+}

+ 28 - 0
internal/app/common/router/router.go

@@ -0,0 +1,28 @@
+/*
+* @desc:后台路由
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/2/18 17:34
+ */
+
+package router
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/net/ghttp"
+	"github.com/tiger1103/gfast/v3/internal/app/common/controller"
+)
+
+var R = new(Router)
+
+type Router struct{}
+
+func (router *Router) BindController(ctx context.Context, group *ghttp.RouterGroup) {
+	group.Group("/pub", func(group *ghttp.RouterGroup) {
+		group.Group("/captcha", func(group *ghttp.RouterGroup) {
+			group.Bind(
+				controller.Captcha,
+			)
+		})
+	})
+}

+ 29 - 0
internal/app/common/service/cache.go

@@ -0,0 +1,29 @@
+/*
+* @desc:缓存处理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/9 11:15
+ */
+
+package service
+
+import (
+	"github.com/tiger1103/gfast-cache/cache"
+)
+
+type ICache interface {
+	cache.IGCache
+}
+
+var c ICache
+
+func Cache() ICache {
+	if c == nil {
+		panic("implement not found for interface ICache, forgot register?")
+	}
+	return c
+}
+
+func RegisterCache(che ICache) {
+	c = che
+}

+ 28 - 0
internal/app/common/service/captcha.go

@@ -0,0 +1,28 @@
+// ================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// You can delete these comments if you wish manually maintain this interface file.
+// ================================================================================
+
+package service
+
+import (
+	"context"
+)
+
+type ICaptcha interface {
+	GetVerifyImgString(ctx context.Context) (idKeyC string, base64stringC string, err error)
+	VerifyString(id, answer string) bool
+}
+
+var localCaptcha ICaptcha
+
+func Captcha() ICaptcha {
+	if localCaptcha == nil {
+		panic("implement not found for interface ICaptcha, forgot register?")
+	}
+	return localCaptcha
+}
+
+func RegisterCaptcha(i ICaptcha) {
+	localCaptcha = i
+}

+ 220 - 0
internal/app/common/service/casbin.go

@@ -0,0 +1,220 @@
+package service
+
+import (
+	"context"
+	"sync"
+
+	"github.com/casbin/casbin/v2"
+	"github.com/casbin/casbin/v2/model"
+	"github.com/casbin/casbin/v2/persist"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/tiger1103/gfast/v3/internal/app/common/dao"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model/entity"
+)
+
+type cabinImpl struct{}
+
+type adapterCasbin struct {
+	Enforcer    *casbin.SyncedEnforcer
+	EnforcerErr error
+	ctx         context.Context
+}
+
+var (
+	cb   = cabinImpl{}
+	once sync.Once
+	ac   *adapterCasbin
+)
+
+// CasbinEnforcer 获取adapter单例对象
+func CasbinEnforcer(ctx context.Context) (enforcer *casbin.SyncedEnforcer, err error) {
+	once.Do(func() {
+		ac = cb.newAdapter(ctx)
+	})
+	enforcer = ac.Enforcer
+	err = ac.EnforcerErr
+	return
+}
+
+// 初始化adapter操作
+func (s *cabinImpl) newAdapter(ctx context.Context) (a *adapterCasbin) {
+	a = new(adapterCasbin)
+	a.initPolicy(ctx)
+	a.ctx = ctx
+	return
+}
+
+func (a *adapterCasbin) initPolicy(ctx context.Context) {
+	// Because the DB is empty at first,
+	// so we need to load the policy from the file adapter (.CSV) first.
+	e, err := casbin.NewSyncedEnforcer(g.Cfg().MustGet(ctx, "casbin.modelFile").String(), a)
+	if err != nil {
+		a.EnforcerErr = err
+		return
+	}
+	a.Enforcer = e
+}
+
+// SavePolicy saves policy to database.
+func (a *adapterCasbin) SavePolicy(model model.Model) (err error) {
+	err = a.dropTable()
+	if err != nil {
+		return
+	}
+	err = a.createTable()
+	if err != nil {
+		return
+	}
+	for ptype, ast := range model["p"] {
+		for _, rule := range ast.Policy {
+			line := savePolicyLine(ptype, rule)
+			_, err := dao.CasbinRule.Ctx(a.ctx).Data(line).Insert()
+			if err != nil {
+				return err
+			}
+		}
+	}
+
+	for ptype, ast := range model["g"] {
+		for _, rule := range ast.Policy {
+			line := savePolicyLine(ptype, rule)
+			_, err := dao.CasbinRule.Ctx(a.ctx).Data(line).Insert()
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return
+}
+
+func (a *adapterCasbin) dropTable() (err error) {
+	return
+}
+
+func (a *adapterCasbin) createTable() (err error) {
+	return
+}
+
+// LoadPolicy loads policy from database.
+func (a *adapterCasbin) LoadPolicy(model model.Model) error {
+	var lines []*entity.CasbinRule
+	if err := dao.CasbinRule.Ctx(a.ctx).Scan(&lines); err != nil {
+		return err
+	}
+	for _, line := range lines {
+		loadPolicyLine(line, model)
+	}
+	return nil
+}
+
+// AddPolicy adds a policy rule to the storage.
+func (a *adapterCasbin) AddPolicy(sec string, ptype string, rule []string) error {
+	line := savePolicyLine(ptype, rule)
+	_, err := dao.CasbinRule.Ctx(a.ctx).Data(line).Insert()
+	return err
+}
+
+// RemovePolicy removes a policy rule from the storage.
+func (a *adapterCasbin) RemovePolicy(sec string, ptype string, rule []string) error {
+	line := savePolicyLine(ptype, rule)
+	err := rawDelete(a, line)
+	return err
+}
+
+// RemoveFilteredPolicy removes policy rules that match the filter from the storage.
+func (a *adapterCasbin) RemoveFilteredPolicy(sec string, ptype string,
+	fieldIndex int, fieldValues ...string) error {
+	line := &entity.CasbinRule{}
+	line.Ptype = ptype
+	if fieldIndex <= 0 && 0 < fieldIndex+len(fieldValues) {
+		line.V0 = fieldValues[0-fieldIndex]
+	}
+	if fieldIndex <= 1 && 1 < fieldIndex+len(fieldValues) {
+		line.V1 = fieldValues[1-fieldIndex]
+	}
+	if fieldIndex <= 2 && 2 < fieldIndex+len(fieldValues) {
+		line.V2 = fieldValues[2-fieldIndex]
+	}
+	if fieldIndex <= 3 && 3 < fieldIndex+len(fieldValues) {
+		line.V3 = fieldValues[3-fieldIndex]
+	}
+	if fieldIndex <= 4 && 4 < fieldIndex+len(fieldValues) {
+		line.V4 = fieldValues[4-fieldIndex]
+	}
+	if fieldIndex <= 5 && 5 < fieldIndex+len(fieldValues) {
+		line.V5 = fieldValues[5-fieldIndex]
+	}
+	err := rawDelete(a, line)
+	return err
+}
+
+func loadPolicyLine(line *entity.CasbinRule, model model.Model) {
+	lineText := line.Ptype
+	if line.V0 != "" {
+		lineText += ", " + line.V0
+	}
+	if line.V1 != "" {
+		lineText += ", " + line.V1
+	}
+	if line.V2 != "" {
+		lineText += ", " + line.V2
+	}
+	if line.V3 != "" {
+		lineText += ", " + line.V3
+	}
+	if line.V4 != "" {
+		lineText += ", " + line.V4
+	}
+	if line.V5 != "" {
+		lineText += ", " + line.V5
+	}
+	persist.LoadPolicyLine(lineText, model)
+}
+
+func savePolicyLine(ptype string, rule []string) *entity.CasbinRule {
+	line := &entity.CasbinRule{}
+	line.Ptype = ptype
+	if len(rule) > 0 {
+		line.V0 = rule[0]
+	}
+	if len(rule) > 1 {
+		line.V1 = rule[1]
+	}
+	if len(rule) > 2 {
+		line.V2 = rule[2]
+	}
+	if len(rule) > 3 {
+		line.V3 = rule[3]
+	}
+	if len(rule) > 4 {
+		line.V4 = rule[4]
+	}
+	if len(rule) > 5 {
+		line.V5 = rule[5]
+	}
+	return line
+}
+
+func rawDelete(a *adapterCasbin, line *entity.CasbinRule) error {
+	db := dao.CasbinRule.Ctx(a.ctx).Where("ptype = ?", line.Ptype)
+	if line.V0 != "" {
+		db = db.Where("v0 = ?", line.V0)
+	}
+	if line.V1 != "" {
+		db = db.Where("v1 = ?", line.V1)
+	}
+	if line.V2 != "" {
+		db = db.Where("v2 = ?", line.V2)
+	}
+	if line.V3 != "" {
+		db = db.Where("v3 = ?", line.V3)
+	}
+	if line.V4 != "" {
+		db = db.Where("v4 = ?", line.V4)
+	}
+	if line.V5 != "" {
+		db = db.Where("v5 = ?", line.V5)
+	}
+	_, err := db.Delete()
+	return err
+}

+ 27 - 0
internal/app/common/service/middleware.go

@@ -0,0 +1,27 @@
+// ================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// You can delete these comments if you wish manually maintain this interface file.
+// ================================================================================
+
+package service
+
+import (
+	"github.com/gogf/gf/v2/net/ghttp"
+)
+
+type IMiddleware interface {
+	MiddlewareCORS(r *ghttp.Request)
+}
+
+var localMiddleware IMiddleware
+
+func Middleware() IMiddleware {
+	if localMiddleware == nil {
+		panic("implement not found for interface IMiddleware, forgot register?")
+	}
+	return localMiddleware
+}
+
+func RegisterMiddleware(i IMiddleware) {
+	localMiddleware = i
+}

+ 37 - 0
internal/app/common/service/sys_config.go

@@ -0,0 +1,37 @@
+// ================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// You can delete these comments if you wish manually maintain this interface file.
+// ================================================================================
+
+package service
+
+import (
+	"context"
+
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model/entity"
+)
+
+type ISysConfig interface {
+	List(ctx context.Context, req *system.ConfigSearchReq) (res *system.ConfigSearchRes, err error)
+	Add(ctx context.Context, req *system.ConfigAddReq, userId uint64) (err error)
+	CheckConfigKeyUnique(ctx context.Context, configKey string, configId ...int64) (err error)
+	Get(ctx context.Context, id int) (res *system.ConfigGetRes, err error)
+	Edit(ctx context.Context, req *system.ConfigEditReq, userId uint64) (err error)
+	Delete(ctx context.Context, ids []int) (err error)
+	GetConfigByKey(ctx context.Context, key string) (config *entity.SysConfig, err error)
+	GetByKey(ctx context.Context, key string) (config *entity.SysConfig, err error)
+}
+
+var localSysConfig ISysConfig
+
+func SysConfig() ISysConfig {
+	if localSysConfig == nil {
+		panic("implement not found for interface ISysConfig, forgot register?")
+	}
+	return localSysConfig
+}
+
+func RegisterSysConfig(i ISysConfig) {
+	localSysConfig = i
+}

+ 34 - 0
internal/app/common/service/sys_dict_data.go

@@ -0,0 +1,34 @@
+// ================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// You can delete these comments if you wish manually maintain this interface file.
+// ================================================================================
+
+package service
+
+import (
+	"context"
+
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+)
+
+type ISysDictData interface {
+	GetDictWithDataByType(ctx context.Context, req *system.GetDictReq) (dict *system.GetDictRes, err error)
+	List(ctx context.Context, req *system.DictDataSearchReq) (res *system.DictDataSearchRes, err error)
+	Add(ctx context.Context, req *system.DictDataAddReq, userId uint64) (err error)
+	Get(ctx context.Context, dictCode uint) (res *system.DictDataGetRes, err error)
+	Edit(ctx context.Context, req *system.DictDataEditReq, userId uint64) (err error)
+	Delete(ctx context.Context, ids []int) (err error)
+}
+
+var localSysDictData ISysDictData
+
+func SysDictData() ISysDictData {
+	if localSysDictData == nil {
+		panic("implement not found for interface ISysDictData, forgot register?")
+	}
+	return localSysDictData
+}
+
+func RegisterSysDictData(i ISysDictData) {
+	localSysDictData = i
+}

+ 36 - 0
internal/app/common/service/sys_dict_type.go

@@ -0,0 +1,36 @@
+// ================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// You can delete these comments if you wish manually maintain this interface file.
+// ================================================================================
+
+package service
+
+import (
+	"context"
+
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/common/model/entity"
+)
+
+type ISysDictType interface {
+	List(ctx context.Context, req *system.DictTypeSearchReq) (res *system.DictTypeSearchRes, err error)
+	Add(ctx context.Context, req *system.DictTypeAddReq, userId uint64) (err error)
+	Edit(ctx context.Context, req *system.DictTypeEditReq, userId uint64) (err error)
+	Get(ctx context.Context, req *system.DictTypeGetReq) (dictType *entity.SysDictType, err error)
+	ExistsDictType(ctx context.Context, dictType string, dictId ...int64) (err error)
+	Delete(ctx context.Context, dictIds []int) (err error)
+	GetAllDictType(ctx context.Context) (list []*entity.SysDictType, err error)
+}
+
+var localSysDictType ISysDictType
+
+func SysDictType() ISysDictType {
+	if localSysDictType == nil {
+		panic("implement not found for interface ISysDictType, forgot register?")
+	}
+	return localSysDictType
+}
+
+func RegisterSysDictType(i ISysDictType) {
+	localSysDictType = i
+}

+ 29 - 0
internal/app/system/consts/cache.go

@@ -0,0 +1,29 @@
+/*
+* @desc:缓存键
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/9 12:06
+ */
+
+package consts
+
+const (
+	// CacheSysAuthMenu 缓存菜单key
+	CacheSysAuthMenu = "sysAuthMenu"
+	// CacheSysDept 缓存部门key
+	CacheSysDept = "sysDept"
+
+	// CacheSysRole 角色缓存key
+	CacheSysRole = "sysRole"
+	// CacheSysWebSet 站点配置缓存key
+	CacheSysWebSet = "sysWebSet"
+	// CacheSysCmsMenu cms缓存key
+	CacheSysCmsMenu = "sysCmsMenu"
+
+	// CacheSysAuthTag 权限缓存TAG标签
+	CacheSysAuthTag = "sysAuthTag"
+	// CacheSysModelTag 模型缓存标签
+	CacheSysModelTag = "sysModelTag"
+	// CacheSysCmsTag cms缓存标签
+	CacheSysCmsTag = "sysCmsTag"
+)

+ 5 - 0
internal/app/system/consts/consts.go

@@ -0,0 +1,5 @@
+package consts
+
+const (
+	PageSize = 10 //分页长度
+)

+ 13 - 0
internal/app/system/consts/context.go

@@ -0,0 +1,13 @@
+/*
+* @desc:context 相关常量
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/16 14:52
+ */
+
+package consts
+
+const (
+	// CtxKey 上下文变量存储键名,前后端系统共享
+	CtxKey = "GFastContext"
+)

+ 22 - 0
internal/app/system/controller/base.go

@@ -0,0 +1,22 @@
+/*
+* @desc:system base controller
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/4 18:12
+ */
+
+package controller
+
+import (
+	"github.com/gogf/gf/v2/net/ghttp"
+	commonController "github.com/tiger1103/gfast/v3/internal/app/common/controller"
+)
+
+type BaseController struct {
+	commonController.BaseController
+}
+
+// Init 自动执行的初始化方法
+func (c *BaseController) Init(r *ghttp.Request) {
+	c.BaseController.Init(r)
+}

+ 34 - 0
internal/app/system/controller/personal.go

@@ -0,0 +1,34 @@
+/*
+* @desc:xxxx功能描述
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/11/3 10:32
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var Personal = new(personalController)
+
+type personalController struct {
+}
+
+func (c *personalController) GetPersonal(ctx context.Context, req *system.PersonalInfoReq) (res *system.PersonalInfoRes, err error) {
+	res, err = service.Personal().GetPersonalInfo(ctx, req)
+	return
+}
+
+func (c *personalController) EditPersonal(ctx context.Context, req *system.PersonalEditReq) (res *system.PersonalEditRes, err error) {
+	res, err = service.Personal().EditPersonal(ctx, req)
+	return
+}
+
+func (c *personalController) ResetPwdPersonal(ctx context.Context, req *system.PersonalResetPwdReq) (res *system.PersonalResetPwdRes, err error) {
+	res, err = service.Personal().ResetPwdPersonal(ctx, req)
+	return
+}

+ 79 - 0
internal/app/system/controller/sys_auth_rule.go

@@ -0,0 +1,79 @@
+/*
+* @desc:菜单
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/3/16 10:36
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var Menu = menuController{}
+
+type menuController struct {
+	BaseController
+}
+
+func (c *menuController) List(ctx context.Context, req *system.RuleSearchReq) (res *system.RuleListRes, err error) {
+	var list []*model.SysAuthRuleInfoRes
+	res = &system.RuleListRes{
+		Rules: make([]*model.SysAuthRuleTreeRes, 0),
+	}
+	list, err = service.SysAuthRule().GetMenuListSearch(ctx, req)
+	if req.Title != "" || req.Component != "" {
+		for _, menu := range list {
+			res.Rules = append(res.Rules, &model.SysAuthRuleTreeRes{
+				SysAuthRuleInfoRes: menu,
+			})
+		}
+	} else {
+		res.Rules = service.SysAuthRule().GetMenuListTree(0, list)
+	}
+	return
+}
+
+func (c *menuController) Add(ctx context.Context, req *system.RuleAddReq) (res *system.RuleAddRes, err error) {
+	err = service.SysAuthRule().Add(ctx, req)
+	return
+}
+
+// GetAddParams 获取菜单添加及编辑相关参数
+func (c *menuController) GetAddParams(ctx context.Context, req *system.RuleGetParamsReq) (res *system.RuleGetParamsRes, err error) {
+	// 获取角色列表
+	res = new(system.RuleGetParamsRes)
+	res.Roles, err = service.SysRole().GetRoleList(ctx)
+	if err != nil {
+		return
+	}
+	res.Menus, err = service.SysAuthRule().GetIsMenuList(ctx)
+	return
+}
+
+// Get 获取菜单信息
+func (c *menuController) Get(ctx context.Context, req *system.RuleInfoReq) (res *system.RuleInfoRes, err error) {
+	res = new(system.RuleInfoRes)
+	res.Rule, err = service.SysAuthRule().Get(ctx, req.Id)
+	if err != nil {
+		return
+	}
+	res.RoleIds, err = service.SysAuthRule().GetMenuRoles(ctx, req.Id)
+	return
+}
+
+// Update 菜单修改
+func (c *menuController) Update(ctx context.Context, req *system.RuleUpdateReq) (res *system.RuleUpdateRes, err error) {
+	err = service.SysAuthRule().Update(ctx, req)
+	return
+}
+
+// Delete 删除菜单
+func (c *menuController) Delete(ctx context.Context, req *system.RuleDeleteReq) (res *system.RuleDeleteRes, err error) {
+	err = service.SysAuthRule().DeleteMenuByIds(ctx, req.Ids)
+	return
+}

+ 51 - 0
internal/app/system/controller/sys_config.go

@@ -0,0 +1,51 @@
+/*
+* @desc:系统参数配置
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/18 21:17
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	commonService "github.com/tiger1103/gfast/v3/internal/app/common/service"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var Config = configController{}
+
+type configController struct {
+	BaseController
+}
+
+// List 系统参数列表
+func (c *configController) List(ctx context.Context, req *system.ConfigSearchReq) (res *system.ConfigSearchRes, err error) {
+	res, err = commonService.SysConfig().List(ctx, req)
+	return
+}
+
+// Add 添加系统参数
+func (c *configController) Add(ctx context.Context, req *system.ConfigAddReq) (res *system.ConfigAddRes, err error) {
+	err = commonService.SysConfig().Add(ctx, req, service.Context().GetUserId(ctx))
+	return
+}
+
+// Get 获取系统参数
+func (c *configController) Get(ctx context.Context, req *system.ConfigGetReq) (res *system.ConfigGetRes, err error) {
+	res, err = commonService.SysConfig().Get(ctx, req.Id)
+	return
+}
+
+// Edit 修改系统参数
+func (c *configController) Edit(ctx context.Context, req *system.ConfigEditReq) (res *system.ConfigEditRes, err error) {
+	err = commonService.SysConfig().Edit(ctx, req, service.Context().GetUserId(ctx))
+	return
+}
+
+// Delete 删除系统参数
+func (c *configController) Delete(ctx context.Context, req *system.ConfigDeleteReq) (res *system.ConfigDeleteRes, err error) {
+	err = commonService.SysConfig().Delete(ctx, req.Ids)
+	return
+}

+ 60 - 0
internal/app/system/controller/sys_dept.go

@@ -0,0 +1,60 @@
+/*
+* @desc:部门管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/4/6 15:15
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var Dept = sysDeptController{}
+
+type sysDeptController struct {
+	BaseController
+}
+
+// List 部门列表
+func (c *sysDeptController) List(ctx context.Context, req *system.DeptSearchReq) (res *system.DeptSearchRes, err error) {
+	res = new(system.DeptSearchRes)
+	res.DeptList, err = service.SysDept().GetList(ctx, req)
+	return
+}
+
+// Add 添加部门
+func (c *sysDeptController) Add(ctx context.Context, req *system.DeptAddReq) (res *system.DeptAddRes, err error) {
+	err = service.SysDept().Add(ctx, req)
+	return
+}
+
+// Edit 修改部门
+func (c *sysDeptController) Edit(ctx context.Context, req *system.DeptEditReq) (res *system.DeptEditRes, err error) {
+	err = service.SysDept().Edit(ctx, req)
+	return
+}
+
+// Delete 删除部门
+func (c *sysDeptController) Delete(ctx context.Context, req *system.DeptDeleteReq) (res *system.DeptDeleteRes, err error) {
+	err = service.SysDept().Delete(ctx, req.Id)
+	return
+}
+
+// TreeSelect 获取部门数据结构数据
+func (c *sysDeptController) TreeSelect(ctx context.Context, req *system.DeptTreeSelectReq) (res *system.DeptTreeSelectRes, err error) {
+	var deptList []*entity.SysDept
+	deptList, err = service.SysDept().GetList(ctx, &system.DeptSearchReq{
+		Status: "1", //正常状态数据
+	})
+	if err != nil {
+		return
+	}
+	res = new(system.DeptTreeSelectRes)
+	res.Deps = service.SysDept().GetListTree(0, deptList)
+	return
+}

+ 55 - 0
internal/app/system/controller/sys_dict_data.go

@@ -0,0 +1,55 @@
+/*
+* @desc:字典数据管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/18 11:57
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	commonService "github.com/tiger1103/gfast/v3/internal/app/common/service"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var DictData = dictDataController{}
+
+type dictDataController struct {
+}
+
+// GetDictData 获取字典数据
+func (c *dictDataController) GetDictData(ctx context.Context, req *system.GetDictReq) (res *system.GetDictRes, err error) {
+	res, err = commonService.SysDictData().GetDictWithDataByType(ctx, req)
+	return
+}
+
+// List 获取字典数据列表
+func (c *dictDataController) List(ctx context.Context, req *system.DictDataSearchReq) (res *system.DictDataSearchRes, err error) {
+	res, err = commonService.SysDictData().List(ctx, req)
+	return
+}
+
+// Add 添加字典数据
+func (c *dictDataController) Add(ctx context.Context, req *system.DictDataAddReq) (res *system.DictDataAddRes, err error) {
+	err = commonService.SysDictData().Add(ctx, req, service.Context().GetUserId(ctx))
+	return
+}
+
+// Get 获取对应的字典数据
+func (c *dictDataController) Get(ctx context.Context, req *system.DictDataGetReq) (res *system.DictDataGetRes, err error) {
+	res, err = commonService.SysDictData().Get(ctx, req.DictCode)
+	return
+}
+
+// Edit 修改字典数据
+func (c *dictDataController) Edit(ctx context.Context, req *system.DictDataEditReq) (res *system.DictDataEditRes, err error) {
+	err = commonService.SysDictData().Edit(ctx, req, service.Context().GetUserId(ctx))
+	return
+}
+
+func (c *dictDataController) Delete(ctx context.Context, req *system.DictDataDeleteReq) (res *system.DictDataDeleteRes, err error) {
+	err = commonService.SysDictData().Delete(ctx, req.Ids)
+	return
+}

+ 57 - 0
internal/app/system/controller/sys_dict_type.go

@@ -0,0 +1,57 @@
+/*
+* @desc:字典类型
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/18 11:57
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	commonService "github.com/tiger1103/gfast/v3/internal/app/common/service"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var DictType = &SysDictTypeController{}
+
+type SysDictTypeController struct {
+}
+
+// List 字典类型列表
+func (c *SysDictTypeController) List(ctx context.Context, req *system.DictTypeSearchReq) (res *system.DictTypeSearchRes, err error) {
+	res, err = commonService.SysDictType().List(ctx, req)
+	return
+}
+
+// Add 添加字典类型
+func (c *SysDictTypeController) Add(ctx context.Context, req *system.DictTypeAddReq) (res *system.DictTypeAddRes, err error) {
+	err = commonService.SysDictType().Add(ctx, req, service.Context().GetUserId(ctx))
+	return
+}
+
+// Get 获取字典类型
+func (c *SysDictTypeController) Get(ctx context.Context, req *system.DictTypeGetReq) (res *system.DictTypeGetRes, err error) {
+	res = new(system.DictTypeGetRes)
+	res.DictType, err = commonService.SysDictType().Get(ctx, req)
+	return
+}
+
+// Edit 修改字典数据
+func (c *SysDictTypeController) Edit(ctx context.Context, req *system.DictTypeEditReq) (res *system.DictTypeEditRes, err error) {
+	err = commonService.SysDictType().Edit(ctx, req, service.Context().GetUserId(ctx))
+	return
+}
+
+func (c *SysDictTypeController) Delete(ctx context.Context, req *system.DictTypeDeleteReq) (res *system.DictTypeDeleteRes, err error) {
+	err = commonService.SysDictType().Delete(ctx, req.DictIds)
+	return
+}
+
+// OptionSelect 获取字典选择框列表
+func (c *SysDictTypeController) OptionSelect(ctx context.Context, req *system.DictTypeAllReq) (res *system.DictTYpeAllRes, err error) {
+	res = new(system.DictTYpeAllRes)
+	res.DictType, err = commonService.SysDictType().GetAllDictType(ctx)
+	return
+}

+ 112 - 0
internal/app/system/controller/sys_login.go

@@ -0,0 +1,112 @@
+/*
+* @desc:登录
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/27 21:52
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/crypto/gmd5"
+	"github.com/gogf/gf/v2/errors/gerror"
+	"github.com/gogf/gf/v2/frame/g"
+	"github.com/gogf/gf/v2/util/gconv"
+	"github.com/gogf/gf/v2/util/gmode"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	commonService "github.com/tiger1103/gfast/v3/internal/app/common/service"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+	"github.com/tiger1103/gfast/v3/library/libUtils"
+)
+
+var (
+	Login = loginController{}
+)
+
+type loginController struct {
+	BaseController
+}
+
+func (c *loginController) Login(ctx context.Context, req *system.UserLoginReq) (res *system.UserLoginRes, err error) {
+	var (
+		user        *model.LoginUserRes
+		token       string
+		permissions []string
+		menuList    []*model.UserMenus
+	)
+	//判断验证码是否正确
+	debug := gmode.IsDevelop()
+	if !debug {
+		if !commonService.Captcha().VerifyString(req.VerifyKey, req.VerifyCode) {
+			err = gerror.New("验证码输入错误")
+			return
+		}
+	}
+	ip := libUtils.GetClientIp(ctx)
+	userAgent := libUtils.GetUserAgent(ctx)
+	user, err = service.SysUser().GetAdminUserByUsernamePassword(ctx, req)
+	if err != nil {
+		// 保存登录失败的日志信息
+		service.SysLoginLog().Invoke(ctx, &model.LoginLogParams{
+			Status:    0,
+			Username:  req.Username,
+			Ip:        ip,
+			UserAgent: userAgent,
+			Msg:       err.Error(),
+			Module:    "系统后台",
+		})
+		return
+	}
+	err = service.SysUser().UpdateLoginInfo(ctx, user.Id, ip)
+	if err != nil {
+		return
+	}
+	// 报存登录成功的日志信息
+	service.SysLoginLog().Invoke(ctx, &model.LoginLogParams{
+		Status:    1,
+		Username:  req.Username,
+		Ip:        ip,
+		UserAgent: userAgent,
+		Msg:       "登录成功",
+		Module:    "系统后台",
+	})
+	key := gconv.String(user.Id) + "-" + gmd5.MustEncryptString(user.UserName) + gmd5.MustEncryptString(user.UserPassword)
+	if g.Cfg().MustGet(ctx, "gfToken.multiLogin").Bool() {
+		key = gconv.String(user.Id) + "-" + gmd5.MustEncryptString(user.UserName) + gmd5.MustEncryptString(user.UserPassword+ip+userAgent)
+	}
+	user.UserPassword = ""
+	token, err = service.GfToken().GenerateToken(ctx, key, user)
+	if err != nil {
+		g.Log().Error(ctx, err)
+		err = gerror.New("登录失败,后端服务出现错误")
+		return
+	}
+	//获取用户菜单数据
+	menuList, permissions, err = service.SysUser().GetAdminRules(ctx, user.Id)
+	if err != nil {
+		return
+	}
+	res = &system.UserLoginRes{
+		UserInfo:    user,
+		Token:       token,
+		MenuList:    menuList,
+		Permissions: permissions,
+	}
+	//用户在线状态保存
+	service.SysUserOnline().Invoke(ctx, &model.SysUserOnlineParams{
+		UserAgent: userAgent,
+		Uuid:      gmd5.MustEncrypt(token),
+		Token:     token,
+		Username:  user.UserName,
+		Ip:        ip,
+	})
+	return
+}
+
+// LoginOut 退出登录
+func (c *loginController) LoginOut(ctx context.Context, req *system.UserLoginOutReq) (res *system.UserLoginOutRes, err error) {
+	err = service.GfToken().RemoveToken(ctx, service.GfToken().GetRequestToken(g.RequestFromCtx(ctx)))
+	return
+}

+ 35 - 0
internal/app/system/controller/sys_login_log.go

@@ -0,0 +1,35 @@
+/*
+* @desc:登录日志管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/24 22:14
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var LoginLog = loginLogController{}
+
+type loginLogController struct {
+	BaseController
+}
+
+func (c *loginLogController) List(ctx context.Context, req *system.LoginLogSearchReq) (res *system.LoginLogSearchRes, err error) {
+	res, err = service.SysLoginLog().List(ctx, req)
+	return
+}
+
+func (c *loginLogController) Delete(ctx context.Context, req *system.LoginLogDelReq) (res *system.LoginLogDelRes, err error) {
+	err = service.SysLoginLog().DeleteLoginLogByIds(ctx, req.Ids)
+	return
+}
+
+func (c *loginLogController) Clear(ctx context.Context, req *system.LoginLogClearReq) (res *system.LoginLogClearRes, err error) {
+	err = service.SysLoginLog().ClearLoginLog(ctx)
+	return
+}

+ 142 - 0
internal/app/system/controller/sys_monitor.go

@@ -0,0 +1,142 @@
+package controller
+
+import (
+	"context"
+	"fmt"
+	"github.com/gogf/gf/v2/os/gtime"
+	"github.com/gogf/gf/v2/util/gconv"
+	"github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/disk"
+	"github.com/shirou/gopsutil/host"
+	"github.com/shirou/gopsutil/load"
+	"github.com/shirou/gopsutil/mem"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/library/libUtils"
+	"os"
+	"runtime"
+	"strconv"
+	"time"
+)
+
+var Monitor = sysMonitorController{
+	startTime: gtime.Now(),
+}
+
+type sysMonitorController struct {
+	BaseController
+	startTime *gtime.Time
+}
+
+func (c *sysMonitorController) List(ctx context.Context, req *system.MonitorSearchReq) (res *system.MonitorSearchRes, err error) {
+	cpuNum := runtime.NumCPU() //核心数
+	var cpuUsed float64 = 0    //用户使用率
+	var cpuAvg5 float64 = 0    //CPU负载5
+	var cpuAvg15 float64 = 0   //当前空闲率
+
+	cpuInfo, err := cpu.Percent(time.Duration(time.Second), false)
+	if err == nil {
+		cpuUsed, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", cpuInfo[0]), 64)
+	}
+
+	loadInfo, err := load.Avg()
+	if err == nil {
+		cpuAvg5, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", loadInfo.Load5), 64)
+		cpuAvg15, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", loadInfo.Load5), 64)
+	}
+
+	var memTotal uint64 = 0  //总内存
+	var memUsed uint64 = 0   //总内存  := 0 //已用内存
+	var memFree uint64 = 0   //剩余内存
+	var memUsage float64 = 0 //使用率
+
+	v, err := mem.VirtualMemory()
+	if err == nil {
+		memTotal = v.Total
+		memUsed = v.Used
+		memFree = memTotal - memUsed
+		memUsage, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", v.UsedPercent), 64)
+	}
+
+	var goTotal uint64 = 0  //go分配的总内存数
+	var goUsed uint64 = 0   //go使用的内存数
+	var goFree uint64 = 0   //go剩余的内存数
+	var goUsage float64 = 0 //使用率
+
+	var gomem runtime.MemStats
+	runtime.ReadMemStats(&gomem)
+	goUsed = gomem.Sys
+	goUsage = gconv.Float64(fmt.Sprintf("%.2f", gconv.Float64(goUsed)/gconv.Float64(memTotal)*100))
+	sysComputerIp := "" //服务器IP
+
+	ip, err := libUtils.GetLocalIP()
+	if err == nil {
+		sysComputerIp = ip
+	}
+
+	sysComputerName := "" //服务器名称
+	sysOsName := ""       //操作系统
+	sysOsArch := ""       //系统架构
+
+	sysInfo, err := host.Info()
+
+	if err == nil {
+		sysComputerName = sysInfo.Hostname
+		sysOsName = sysInfo.OS
+		sysOsArch = sysInfo.KernelArch
+	}
+
+	goName := "GoLang"             //语言环境
+	goVersion := runtime.Version() //版本
+	gtime.Date()
+	goStartTime := c.startTime //启动时间
+
+	goRunTime := gtime.Now().Timestamp() - c.startTime.Timestamp() //运行时长(秒)
+	goHome := runtime.GOROOT()                                     //安装路径
+	goUserDir := ""                                                //项目路径
+
+	curDir, err := os.Getwd()
+
+	if err == nil {
+		goUserDir = curDir
+	}
+
+	//服务器磁盘信息
+	diskList := make([]disk.UsageStat, 0)
+	diskInfo, err := disk.Partitions(true) //所有分区
+	if err == nil {
+		for _, p := range diskInfo {
+			diskDetail, err := disk.Usage(p.Mountpoint)
+			if err == nil {
+				diskDetail.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", diskDetail.UsedPercent), 64)
+				diskList = append(diskList, *diskDetail)
+			}
+		}
+	}
+	res = new(system.MonitorSearchRes)
+	res = &system.MonitorSearchRes{
+		"cpuNum":          cpuNum,
+		"cpuUsed":         cpuUsed,
+		"cpuAvg5":         gconv.String(cpuAvg5),
+		"cpuAvg15":        gconv.String(cpuAvg15),
+		"memTotal":        memTotal,
+		"goTotal":         goTotal,
+		"memUsed":         memUsed,
+		"goUsed":          goUsed,
+		"memFree":         memFree,
+		"goFree":          goFree,
+		"memUsage":        memUsage,
+		"goUsage":         goUsage,
+		"sysComputerName": sysComputerName,
+		"sysOsName":       sysOsName,
+		"sysComputerIp":   sysComputerIp,
+		"sysOsArch":       sysOsArch,
+		"goName":          goName,
+		"goVersion":       goVersion,
+		"goStartTime":     goStartTime,
+		"goRunTime":       goRunTime,
+		"goHome":          goHome,
+		"goUserDir":       goUserDir,
+		"diskList":        diskList,
+	}
+	return
+}

+ 43 - 0
internal/app/system/controller/sys_oper_log.go

@@ -0,0 +1,43 @@
+/*
+* @desc:系统后台操作日志
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/9/21 16:10
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var OperLog = new(operateLogController)
+
+type operateLogController struct {
+	BaseController
+}
+
+// List 列表
+func (c *operateLogController) List(ctx context.Context, req *system.SysOperLogSearchReq) (res *system.SysOperLogSearchRes, err error) {
+	res, err = service.OperateLog().List(ctx, req)
+	return
+}
+
+// Get 获取操作日志
+func (c *operateLogController) Get(ctx context.Context, req *system.SysOperLogGetReq) (res *system.SysOperLogGetRes, err error) {
+	res = new(system.SysOperLogGetRes)
+	res.SysOperLogInfoRes, err = service.OperateLog().GetByOperId(ctx, req.OperId)
+	return
+}
+
+func (c *operateLogController) Delete(ctx context.Context, req *system.SysOperLogDeleteReq) (res *system.SysOperLogDeleteRes, err error) {
+	err = service.OperateLog().DeleteByIds(ctx, req.OperIds)
+	return
+}
+
+func (c *operateLogController) Clear(ctx context.Context, req *system.SysOperLogClearReq) (res *system.SysOperLogClearRes, err error) {
+	err = service.OperateLog().ClearLog(ctx)
+	return
+}

+ 44 - 0
internal/app/system/controller/sys_post.go

@@ -0,0 +1,44 @@
+/*
+* @desc:岗位管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2022/4/7 23:12
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var Post = postController{}
+
+type postController struct {
+	BaseController
+}
+
+// List 岗位列表
+func (c *postController) List(ctx context.Context, req *system.PostSearchReq) (res *system.PostSearchRes, err error) {
+	res, err = service.SysPost().List(ctx, req)
+	return
+}
+
+// Add 添加岗位
+func (c *postController) Add(ctx context.Context, req *system.PostAddReq) (res *system.PostAddRes, err error) {
+	err = service.SysPost().Add(ctx, req)
+	return
+}
+
+// Edit 修改岗位
+func (c *postController) Edit(ctx context.Context, req *system.PostEditReq) (res *system.PostEditRes, err error) {
+	err = service.SysPost().Edit(ctx, req)
+	return
+}
+
+// Delete 删除岗位
+func (c *postController) Delete(ctx context.Context, req *system.PostDeleteReq) (res *system.PostDeleteRes, err error) {
+	err = service.SysPost().Delete(ctx, req.Ids)
+	return
+}

+ 62 - 0
internal/app/system/controller/sys_role.go

@@ -0,0 +1,62 @@
+/*
+* @desc:角色管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2022/3/30 9:08
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var Role = roleController{}
+
+type roleController struct {
+	BaseController
+}
+
+// List 角色列表
+func (c *roleController) List(ctx context.Context, req *system.RoleListReq) (res *system.RoleListRes, err error) {
+	res, err = service.SysRole().GetRoleListSearch(ctx, req)
+	return
+}
+
+// GetParams 获取角色表单参数
+func (c *roleController) GetParams(ctx context.Context, req *system.RoleGetParamsReq) (res *system.RoleGetParamsRes, err error) {
+	res = new(system.RoleGetParamsRes)
+	res.Menu, err = service.SysAuthRule().GetMenuList(ctx)
+	return
+}
+
+// Add 添加角色信息
+func (c *roleController) Add(ctx context.Context, req *system.RoleAddReq) (res *system.RoleAddRes, err error) {
+	err = service.SysRole().AddRole(ctx, req)
+	return
+}
+
+// Get 获取角色信息
+func (c *roleController) Get(ctx context.Context, req *system.RoleGetReq) (res *system.RoleGetRes, err error) {
+	res = new(system.RoleGetRes)
+	res.Role, err = service.SysRole().Get(ctx, req.Id)
+	if err != nil {
+		return
+	}
+	res.MenuIds, err = service.SysRole().GetFilteredNamedPolicy(ctx, req.Id)
+	return
+}
+
+// Edit 修改角色信息
+func (c *roleController) Edit(ctx context.Context, req *system.RoleEditReq) (res *system.RoleEditRes, err error) {
+	err = service.SysRole().EditRole(ctx, req)
+	return
+}
+
+// Delete 删除角色
+func (c *roleController) Delete(ctx context.Context, req *system.RoleDeleteReq) (res *system.RoleDeleteRes, err error) {
+	err = service.SysRole().DeleteByIds(ctx, req.Ids)
+	return
+}

+ 102 - 0
internal/app/system/controller/sys_user.go

@@ -0,0 +1,102 @@
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model"
+	"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var (
+	User = userController{}
+)
+
+type userController struct {
+	BaseController
+}
+
+// GetUserMenus 获取用户菜单及按钮权限
+func (c *userController) GetUserMenus(ctx context.Context, req *system.UserMenusReq) (res *system.UserMenusRes, err error) {
+	var (
+		permissions []string
+		menuList    []*model.UserMenus
+	)
+	userId := service.Context().GetUserId(ctx)
+	menuList, permissions, err = service.SysUser().GetAdminRules(ctx, userId)
+	res = &system.UserMenusRes{
+		MenuList:    menuList,
+		Permissions: permissions,
+	}
+	return
+}
+
+// List 用户列表
+func (c *userController) List(ctx context.Context, req *system.UserSearchReq) (res *system.UserSearchRes, err error) {
+	var (
+		total    interface{}
+		userList []*entity.SysUser
+	)
+	res = new(system.UserSearchRes)
+	total, userList, err = service.SysUser().List(ctx, req)
+	if err != nil || total == 0 {
+		return
+	}
+	res.Total = total
+	res.UserList, err = service.SysUser().GetUsersRoleDept(ctx, userList)
+	return
+}
+
+// GetParams 获取用户维护相关参数
+func (c *userController) GetParams(ctx context.Context, req *system.UserGetParamsReq) (res *system.UserGetParamsRes, err error) {
+	res = new(system.UserGetParamsRes)
+	res.RoleList, err = service.SysRole().GetRoleList(ctx)
+	if err != nil {
+		return
+	}
+	res.Posts, err = service.SysPost().GetUsedPost(ctx)
+	return
+}
+
+// Add 添加用户
+func (c *userController) Add(ctx context.Context, req *system.UserAddReq) (res *system.UserAddRes, err error) {
+	err = service.SysUser().Add(ctx, req)
+	return
+}
+
+// GetEditUser 获取修改用户信息
+func (c *userController) GetEditUser(ctx context.Context, req *system.UserGetEditReq) (res *system.UserGetEditRes, err error) {
+	res, err = service.SysUser().GetEditUser(ctx, req.Id)
+	return
+}
+
+// Edit 修改用户
+func (c *userController) Edit(ctx context.Context, req *system.UserEditReq) (res *system.UserEditRes, err error) {
+	err = service.SysUser().Edit(ctx, req)
+	return
+}
+
+// ResetPwd 重置密码
+func (c *userController) ResetPwd(ctx context.Context, req *system.UserResetPwdReq) (res *system.UserResetPwdRes, err error) {
+	err = service.SysUser().ResetUserPwd(ctx, req)
+	return
+}
+
+// SetStatus 修改用户状态
+func (c *userController) SetStatus(ctx context.Context, req *system.UserStatusReq) (res *system.UserStatusRes, err error) {
+	err = service.SysUser().ChangeUserStatus(ctx, req)
+	return
+}
+
+// Delete 删除用户
+func (c *userController) Delete(ctx context.Context, req *system.UserDeleteReq) (res *system.UserDeleteRes, err error) {
+	err = service.SysUser().Delete(ctx, req.Ids)
+	return
+}
+
+// GetUsers 通过用户id批量获取用户信息
+func (c *userController) GetUsers(ctx context.Context, req *system.UserGetByIdsReq) (res *system.UserGetByIdsRes, err error) {
+	res = new(system.UserGetByIdsRes)
+	res.List, err = service.SysUser().GetUsers(ctx, req.Ids)
+	return
+}

+ 28 - 0
internal/app/system/controller/sys_user_online.go

@@ -0,0 +1,28 @@
+/*
+* @desc:在线用户管理
+* @company:云南奇讯科技有限公司
+* @Author: yixiaohu<yxh669@qq.com>
+* @Date:   2023/1/10 17:23
+ */
+
+package controller
+
+import (
+	"context"
+	"github.com/tiger1103/gfast/v3/api/v1/system"
+	"github.com/tiger1103/gfast/v3/internal/app/system/service"
+)
+
+var UserOnline = new(SysUserOnlineController)
+
+type SysUserOnlineController struct{}
+
+func (c *SysUserOnlineController) List(ctx context.Context, req *system.SysUserOnlineSearchReq) (res *system.SysUserOnlineSearchRes, err error) {
+	res, err = service.SysUserOnline().GetOnlineListPage(ctx, req)
+	return
+}
+
+func (c *SysUserOnlineController) ForceLogout(ctx context.Context, req *system.SysUserOnlineForceLogoutReq) (res *system.SysUserOnlineForceLogoutRes, err error) {
+	err = service.SysUserOnline().ForceLogout(ctx, req.Ids)
+	return
+}

+ 114 - 0
internal/app/system/dao/internal/sys_auth_rule.go

@@ -0,0 +1,114 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysAuthRuleDao is the data access object for table sys_auth_rule.
+type SysAuthRuleDao struct {
+	table   string             // table is the underlying table name of the DAO.
+	group   string             // group is the database configuration group name of current DAO.
+	columns SysAuthRuleColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysAuthRuleColumns defines and stores column names for table sys_auth_rule.
+type SysAuthRuleColumns struct {
+	Id         string //
+	Pid        string // 父ID
+	Name       string // 规则名称
+	Title      string // 规则名称
+	Icon       string // 图标
+	Condition  string // 条件
+	Remark     string // 备注
+	MenuType   string // 类型 0目录 1菜单 2按钮
+	Weigh      string // 权重
+	IsHide     string // 显示状态
+	Path       string // 路由地址
+	Component  string // 组件路径
+	IsLink     string // 是否外链 1是 0否
+	ModuleType string // 所属模块
+	ModelId    string // 模型ID
+	IsIframe   string // 是否内嵌iframe
+	IsCached   string // 是否缓存
+	Redirect   string // 路由重定向地址
+	IsAffix    string // 是否固定
+	LinkUrl    string // 链接地址
+	CreatedAt  string // 创建日期
+	UpdatedAt  string // 修改日期
+}
+
+// sysAuthRuleColumns holds the columns for table sys_auth_rule.
+var sysAuthRuleColumns = SysAuthRuleColumns{
+	Id:         "id",
+	Pid:        "pid",
+	Name:       "name",
+	Title:      "title",
+	Icon:       "icon",
+	Condition:  "condition",
+	Remark:     "remark",
+	MenuType:   "menu_type",
+	Weigh:      "weigh",
+	IsHide:     "is_hide",
+	Path:       "path",
+	Component:  "component",
+	IsLink:     "is_link",
+	ModuleType: "module_type",
+	ModelId:    "model_id",
+	IsIframe:   "is_iframe",
+	IsCached:   "is_cached",
+	Redirect:   "redirect",
+	IsAffix:    "is_affix",
+	LinkUrl:    "link_url",
+	CreatedAt:  "created_at",
+	UpdatedAt:  "updated_at",
+}
+
+// NewSysAuthRuleDao creates and returns a new DAO object for table data access.
+func NewSysAuthRuleDao() *SysAuthRuleDao {
+	return &SysAuthRuleDao{
+		group:   "default",
+		table:   "sys_auth_rule",
+		columns: sysAuthRuleColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysAuthRuleDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysAuthRuleDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysAuthRuleDao) Columns() SysAuthRuleColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysAuthRuleDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysAuthRuleDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysAuthRuleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 98 - 0
internal/app/system/dao/internal/sys_dept.go

@@ -0,0 +1,98 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysDeptDao is the data access object for table sys_dept.
+type SysDeptDao struct {
+	table   string         // table is the underlying table name of the DAO.
+	group   string         // group is the database configuration group name of current DAO.
+	columns SysDeptColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysDeptColumns defines and stores column names for table sys_dept.
+type SysDeptColumns struct {
+	DeptId    string // 部门id
+	ParentId  string // 父部门id
+	Ancestors string // 祖级列表
+	DeptName  string // 部门名称
+	OrderNum  string // 显示顺序
+	Leader    string // 负责人
+	Phone     string // 联系电话
+	Email     string // 邮箱
+	Status    string // 部门状态(0正常 1停用)
+	CreatedBy string // 创建人
+	UpdatedBy string // 修改人
+	CreatedAt string // 创建时间
+	UpdatedAt string // 修改时间
+	DeletedAt string // 删除时间
+}
+
+// sysDeptColumns holds the columns for table sys_dept.
+var sysDeptColumns = SysDeptColumns{
+	DeptId:    "dept_id",
+	ParentId:  "parent_id",
+	Ancestors: "ancestors",
+	DeptName:  "dept_name",
+	OrderNum:  "order_num",
+	Leader:    "leader",
+	Phone:     "phone",
+	Email:     "email",
+	Status:    "status",
+	CreatedBy: "created_by",
+	UpdatedBy: "updated_by",
+	CreatedAt: "created_at",
+	UpdatedAt: "updated_at",
+	DeletedAt: "deleted_at",
+}
+
+// NewSysDeptDao creates and returns a new DAO object for table data access.
+func NewSysDeptDao() *SysDeptDao {
+	return &SysDeptDao{
+		group:   "default",
+		table:   "sys_dept",
+		columns: sysDeptColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysDeptDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysDeptDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysDeptDao) Columns() SysDeptColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysDeptDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysDeptDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 102 - 0
internal/app/system/dao/internal/sys_job.go

@@ -0,0 +1,102 @@
+// ==========================================================================
+// GFast自动生成dao internal操作代码。
+// 生成日期:2023-01-12 17:43:50
+// 生成路径: internal/app/system/dao/internal/sys_job.go
+// 生成人:gfast
+// desc:定时任务
+// company:云南奇讯科技有限公司
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysJobDao is the manager for logic model data accessing and custom defined data operations functions management.
+type SysJobDao struct {
+	table   string        // Table is the underlying table name of the DAO.
+	group   string        // Group is the database configuration group name of current DAO.
+	columns SysJobColumns // Columns is the short type for Columns, which contains all the column names of Table for convenient usage.
+}
+
+// SysJobColumns defines and stores column names for table sys_job.
+type SysJobColumns struct {
+	JobId          string // 任务ID
+	JobName        string // 任务名称
+	JobParams      string // 参数
+	JobGroup       string // 任务组名
+	InvokeTarget   string // 任务方法
+	CronExpression string // cron执行表达式
+	MisfirePolicy  string // 计划执行策略
+	Concurrent     string // 是否并发执行
+	Status         string // 状态
+	CreatedBy      string // 创建者
+	UpdatedBy      string // 更新者
+	Remark         string // 备注信息
+	CreatedAt      string // 创建时间
+	UpdatedAt      string // 更新时间
+}
+
+var sysJobColumns = SysJobColumns{
+	JobId:          "job_id",
+	JobName:        "job_name",
+	JobParams:      "job_params",
+	JobGroup:       "job_group",
+	InvokeTarget:   "invoke_target",
+	CronExpression: "cron_expression",
+	MisfirePolicy:  "misfire_policy",
+	Concurrent:     "concurrent",
+	Status:         "status",
+	CreatedBy:      "created_by",
+	UpdatedBy:      "updated_by",
+	Remark:         "remark",
+	CreatedAt:      "created_at",
+	UpdatedAt:      "updated_at",
+}
+
+// NewSysJobDao creates and returns a new DAO object for table data access.
+func NewSysJobDao() *SysJobDao {
+	return &SysJobDao{
+		group:   "default",
+		table:   "sys_job",
+		columns: sysJobColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysJobDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysJobDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysJobDao) Columns() SysJobColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysJobDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysJobDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysJobDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 79 - 0
internal/app/system/dao/internal/sys_job_log.go

@@ -0,0 +1,79 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysJobLogDao is the data access object for table sys_job_log.
+type SysJobLogDao struct {
+	table   string           // table is the underlying table name of the DAO.
+	group   string           // group is the database configuration group name of current DAO.
+	columns SysJobLogColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysJobLogColumns defines and stores column names for table sys_job_log.
+type SysJobLogColumns struct {
+	Id         string // 主键
+	TargetName string // 方法名
+	CreatedAt  string // 执行日期
+	Result     string // 执行结果
+}
+
+// sysJobLogColumns holds the columns for table sys_job_log.
+var sysJobLogColumns = SysJobLogColumns{
+	Id:         "id",
+	TargetName: "target_name",
+	CreatedAt:  "created_at",
+	Result:     "result",
+}
+
+// NewSysJobLogDao creates and returns a new DAO object for table data access.
+func NewSysJobLogDao() *SysJobLogDao {
+	return &SysJobLogDao{
+		group:   "default",
+		table:   "sys_job_log",
+		columns: sysJobLogColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysJobLogDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysJobLogDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysJobLogDao) Columns() SysJobLogColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysJobLogDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysJobLogDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysJobLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 90 - 0
internal/app/system/dao/internal/sys_login_log.go

@@ -0,0 +1,90 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-03-08 11:31:48
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysLoginLogDao is the data access object for table sys_login_log.
+type SysLoginLogDao struct {
+	table   string             // table is the underlying table name of the DAO.
+	group   string             // group is the database configuration group name of current DAO.
+	columns SysLoginLogColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysLoginLogColumns defines and stores column names for table sys_login_log.
+type SysLoginLogColumns struct {
+	InfoId        string // 访问ID
+	LoginName     string // 登录账号
+	Ipaddr        string // 登录IP地址
+	LoginLocation string // 登录地点
+	Browser       string // 浏览器类型
+	Os            string // 操作系统
+	Status        string // 登录状态(0成功 1失败)
+	Msg           string // 提示消息
+	LoginTime     string // 登录时间
+	Module        string // 登录模块
+}
+
+// sysLoginLogColumns holds the columns for table sys_login_log.
+var sysLoginLogColumns = SysLoginLogColumns{
+	InfoId:        "info_id",
+	LoginName:     "login_name",
+	Ipaddr:        "ipaddr",
+	LoginLocation: "login_location",
+	Browser:       "browser",
+	Os:            "os",
+	Status:        "status",
+	Msg:           "msg",
+	LoginTime:     "login_time",
+	Module:        "module",
+}
+
+// NewSysLoginLogDao creates and returns a new DAO object for table data access.
+func NewSysLoginLogDao() *SysLoginLogDao {
+	return &SysLoginLogDao{
+		group:   "default",
+		table:   "sys_login_log",
+		columns: sysLoginLogColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysLoginLogDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysLoginLogDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysLoginLogDao) Columns() SysLoginLogColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysLoginLogDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysLoginLogDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysLoginLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 99 - 0
internal/app/system/dao/internal/sys_oper_log.go

@@ -0,0 +1,99 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysOperLogDao is the data access object for table sys_oper_log.
+type SysOperLogDao struct {
+	table   string            // table is the underlying table name of the DAO.
+	group   string            // group is the database configuration group name of current DAO.
+	columns SysOperLogColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysOperLogColumns defines and stores column names for table sys_oper_log.
+type SysOperLogColumns struct {
+	OperId        string // 日志主键
+	Title         string // 模块标题
+	BusinessType  string // 业务类型(0其它 1新增 2修改 3删除)
+	Method        string // 方法名称
+	RequestMethod string // 请求方式
+	OperatorType  string // 操作类别(0其它 1后台用户 2手机端用户)
+	OperName      string // 操作人员
+	DeptName      string // 部门名称
+	OperUrl       string // 请求URL
+	OperIp        string // 主机地址
+	OperLocation  string // 操作地点
+	OperParam     string // 请求参数
+	ErrorMsg      string // 错误消息
+	OperTime      string // 操作时间
+}
+
+// sysOperLogColumns holds the columns for table sys_oper_log.
+var sysOperLogColumns = SysOperLogColumns{
+	OperId:        "oper_id",
+	Title:         "title",
+	BusinessType:  "business_type",
+	Method:        "method",
+	RequestMethod: "request_method",
+	OperatorType:  "operator_type",
+	OperName:      "oper_name",
+	DeptName:      "dept_name",
+	OperUrl:       "oper_url",
+	OperIp:        "oper_ip",
+	OperLocation:  "oper_location",
+	OperParam:     "oper_param",
+	ErrorMsg:      "error_msg",
+	OperTime:      "oper_time",
+}
+
+// NewSysOperLogDao creates and returns a new DAO object for table data access.
+func NewSysOperLogDao() *SysOperLogDao {
+	return &SysOperLogDao{
+		group:   "default",
+		table:   "sys_oper_log",
+		columns: sysOperLogColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysOperLogDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysOperLogDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysOperLogDao) Columns() SysOperLogColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysOperLogDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysOperLogDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysOperLogDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 92 - 0
internal/app/system/dao/internal/sys_post.go

@@ -0,0 +1,92 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-04-07 23:26:21
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysPostDao is the data access object for table sys_post.
+type SysPostDao struct {
+	table   string         // table is the underlying table name of the DAO.
+	group   string         // group is the database configuration group name of current DAO.
+	columns SysPostColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysPostColumns defines and stores column names for table sys_post.
+type SysPostColumns struct {
+	PostId    string // 岗位ID
+	PostCode  string // 岗位编码
+	PostName  string // 岗位名称
+	PostSort  string // 显示顺序
+	Status    string // 状态(0正常 1停用)
+	Remark    string // 备注
+	CreatedBy string // 创建人
+	UpdatedBy string // 修改人
+	CreatedAt string // 创建时间
+	UpdatedAt string // 修改时间
+	DeletedAt string // 删除时间
+}
+
+// sysPostColumns holds the columns for table sys_post.
+var sysPostColumns = SysPostColumns{
+	PostId:    "post_id",
+	PostCode:  "post_code",
+	PostName:  "post_name",
+	PostSort:  "post_sort",
+	Status:    "status",
+	Remark:    "remark",
+	CreatedBy: "created_by",
+	UpdatedBy: "updated_by",
+	CreatedAt: "created_at",
+	UpdatedAt: "updated_at",
+	DeletedAt: "deleted_at",
+}
+
+// NewSysPostDao creates and returns a new DAO object for table data access.
+func NewSysPostDao() *SysPostDao {
+	return &SysPostDao{
+		group:   "default",
+		table:   "sys_post",
+		columns: sysPostColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysPostDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysPostDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysPostDao) Columns() SysPostColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysPostDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysPostDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 86 - 0
internal/app/system/dao/internal/sys_role.go

@@ -0,0 +1,86 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysRoleDao is the data access object for table sys_role.
+type SysRoleDao struct {
+	table   string         // table is the underlying table name of the DAO.
+	group   string         // group is the database configuration group name of current DAO.
+	columns SysRoleColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysRoleColumns defines and stores column names for table sys_role.
+type SysRoleColumns struct {
+	Id        string //
+	Status    string // 状态;0:禁用;1:正常
+	ListOrder string // 排序
+	Name      string // 角色名称
+	Remark    string // 备注
+	DataScope string // 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
+	CreatedAt string // 创建时间
+	UpdatedAt string // 更新时间
+}
+
+// sysRoleColumns holds the columns for table sys_role.
+var sysRoleColumns = SysRoleColumns{
+	Id:        "id",
+	Status:    "status",
+	ListOrder: "list_order",
+	Name:      "name",
+	Remark:    "remark",
+	DataScope: "data_scope",
+	CreatedAt: "created_at",
+	UpdatedAt: "updated_at",
+}
+
+// NewSysRoleDao creates and returns a new DAO object for table data access.
+func NewSysRoleDao() *SysRoleDao {
+	return &SysRoleDao{
+		group:   "default",
+		table:   "sys_role",
+		columns: sysRoleColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysRoleDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysRoleDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysRoleDao) Columns() SysRoleColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysRoleDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysRoleDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysRoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 75 - 0
internal/app/system/dao/internal/sys_role_dept.go

@@ -0,0 +1,75 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysRoleDeptDao is the data access object for table sys_role_dept.
+type SysRoleDeptDao struct {
+	table   string             // table is the underlying table name of the DAO.
+	group   string             // group is the database configuration group name of current DAO.
+	columns SysRoleDeptColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysRoleDeptColumns defines and stores column names for table sys_role_dept.
+type SysRoleDeptColumns struct {
+	RoleId string // 角色ID
+	DeptId string // 部门ID
+}
+
+// sysRoleDeptColumns holds the columns for table sys_role_dept.
+var sysRoleDeptColumns = SysRoleDeptColumns{
+	RoleId: "role_id",
+	DeptId: "dept_id",
+}
+
+// NewSysRoleDeptDao creates and returns a new DAO object for table data access.
+func NewSysRoleDeptDao() *SysRoleDeptDao {
+	return &SysRoleDeptDao{
+		group:   "default",
+		table:   "sys_role_dept",
+		columns: sysRoleDeptColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysRoleDeptDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysRoleDeptDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysRoleDeptDao) Columns() SysRoleDeptColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysRoleDeptDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysRoleDeptDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysRoleDeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 112 - 0
internal/app/system/dao/internal/sys_user.go

@@ -0,0 +1,112 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT. Created at 2022-03-02 16:48:23
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysUserDao is the data access object for table sys_user.
+type SysUserDao struct {
+	table   string         // table is the underlying table name of the DAO.
+	group   string         // group is the database configuration group name of current DAO.
+	columns SysUserColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysUserColumns defines and stores column names for table sys_user.
+type SysUserColumns struct {
+	Id            string //
+	UserName      string // 用户名
+	Mobile        string // 中国手机不带国家代码,国际手机号格式为:国家代码-手机号
+	UserNickname  string // 用户昵称
+	Birthday      string // 生日
+	UserPassword  string // 登录密码;cmf_password加密
+	UserSalt      string // 加密盐
+	UserStatus    string // 用户状态;0:禁用,1:正常,2:未验证
+	UserEmail     string // 用户登录邮箱
+	Sex           string // 性别;0:保密,1:男,2:女
+	Avatar        string // 用户头像
+	DeptId        string // 部门id
+	Remark        string // 备注
+	IsAdmin       string // 是否后台管理员 1 是  0   否
+	Address       string // 联系地址
+	Describe      string // 描述信息
+	LastLoginIp   string // 最后登录ip
+	LastLoginTime string // 最后登录时间
+	CreatedAt     string // 创建时间
+	UpdatedAt     string // 更新时间
+	DeletedAt     string // 删除时间
+}
+
+// sysUserColumns holds the columns for table sys_user.
+var sysUserColumns = SysUserColumns{
+	Id:            "id",
+	UserName:      "user_name",
+	Mobile:        "mobile",
+	UserNickname:  "user_nickname",
+	Birthday:      "birthday",
+	UserPassword:  "user_password",
+	UserSalt:      "user_salt",
+	UserStatus:    "user_status",
+	UserEmail:     "user_email",
+	Sex:           "sex",
+	Avatar:        "avatar",
+	DeptId:        "dept_id",
+	Remark:        "remark",
+	IsAdmin:       "is_admin",
+	Address:       "address",
+	Describe:      "describe",
+	LastLoginIp:   "last_login_ip",
+	LastLoginTime: "last_login_time",
+	CreatedAt:     "created_at",
+	UpdatedAt:     "updated_at",
+	DeletedAt:     "deleted_at",
+}
+
+// NewSysUserDao creates and returns a new DAO object for table data access.
+func NewSysUserDao() *SysUserDao {
+	return &SysUserDao{
+		group:   "default",
+		table:   "sys_user",
+		columns: sysUserColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysUserDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysUserDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysUserDao) Columns() SysUserColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysUserDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysUserDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysUserDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 87 - 0
internal/app/system/dao/internal/sys_user_online.go

@@ -0,0 +1,87 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysUserOnlineDao is the data access object for table sys_user_online.
+type SysUserOnlineDao struct {
+	table   string               // table is the underlying table name of the DAO.
+	group   string               // group is the database configuration group name of current DAO.
+	columns SysUserOnlineColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysUserOnlineColumns defines and stores column names for table sys_user_online.
+type SysUserOnlineColumns struct {
+	Id         string //
+	Uuid       string // 用户标识
+	Token      string // 用户token
+	CreateTime string // 登录时间
+	UserName   string // 用户名
+	Ip         string // 登录ip
+	Explorer   string // 浏览器
+	Os         string // 操作系统
+}
+
+// sysUserOnlineColumns holds the columns for table sys_user_online.
+var sysUserOnlineColumns = SysUserOnlineColumns{
+	Id:         "id",
+	Uuid:       "uuid",
+	Token:      "token",
+	CreateTime: "create_time",
+	UserName:   "user_name",
+	Ip:         "ip",
+	Explorer:   "explorer",
+	Os:         "os",
+}
+
+// NewSysUserOnlineDao creates and returns a new DAO object for table data access.
+func NewSysUserOnlineDao() *SysUserOnlineDao {
+	return &SysUserOnlineDao{
+		group:   "default",
+		table:   "sys_user_online",
+		columns: sysUserOnlineColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysUserOnlineDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysUserOnlineDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysUserOnlineDao) Columns() SysUserOnlineColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysUserOnlineDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysUserOnlineDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysUserOnlineDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 74 - 0
internal/app/system/dao/internal/sys_user_post.go

@@ -0,0 +1,74 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// SysUserPostDao is the data access object for table sys_user_post.
+type SysUserPostDao struct {
+	table   string             // table is the underlying table name of the DAO.
+	group   string             // group is the database configuration group name of current DAO.
+	columns SysUserPostColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// SysUserPostColumns defines and stores column names for table sys_user_post.
+type SysUserPostColumns struct {
+	UserId string // 用户ID
+	PostId string // 岗位ID
+}
+
+// sysUserPostColumns holds the columns for table sys_user_post.
+var sysUserPostColumns = SysUserPostColumns{
+	UserId: "user_id",
+	PostId: "post_id",
+}
+
+// NewSysUserPostDao creates and returns a new DAO object for table data access.
+func NewSysUserPostDao() *SysUserPostDao {
+	return &SysUserPostDao{
+		group:   "default",
+		table:   "sys_user_post",
+		columns: sysUserPostColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *SysUserPostDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *SysUserPostDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *SysUserPostDao) Columns() SysUserPostColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *SysUserPostDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *SysUserPostDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *SysUserPostDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 107 - 0
internal/app/system/dao/internal/tools_gen_table.go

@@ -0,0 +1,107 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// ToolsGenTableDao is the data access object for table tools_gen_table.
+type ToolsGenTableDao struct {
+	table   string               // table is the underlying table name of the DAO.
+	group   string               // group is the database configuration group name of current DAO.
+	columns ToolsGenTableColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// ToolsGenTableColumns defines and stores column names for table tools_gen_table.
+type ToolsGenTableColumns struct {
+	TableId        string // 编号
+	TableName      string // 表名称
+	TableComment   string // 表描述
+	ClassName      string // 实体类名称
+	TplCategory    string // 使用的模板(crud单表操作 tree树表操作)
+	PackageName    string // 生成包路径
+	ModuleName     string // 生成模块名
+	BusinessName   string // 生成业务名
+	FunctionName   string // 生成功能名
+	FunctionAuthor string // 生成功能作者
+	Options        string // 其它生成选项
+	CreateTime     string // 创建时间
+	UpdateTime     string // 更新时间
+	Remark         string // 备注
+	Overwrite      string // 是否覆盖原有文件
+	SortColumn     string // 排序字段名
+	SortType       string // 排序方式 (asc顺序 desc倒序)
+	ShowDetail     string // 是否有查看详情功能
+}
+
+// toolsGenTableColumns holds the columns for table tools_gen_table.
+var toolsGenTableColumns = ToolsGenTableColumns{
+	TableId:        "table_id",
+	TableName:      "table_name",
+	TableComment:   "table_comment",
+	ClassName:      "class_name",
+	TplCategory:    "tpl_category",
+	PackageName:    "package_name",
+	ModuleName:     "module_name",
+	BusinessName:   "business_name",
+	FunctionName:   "function_name",
+	FunctionAuthor: "function_author",
+	Options:        "options",
+	CreateTime:     "create_time",
+	UpdateTime:     "update_time",
+	Remark:         "remark",
+	Overwrite:      "overwrite",
+	SortColumn:     "sort_column",
+	SortType:       "sort_type",
+	ShowDetail:     "show_detail",
+}
+
+// NewToolsGenTableDao creates and returns a new DAO object for table data access.
+func NewToolsGenTableDao() *ToolsGenTableDao {
+	return &ToolsGenTableDao{
+		group:   "default",
+		table:   "tools_gen_table",
+		columns: toolsGenTableColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *ToolsGenTableDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *ToolsGenTableDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *ToolsGenTableDao) Columns() ToolsGenTableColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *ToolsGenTableDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *ToolsGenTableDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *ToolsGenTableDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 151 - 0
internal/app/system/dao/internal/tools_gen_table_column.go

@@ -0,0 +1,151 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+
+	"github.com/gogf/gf/v2/database/gdb"
+	"github.com/gogf/gf/v2/frame/g"
+)
+
+// ToolsGenTableColumnDao is the data access object for table tools_gen_table_column.
+type ToolsGenTableColumnDao struct {
+	table   string                     // table is the underlying table name of the DAO.
+	group   string                     // group is the database configuration group name of current DAO.
+	columns ToolsGenTableColumnColumns // columns contains all the column names of Table for convenient usage.
+}
+
+// ToolsGenTableColumnColumns defines and stores column names for table tools_gen_table_column.
+type ToolsGenTableColumnColumns struct {
+	ColumnId              string // 编号
+	TableId               string // 归属表编号
+	ColumnName            string // 列名称
+	ColumnComment         string // 列描述
+	ColumnType            string // 列类型
+	GoType                string // Go类型
+	TsType                string // TS类型
+	GoField               string // Go字段名
+	HtmlField             string // html字段名
+	IsPk                  string // 是否主键(1是)
+	IsIncrement           string // 是否自增(1是)
+	IsRequired            string // 是否必填(1是)
+	IsInsert              string // 是否为插入字段(1是)
+	IsEdit                string // 是否编辑字段(1是)
+	IsList                string // 是否列表字段(1是)
+	IsDetail              string // 是否详情字段
+	IsQuery               string // 是否查询字段(1是)
+	SortOrderEdit         string // 插入编辑显示顺序
+	SortOrderList         string // 列表显示顺序
+	SortOrderDetail       string // 详情显示顺序
+	SortOrderQuery        string // 查询显示顺序
+	QueryType             string // 查询方式(等于、不等于、大于、小于、范围)
+	HtmlType              string // 显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)
+	DictType              string // 字典类型
+	LinkTableName         string // 关联表名
+	LinkTableClass        string // 关联表类名
+	LinkTableModuleName   string // 关联表模块名
+	LinkTableBusinessName string // 关联表业务名
+	LinkTablePackage      string // 关联表包名
+	LinkLabelId           string // 关联表键名
+	LinkLabelName         string // 关联表字段值
+	ColSpan               string // 详情页占列数
+	RowSpan               string // 详情页占行数
+	IsRowStart            string // 详情页为行首
+	MinWidth              string // 表格最小宽度
+	IsFixed               string // 是否表格列左固定
+	IsOverflowTooltip     string // 是否过长自动隐藏
+	IsCascade             string // 是否级联查询
+	ParentColumnName      string // 上级字段名
+	CascadeColumnName     string // 级联查询字段
+}
+
+// toolsGenTableColumnColumns holds the columns for table tools_gen_table_column.
+var toolsGenTableColumnColumns = ToolsGenTableColumnColumns{
+	ColumnId:              "column_id",
+	TableId:               "table_id",
+	ColumnName:            "column_name",
+	ColumnComment:         "column_comment",
+	ColumnType:            "column_type",
+	GoType:                "go_type",
+	TsType:                "ts_type",
+	GoField:               "go_field",
+	HtmlField:             "html_field",
+	IsPk:                  "is_pk",
+	IsIncrement:           "is_increment",
+	IsRequired:            "is_required",
+	IsInsert:              "is_insert",
+	IsEdit:                "is_edit",
+	IsList:                "is_list",
+	IsDetail:              "is_detail",
+	IsQuery:               "is_query",
+	SortOrderEdit:         "sort_order_edit",
+	SortOrderList:         "sort_order_list",
+	SortOrderDetail:       "sort_order_detail",
+	SortOrderQuery:        "sort_order_query",
+	QueryType:             "query_type",
+	HtmlType:              "html_type",
+	DictType:              "dict_type",
+	LinkTableName:         "link_table_name",
+	LinkTableClass:        "link_table_class",
+	LinkTableModuleName:   "link_table_module_name",
+	LinkTableBusinessName: "link_table_business_name",
+	LinkTablePackage:      "link_table_package",
+	LinkLabelId:           "link_label_id",
+	LinkLabelName:         "link_label_name",
+	ColSpan:               "col_span",
+	RowSpan:               "row_span",
+	IsRowStart:            "is_row_start",
+	MinWidth:              "min_width",
+	IsFixed:               "is_fixed",
+	IsOverflowTooltip:     "is_overflow_tooltip",
+	IsCascade:             "is_cascade",
+	ParentColumnName:      "parent_column_name",
+	CascadeColumnName:     "cascade_column_name",
+}
+
+// NewToolsGenTableColumnDao creates and returns a new DAO object for table data access.
+func NewToolsGenTableColumnDao() *ToolsGenTableColumnDao {
+	return &ToolsGenTableColumnDao{
+		group:   "default",
+		table:   "tools_gen_table_column",
+		columns: toolsGenTableColumnColumns,
+	}
+}
+
+// DB retrieves and returns the underlying raw database management object of current DAO.
+func (dao *ToolsGenTableColumnDao) DB() gdb.DB {
+	return g.DB(dao.group)
+}
+
+// Table returns the table name of current dao.
+func (dao *ToolsGenTableColumnDao) Table() string {
+	return dao.table
+}
+
+// Columns returns all column names of current dao.
+func (dao *ToolsGenTableColumnDao) Columns() ToolsGenTableColumnColumns {
+	return dao.columns
+}
+
+// Group returns the configuration group name of database of current dao.
+func (dao *ToolsGenTableColumnDao) Group() string {
+	return dao.group
+}
+
+// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
+func (dao *ToolsGenTableColumnDao) Ctx(ctx context.Context) *gdb.Model {
+	return dao.DB().Model(dao.table).Safe().Ctx(ctx)
+}
+
+// Transaction wraps the transaction logic using function f.
+// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
+// It commits the transaction and returns nil if function f returns nil.
+//
+// Note that, you should not Commit or Rollback the transaction in function f
+// as it is automatically handled by this function.
+func (dao *ToolsGenTableColumnDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
+	return dao.Ctx(ctx).Transaction(ctx, f)
+}

+ 24 - 0
internal/app/system/dao/sys_auth_rule.go

@@ -0,0 +1,24 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"github.com/tiger1103/gfast/v3/internal/app/system/dao/internal"
+)
+
+// sysAuthRuleDao is the data access object for table sys_auth_rule.
+// You can define custom methods on it to extend its functionality as you wish.
+type sysAuthRuleDao struct {
+	*internal.SysAuthRuleDao
+}
+
+var (
+	// SysAuthRule is globally public accessible object for table sys_auth_rule operations.
+	SysAuthRule = sysAuthRuleDao{
+		internal.NewSysAuthRuleDao(),
+	}
+)
+
+// Fill with you ideas below.

+ 27 - 0
internal/app/system/dao/sys_dept.go

@@ -0,0 +1,27 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"github.com/tiger1103/gfast/v3/internal/app/system/dao/internal"
+)
+
+// internalSysDeptDao is internal type for wrapping internal DAO implements.
+type internalSysDeptDao = *internal.SysDeptDao
+
+// sysDeptDao is the data access object for table sys_dept.
+// You can define custom methods on it to extend its functionality as you wish.
+type sysDeptDao struct {
+	internalSysDeptDao
+}
+
+var (
+	// SysDept is globally public accessible object for table sys_dept operations.
+	SysDept = sysDeptDao{
+		internal.NewSysDeptDao(),
+	}
+)
+
+// Fill with you ideas below.

+ 29 - 0
internal/app/system/dao/sys_job.go

@@ -0,0 +1,29 @@
+// ==========================================================================
+// GFast自动生成dao操作代码。
+// 生成日期:2023-01-12 17:43:50
+// 生成路径: internal/app/system/dao/sys_job.go
+// 生成人:gfast
+// desc:定时任务
+// company:云南奇讯科技有限公司
+// ==========================================================================
+
+package dao
+
+import (
+	"github.com/tiger1103/gfast/v3/internal/app/system/dao/internal"
+)
+
+// sysJobDao is the manager for logic model data accessing and custom defined data operations functions management.
+// You can define custom methods on it to extend its functionality as you wish.
+type sysJobDao struct {
+	*internal.SysJobDao
+}
+
+var (
+	// SysJob is globally public accessible object for table tools_gen_table operations.
+	SysJob = sysJobDao{
+		internal.NewSysJobDao(),
+	}
+)
+
+// Fill with you ideas below.

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor