Kaynağa Gözat

项目初始

yxh 4 yıl önce
ebeveyn
işleme
f7a750ff89
100 değiştirilmiş dosya ile 8932 ekleme ve 0 silme
  1. 1 0
      .gitattributes
  2. 23 0
      .gitignore
  3. 26 0
      Dockerfile
  4. 129 0
      README.MD
  5. 63 0
      app/common/adapter/upload.go
  6. 225 0
      app/common/adapter/upload_local_apapter.go
  7. 268 0
      app/common/adapter/upload_tencent_cos_adapter.go
  8. 24 0
      app/common/api/captcha.go
  9. 33 0
      app/common/api/common_base.go
  10. 25 0
      app/common/dao/casbin_rule.go
  11. 395 0
      app/common/dao/internal/casbin_rule.go
  12. 57 0
      app/common/dao/internal/sys_config.go
  13. 26 0
      app/common/dao/sys_config.go
  14. 22 0
      app/common/global/cache_key.go
  15. 14 0
      app/common/model/casbin_rule.go
  16. 16 0
      app/common/model/internal/casbin_rule.go
  17. 13 0
      app/common/model/req.go
  18. 51 0
      app/common/model/sys_config.go
  19. 244 0
      app/common/service/cache.go
  20. 41 0
      app/common/service/captcha.go
  21. 237 0
      app/common/service/casbin.go
  22. 150 0
      app/common/service/sys_config.go
  23. 228 0
      app/system/api/auth.go
  24. 158 0
      app/system/api/sys_auth_rule.go
  25. 18 0
      app/system/api/sys_base.go
  26. 109 0
      app/system/api/sys_config.go
  27. 124 0
      app/system/api/sys_dept.go
  28. 119 0
      app/system/api/sys_dict_data.go
  29. 96 0
      app/system/api/sys_dict_type.go
  30. 116 0
      app/system/api/sys_job.go
  31. 60 0
      app/system/api/sys_login_log.go
  32. 150 0
      app/system/api/sys_monitor.go
  33. 110 0
      app/system/api/sys_oper_log.go
  34. 88 0
      app/system/api/sys_post.go
  35. 138 0
      app/system/api/sys_role.go
  36. 233 0
      app/system/api/sys_user.go
  37. 57 0
      app/system/api/sys_user_online.go
  38. 45 0
      app/system/api/sys_web_set.go
  39. 33 0
      app/system/api/upload.go
  40. 82 0
      app/system/api/user_Profile.go
  41. 0 0
      app/system/dao/.gitkeep
  42. 41 0
      app/system/dao/context.go
  43. 420 0
      app/system/dao/internal/sys_auth_rule.go
  44. 65 0
      app/system/dao/internal/sys_dept.go
  45. 411 0
      app/system/dao/internal/sys_dict_data.go
  46. 401 0
      app/system/dao/internal/sys_dict_type.go
  47. 65 0
      app/system/dao/internal/sys_job.go
  48. 400 0
      app/system/dao/internal/sys_login_log.go
  49. 69 0
      app/system/dao/internal/sys_model_info.go
  50. 67 0
      app/system/dao/internal/sys_oper_log.go
  51. 57 0
      app/system/dao/internal/sys_post.go
  52. 393 0
      app/system/dao/internal/sys_role.go
  53. 39 0
      app/system/dao/internal/sys_role_dept.go
  54. 424 0
      app/system/dao/internal/sys_user.go
  55. 397 0
      app/system/dao/internal/sys_user_online.go
  56. 39 0
      app/system/dao/internal/sys_user_post.go
  57. 39 0
      app/system/dao/internal/sys_web_set.go
  58. 70 0
      app/system/dao/sys_auth_rule.go
  59. 58 0
      app/system/dao/sys_dept.go
  60. 25 0
      app/system/dao/sys_dict_data.go
  61. 23 0
      app/system/dao/sys_dict_type.go
  62. 58 0
      app/system/dao/sys_job.go
  63. 35 0
      app/system/dao/sys_login_log.go
  64. 39 0
      app/system/dao/sys_model_info.go
  65. 54 0
      app/system/dao/sys_oper_log.go
  66. 54 0
      app/system/dao/sys_post.go
  67. 25 0
      app/system/dao/sys_role.go
  68. 25 0
      app/system/dao/sys_role_dept.go
  69. 52 0
      app/system/dao/sys_user.go
  70. 49 0
      app/system/dao/sys_user_online.go
  71. 25 0
      app/system/dao/sys_user_post.go
  72. 28 0
      app/system/dao/sys_web_set.go
  73. 0 0
      app/system/model/.gitkeep
  74. 33 0
      app/system/model/internal/sys_auth_rule.go
  75. 28 0
      app/system/model/internal/sys_dict_data.go
  76. 23 0
      app/system/model/internal/sys_dict_type.go
  77. 23 0
      app/system/model/internal/sys_login_log.go
  78. 26 0
      app/system/model/internal/sys_model_info.go
  79. 15 0
      app/system/model/internal/sys_role.go
  80. 11 0
      app/system/model/internal/sys_role_dept.go
  81. 35 0
      app/system/model/internal/sys_user.go
  82. 21 0
      app/system/model/internal/sys_user_online.go
  83. 11 0
      app/system/model/internal/sys_user_post.go
  84. 67 0
      app/system/model/sys_auth_rule.go
  85. 27 0
      app/system/model/sys_dept.go
  86. 71 0
      app/system/model/sys_dict_data.go
  87. 47 0
      app/system/model/sys_dict_type.go
  88. 28 0
      app/system/model/sys_job.go
  89. 36 0
      app/system/model/sys_login_log.go
  90. 14 0
      app/system/model/sys_model_info.go
  91. 29 0
      app/system/model/sys_oper_log.go
  92. 24 0
      app/system/model/sys_post.go
  93. 34 0
      app/system/model/sys_role.go
  94. 14 0
      app/system/model/sys_role_dept.go
  95. 114 0
      app/system/model/sys_user.go
  96. 22 0
      app/system/model/sys_user_online.go
  97. 14 0
      app/system/model/sys_user_post.go
  98. 19 0
      app/system/model/sys_web_set.go
  99. 152 0
      app/system/router/router.go
  100. 0 0
      app/system/service/.gitkeep

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
+* linguist-language=GO

+ 23 - 0
.gitignore

@@ -0,0 +1,23 @@
+.buildpath
+.hgignore.swp
+.project
+.orig
+.swp
+.idea/
+.settings/
+.vscode/
+vender/
+data/log/
+data/session/
+composer.lock
+gitpush.sh
+pkg/
+bin/
+cbuild
+*/.DS_Store
+main
+.vscode
+*.exe
+tmp/*
+public/resource/pub_upload/
+data/dataBak

+ 26 - 0
Dockerfile

@@ -0,0 +1,26 @@
+FROM loads/alpine:3.8
+
+LABEL maintainer="john@goframe.org"
+
+###############################################################################
+#                                INSTALLATION
+###############################################################################
+
+# 设置固定的项目路径
+ENV WORKDIR /var/www/gfast
+
+# 添加应用可执行文件,并设置执行权限
+ADD ./bin/linux_amd64/main   $WORKDIR/main
+RUN chmod +x $WORKDIR/main
+
+# 添加I18N多语言文件、静态文件、配置文件、模板文件
+ADD i18n     $WORKDIR/i18n
+ADD public   $WORKDIR/public
+ADD config   $WORKDIR/config
+ADD template $WORKDIR/template
+
+###############################################################################
+#                                   START
+###############################################################################
+WORKDIR $WORKDIR
+CMD ./main

+ 129 - 0
README.MD

@@ -0,0 +1,129 @@
+# GFast-V2
+
+## 平台简介
+* 基于GF(Go Frame)的后台管理系统
+* 前端采用ruoyi-ui 、Vue、Element UI。
+* 后端采用GO语言 框架 GF(Go Frame)。
+* 阿里云优惠券:[点我进入](https://www.aliyun.com/minisite/goods?userCode=fcor2omk ),腾讯云优惠券:[点我领取](https://cloud.tencent.com/act/cps/redirect?redirect=1062&cps_key=20b1c3842f74986b2894e2c5fcde7ea2&from=console )
+* 本项目由奇讯科技团队开发。
+
+## 内置功能
+
+1.  用户管理:用户是系统操作者,该功能主要完成系统用户配置。
+2.  部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
+3.  岗位管理:配置系统用户所属担任职务。
+4.  菜单管理:配置系统菜单,操作权限,按钮权限标识等。
+5.  角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
+6.  字典管理:对系统中经常使用的一些较为固定的数据进行维护。
+7.  参数管理:对系统动态配置常用参数。
+8.  操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
+9. 登录日志:系统登录日志记录查询包含登录异常。
+10. 在线用户:当前系统中活跃用户状态监控。
+11. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
+12. 代码生成:前后端代码的生成。
+13. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
+14. 在线构建器:拖动表单元素生成相应的HTML代码。
+15. 文件上传,缓存标签等。
+16. 正在开发中的功能:cms管理、模型管理、工作流引擎
+
+## 演示地址
+[http://demo.g-fast.cn](http://demo.g-fast.cn/)
+账号:demo  密码:123456
+## 配置
+项目数据库文件 /data/db.sql 创建数据库导入后修改配置/config/config.toml
+
+其中jwt配置
+
+```yaml
+[gToken]
+    [gToken.system]
+        CacheMode = 2 #此处若使用了redis配置为2 若没使用redis配置1
+        CacheKey = "GToken:"
+        Timeout = 3600000 #1个小时
+        MaxRefresh = 0
+        TokenDelimiter="_"
+        EncryptKey = "koi29a83idakguqjq29asd9asd8a7jhq"
+        AuthFailMsg = "登录超时,请重新登录"
+        MultiLogin = true  #后台是否允许多端同时在线
+```
+
+##运行
+go run main.go 直接访问http://localhost:8199
+
+账号:demo  密码:123456
+
+项目为前后端分离,前端地址:
+
+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.qjit.cn/docs/gfast/introduce](http://doc.qjit.cn/docs/gfast/introduce)
+
+## 演示图
+
+<table>
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
+    </tr>
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/707825ad3f29de74a8d6d02fbd73ad631ea.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/46be40cc6f01aa300eed53a19b5012bf484.jpg"/></td>
+    </tr>
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/4284796d4cea240d181b8f2201813dda710.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/3ecfac87a049f7fe36abbcaafb2c40d36cf.jpg"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/71c2d48905221a09a728df4aff4160b8607.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/c14c1ee9a64a6a9c2c22f67d43198767dbe.jpg"/></td>
+    </tr>	 
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/fdea1d8bb8625c27bf964176a2c8ebc6945.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/509d2708cfd762b6e6339364cac1cc1970c.jpg"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-f1fd681cc9d295db74e85ad6d2fe4389454.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
+    </tr>
+</table>
+
+## 感谢(排名不分先后)
+> gf框架 [https://github.com/gogf/gf](https://github.com/gogf/gf)
+>
+> RuoYi-Vue [https://gitee.com/y_project/RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)
+>
+> swaggo [https://github.com/swaggo/swag](https://github.com/swaggo/swag)
+>
+>tpflow [https://gitee.com/ntdgg/tpflow](https://gitee.com/ntdgg/tpflow)
+>
+>gtoken [https://github.com/goflyfox/gtoken](https://github.com/goflyfox/gtoken)
+>
+>casbin [https://github.com/casbin/casbin](https://github.com/casbin/casbin)
+>
+>云捷go [https://gitee.com/yunjieg/yjgo](https://gitee.com/yunjieg/yjgo)
+## 交流QQ群
+
+> <img src="https://gitee.com/tiger1103/gfast/raw/master/public/qqcode.png"/>  
+
+> 快来加入群聊【Gfast框架交流群】(群号865697297),发现精彩内容。
+
+## 免责声明:
+> 1、Gfast仅限自己学习使用,一切商业行为与Gfast无关。
+
+> 2、用户不得利用Gfast从事非法行为,用户应当合法合规的使用,发现用户在使用产品时有任何的非法行为,Gfast有权配合有关机关进行调查或向政府部门举报,Gfast不承担用户因非法行为造成的任何法律责任,一切法律责任由用户自行承担,如因用户使用造成第三方损害的,用户应当依法予以赔偿。
+
+> 3、所有与使用Gfast相关的资源直接风险均由用户承担。
+
+###生成dao
+因为我们在开发过程中,goFrame框架的gf-cli 一直在更新功能,建议不要直接去覆盖,生成到tmp目录后将需要的文件复制到对应的地方
+```
+例如: gf gen dao -path ./tmp  -l "mysql:root:123456@tcp(127.0.0.1:3306)/gfast-v2" -t 表名
+```
+

+ 63 - 0
app/common/adapter/upload.go

@@ -0,0 +1,63 @@
+/*
+* @desc:上传适配器
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/7 8:54
+ */
+
+package adapter
+
+import (
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+)
+
+// FileInfo 上传的文件信息
+type FileInfo struct {
+	FileName string `json:"fileName"`
+	FileSize int64  `json:"fileSize"`
+	FileUrl  string `json:"fileUrl"`
+	FileType string `json:"fileType"`
+}
+
+type UploadAdapter interface {
+	UpImg(file *ghttp.UploadFile) (fileInfo *FileInfo, err error)
+	UpFile(file *ghttp.UploadFile) (fileInfo *FileInfo, err error)
+	UpImgs(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error)
+	UpFiles(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error)
+}
+
+type upload struct {
+	adapter UploadAdapter
+}
+
+var Upload = &upload{
+	//使用本地上传
+	adapter: UploadLocalAdapter{
+		UpPath:     "/pub_upload/",
+		UploadPath: g.Cfg().GetString("server.ServerRoot") + "/pub_upload/",
+	},
+	//使用腾讯云COS上传
+	/*adapter: UploadTencentCOSAdapter{
+		UpPath:    "/gfast/",
+		RawUrl:    "https://您的cos空间域名.cos.ap-chongqing.myqcloud.com",
+		SecretID:  "填写您的SecretID",
+		SecretKey: "填写您的SecretKey",
+	},*/
+}
+
+func (u upload) UpImg(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
+	return u.adapter.UpImg(file)
+}
+
+func (u upload) UpFile(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
+	return u.adapter.UpFile(file)
+}
+
+func (u upload) UpImgs(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
+	return u.adapter.UpImgs(files)
+}
+
+func (u upload) UpFiles(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
+	return u.adapter.UpFiles(files)
+}

+ 225 - 0
app/common/adapter/upload_local_apapter.go

@@ -0,0 +1,225 @@
+/*
+* @desc:本地上传
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/7 8:47
+ */
+
+package adapter
+
+import (
+	"gfast/app/common/model"
+	"gfast/app/common/service"
+	"github.com/gogf/gf/errors/gerror"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/os/gtime"
+	"github.com/gogf/gf/text/gregex"
+	"github.com/gogf/gf/text/gstr"
+	"github.com/gogf/gf/util/gconv"
+)
+
+type UploadLocalAdapter struct {
+	UpPath     string
+	UploadPath string
+}
+
+// UpImg 上传图片
+func (up UploadLocalAdapter) UpImg(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
+	return up.upByType(file, "img")
+}
+
+// UpFile 上传文件
+func (up UploadLocalAdapter) UpFile(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
+	return up.upByType(file, "file")
+}
+
+// UpImgs 批量上传图片
+func (up UploadLocalAdapter) UpImgs(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
+	return up.upBathByType(files, "img")
+}
+
+// UpFiles 批量上传文件
+func (up UploadLocalAdapter) UpFiles(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
+	return up.upBathByType(files, "file")
+}
+
+//文件上传 img|file
+func (up UploadLocalAdapter) upByType(file *ghttp.UploadFile, fType string) (fileInfo *FileInfo, err error) {
+	if file == nil {
+		err = gerror.New("未上传任何文件")
+		return
+	}
+	var (
+		typeKey string
+		sizeKey string
+	)
+	if fType == "img" {
+		typeKey = "sys.uploadFile.imageType"
+		sizeKey = "sys.uploadFile.imageSize"
+	} else if fType == "file" {
+		typeKey = "sys.uploadFile.fileType"
+		sizeKey = "sys.uploadFile.fileSize"
+	}
+	//获取上传类型配置
+	config, err := up.getUpConfig(typeKey)
+	if err != nil {
+		return
+	}
+
+	//检测文件类型
+	rightType := up.checkFileType(file.Filename, config.ConfigValue)
+	if !rightType {
+		err = gerror.New("上传文件类型错误,只能包含后缀为:" + config.ConfigValue + "的文件。")
+		return
+	}
+	//获取上传大小配置
+	config, err = up.getUpConfig(sizeKey)
+	if err != nil {
+		return
+	}
+	rightSize, err := up.checkSize(config.ConfigValue, file.Size)
+	if err != nil {
+		return
+	}
+	if !rightSize {
+		err = gerror.New("上传文件超过最大尺寸:" + config.ConfigValue)
+		return
+	}
+	path := up.getUpPath()
+	fileName, err := file.Save(path, true)
+	if err != nil {
+		return
+	}
+	fileInfo = &FileInfo{
+		FileName: file.Filename,
+		FileSize: file.Size,
+		FileUrl:  up.getUrl(path, fileName),
+		FileType: file.Header.Get("Content-type"),
+	}
+	return
+}
+
+//批量上传 img|file
+func (up UploadLocalAdapter) upBathByType(files []*ghttp.UploadFile, fType string) (fileInfos []*FileInfo, err error) {
+	if len(files) == 0 {
+		err = gerror.New("未上传任何文件")
+		return
+	}
+	var (
+		typeKey string
+		sizeKey string
+	)
+	if fType == "img" {
+		typeKey = "sys.uploadFile.imageType"
+		sizeKey = "sys.uploadFile.imageSize"
+	} else if fType == "file" {
+		typeKey = "sys.uploadFile.fileType"
+		sizeKey = "sys.uploadFile.fileSize"
+	}
+	//获取上传类型配置
+	configType, err := up.getUpConfig(typeKey)
+	if err != nil {
+		return
+	}
+	//获取上传大小配置
+	configSize, err := up.getUpConfig(sizeKey)
+	if err != nil {
+		return
+	}
+	for _, file := range files {
+		//检测文件类型
+		rightType := up.checkFileType(file.Filename, configType.ConfigValue)
+		if !rightType {
+			err = gerror.New("上传文件类型错误,只能包含后缀为:" + configType.ConfigValue + "的文件。")
+			return
+		}
+		var rightSize bool
+		rightSize, err = up.checkSize(configSize.ConfigValue, file.Size)
+		if err != nil {
+			return
+		}
+		if !rightSize {
+			err = gerror.New("上传文件超过最大尺寸:" + configSize.ConfigValue)
+			return
+		}
+	}
+	path := up.getUpPath()
+	for _, file := range files {
+		var fileName string
+		fileName, err = file.Save(path, true)
+		if err != nil {
+			return
+		}
+		fileInfo := &FileInfo{
+			FileName: file.Filename,
+			FileSize: file.Size,
+			FileUrl:  up.getUrl(path, fileName),
+			FileType: file.Header.Get("Content-type"),
+		}
+		fileInfos = append(fileInfos, fileInfo)
+	}
+	return
+}
+
+//检查文件大小是否合法
+func (up UploadLocalAdapter) checkSize(configSize string, fileSize int64) (bool, error) {
+	match, err := gregex.MatchString(`^([0-9]+)(?i:([a-z]*))$`, configSize)
+	if err != nil {
+		return false, err
+	}
+	if len(match) == 0 {
+		err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB)")
+		return false, err
+	}
+	var cfSize int64
+	switch gstr.ToUpper(match[2]) {
+	case "MB", "M":
+		cfSize = gconv.Int64(match[1]) * 1024 * 1024
+	case "KB", "K":
+		cfSize = gconv.Int64(match[1]) * 1024
+	case "":
+		cfSize = gconv.Int64(match[1])
+	}
+	if cfSize == 0 {
+		err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB),最大单位为MB")
+		return false, err
+	}
+	return cfSize >= fileSize, nil
+}
+
+//获取上传配置
+func (up UploadLocalAdapter) getUpConfig(key string) (config *model.SysConfig, err error) {
+	config, err = service.SysConfig.GetConfigByKey(key)
+	if err != nil {
+		return
+	}
+	if config == nil {
+		err = gerror.New("上传文件类型未设置,请在后台配置")
+		return
+	}
+	return
+}
+
+//判断上传文件类型是否合法
+func (up UploadLocalAdapter) checkFileType(fileName, typeString string) bool {
+	suffix := gstr.SubStrRune(fileName, gstr.PosRRune(fileName, ".")+1, gstr.LenRune(fileName)-1)
+	imageType := gstr.Split(typeString, ",")
+	rightType := false
+	for _, v := range imageType {
+		if gstr.Equal(suffix, v) {
+			rightType = true
+			break
+		}
+	}
+	return rightType
+}
+
+func (up UploadLocalAdapter) getUpPath() (upPath string) {
+	upPath = up.UploadPath + gtime.Date() + "/"
+	return
+}
+
+func (up UploadLocalAdapter) getUrl(path, fileName string) string {
+	url := gstr.SubStr(path, gstr.Pos(path, up.UpPath)+1) + fileName
+	return url
+}

+ 268 - 0
app/common/adapter/upload_tencent_cos_adapter.go

@@ -0,0 +1,268 @@
+/*
+* @desc:腾讯oss
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/7 15:51
+ */
+
+package adapter
+
+import (
+	"context"
+	"gfast/app/common/model"
+	"gfast/app/common/service"
+	"github.com/gogf/gf/errors/gerror"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/os/gfile"
+	"github.com/gogf/gf/os/gtime"
+	"github.com/gogf/gf/text/gregex"
+	"github.com/gogf/gf/text/gstr"
+	"github.com/gogf/gf/util/gconv"
+	"github.com/gogf/gf/util/grand"
+	"github.com/tencentyun/cos-go-sdk-v5"
+	"github.com/tencentyun/cos-go-sdk-v5/debug"
+	"io"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+)
+
+type UploadTencentCOSAdapter struct {
+	UpPath    string
+	SecretID  string
+	SecretKey string
+	RawUrl    string
+}
+
+func (u UploadTencentCOSAdapter) UpImg(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
+	return u.upByType(file, "img")
+}
+
+func (u UploadTencentCOSAdapter) UpFile(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
+	return u.upByType(file, "file")
+}
+
+func (u UploadTencentCOSAdapter) UpImgs(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
+	return u.upBathByType(files, "img")
+}
+
+func (u UploadTencentCOSAdapter) UpFiles(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
+	return u.upBathByType(files, "file")
+}
+
+//文件上传 img|file
+func (u UploadTencentCOSAdapter) upByType(file *ghttp.UploadFile, fType string) (fileInfo *FileInfo, err error) {
+	if file == nil {
+		err = gerror.New("未上传任何文件")
+		return
+	}
+	var (
+		typeKey string
+		sizeKey string
+	)
+	if fType == "img" {
+		typeKey = "sys.uploadFile.imageType"
+		sizeKey = "sys.uploadFile.imageSize"
+	} else if fType == "file" {
+		typeKey = "sys.uploadFile.fileType"
+		sizeKey = "sys.uploadFile.fileSize"
+	}
+	//获取上传类型配置
+	config, err := u.getUpConfig(typeKey)
+	if err != nil {
+		return
+	}
+
+	//检测文件类型
+	rightType := u.checkFileType(file.Filename, config.ConfigValue)
+	if !rightType {
+		err = gerror.New("上传文件类型错误,只能包含后缀为:" + config.ConfigValue + "的文件。")
+		return
+	}
+	//获取上传大小配置
+	config, err = u.getUpConfig(sizeKey)
+	if err != nil {
+		return
+	}
+	rightSize, err := u.checkSize(config.ConfigValue, file.Size)
+	if err != nil {
+		return
+	}
+	if !rightSize {
+		err = gerror.New("上传文件超过最大尺寸:" + config.ConfigValue)
+		return
+	}
+	var path string
+	path, err = u.upAction(file)
+	if err != nil {
+		return
+	}
+	fileInfo = &FileInfo{
+		FileName: file.Filename,
+		FileSize: file.Size,
+		FileUrl:  u.getUrl(path),
+		FileType: file.Header.Get("Content-type"),
+	}
+	return
+}
+
+//批量上传 img|file
+func (u UploadTencentCOSAdapter) upBathByType(files []*ghttp.UploadFile, fType string) (fileInfos []*FileInfo, err error) {
+	if len(files) == 0 {
+		err = gerror.New("未上传任何文件")
+		return
+	}
+	var (
+		typeKey string
+		sizeKey string
+	)
+	if fType == "img" {
+		typeKey = "sys.uploadFile.imageType"
+		sizeKey = "sys.uploadFile.imageSize"
+	} else if fType == "file" {
+		typeKey = "sys.uploadFile.fileType"
+		sizeKey = "sys.uploadFile.fileSize"
+	}
+	//获取上传类型配置
+	configType, err := u.getUpConfig(typeKey)
+	if err != nil {
+		return
+	}
+	//获取上传大小配置
+	configSize, err := u.getUpConfig(sizeKey)
+	if err != nil {
+		return
+	}
+	for _, file := range files {
+		//检测文件类型
+		rightType := u.checkFileType(file.Filename, configType.ConfigValue)
+		if !rightType {
+			err = gerror.New("上传文件类型错误,只能包含后缀为:" + configType.ConfigValue + "的文件。")
+			return
+		}
+		var rightSize bool
+		rightSize, err = u.checkSize(configSize.ConfigValue, file.Size)
+		if err != nil {
+			return
+		}
+		if !rightSize {
+			err = gerror.New("上传文件超过最大尺寸:" + configSize.ConfigValue)
+			return
+		}
+	}
+	for _, file := range files {
+		var path string
+		path, err = u.upAction(file)
+		if err != nil {
+			return
+		}
+		fileInfo := &FileInfo{
+			FileName: file.Filename,
+			FileSize: file.Size,
+			FileUrl:  u.getUrl(path),
+			FileType: file.Header.Get("Content-type"),
+		}
+		fileInfos = append(fileInfos, fileInfo)
+	}
+	return
+}
+
+// 上传到腾讯cos操作
+func (u UploadTencentCOSAdapter) upAction(file *ghttp.UploadFile) (path string, err error) {
+	name := gfile.Basename(file.Filename)
+	name = strings.ToLower(strconv.FormatInt(gtime.TimestampNano(), 36) + grand.S(6))
+	name = name + gfile.Ext(file.Filename)
+
+	path = u.getUpPath() + name
+	url, _ := url.Parse(u.RawUrl)
+	b := &cos.BaseURL{BucketURL: url}
+	c := cos.NewClient(b, &http.Client{
+		Transport: &cos.AuthorizationTransport{
+			SecretID:  u.SecretID,
+			SecretKey: u.SecretKey,
+			Transport: &debug.DebugRequestTransport{
+				RequestHeader:  false,
+				RequestBody:    false,
+				ResponseHeader: false,
+				ResponseBody:   false,
+			},
+		},
+	})
+	opt := &cos.ObjectPutOptions{
+		ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
+			ContentLength: int64(file.Size),
+		},
+	}
+	var f io.ReadCloser
+	f, err = file.Open()
+	if err != nil {
+		return
+	}
+	defer f.Close()
+	_, err = c.Object.Put(context.Background(), path, f, opt)
+	return
+}
+
+//获取上传配置
+func (u UploadTencentCOSAdapter) getUpConfig(key string) (config *model.SysConfig, err error) {
+	config, err = service.SysConfig.GetConfigByKey(key)
+	if err != nil {
+		return
+	}
+	if config == nil {
+		err = gerror.New("上传文件类型未设置,请在后台配置")
+		return
+	}
+	return
+}
+
+//判断上传文件类型是否合法
+func (u UploadTencentCOSAdapter) checkFileType(fileName, typeString string) bool {
+	suffix := gstr.SubStrRune(fileName, gstr.PosRRune(fileName, ".")+1, gstr.LenRune(fileName)-1)
+	imageType := gstr.Split(typeString, ",")
+	rightType := false
+	for _, v := range imageType {
+		if gstr.Equal(suffix, v) {
+			rightType = true
+			break
+		}
+	}
+	return rightType
+}
+
+//检查文件大小是否合法
+func (u UploadTencentCOSAdapter) checkSize(configSize string, fileSize int64) (bool, error) {
+	match, err := gregex.MatchString(`^([0-9]+)(?i:([a-z]*))$`, configSize)
+	if err != nil {
+		return false, err
+	}
+	if len(match) == 0 {
+		err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB)")
+		return false, err
+	}
+	var cfSize int64
+	switch gstr.ToUpper(match[2]) {
+	case "MB", "M":
+		cfSize = gconv.Int64(match[1]) * 1024 * 1024
+	case "KB", "K":
+		cfSize = gconv.Int64(match[1]) * 1024
+	case "":
+		cfSize = gconv.Int64(match[1])
+	}
+	if cfSize == 0 {
+		err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB),最大单位为MB")
+		return false, err
+	}
+	return cfSize >= fileSize, nil
+}
+
+func (u UploadTencentCOSAdapter) getUpPath() (upPath string) {
+	upPath = u.UpPath + gtime.Date() + "/"
+	return
+}
+
+func (u UploadTencentCOSAdapter) getUrl(path string) string {
+	url := u.RawUrl + path
+	return url
+}

+ 24 - 0
app/common/api/captcha.go

@@ -0,0 +1,24 @@
+package api
+
+import (
+	"gfast/app/common/service"
+	"gfast/library"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+)
+
+type captcha struct{}
+
+var Captcha = new(captcha)
+
+// Img
+// @Summary 获取验证码图片信息
+// @Description 获取验证码图片信息
+// @Tags 公共
+// @Success 0 {object} response.Response "{"code": 200, "data": [...]}"
+// @Router /system/public/verify [post]
+// @Security
+func (c *captcha) Img(r *ghttp.Request) {
+	idKeyC, base64stringC := service.Captcha.GetVerifyImgString()
+	library.SusJson(true, r, "ok", g.MapStrStr{"idKeyC": idKeyC, "base64stringC": base64stringC})
+}

+ 33 - 0
app/common/api/common_base.go

@@ -0,0 +1,33 @@
+package api
+
+import (
+	"gfast/library"
+	"github.com/gogf/gf/net/ghttp"
+)
+
+type CommonBase struct{}
+
+// SusJson 成功的返回
+func (c *CommonBase) SusJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) {
+	library.SusJson(isExit, r, msg, data...)
+}
+
+// FailJson 失败的返回
+func (c *CommonBase) FailJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) {
+	library.FailJson(isExit, r, msg, data...)
+}
+
+// FailJsonExit 失败中断返回
+func (c *CommonBase) FailJsonExit(r *ghttp.Request, msg string) {
+	c.FailJson(true, r, msg)
+}
+
+// SusJsonExit 成功中断返回
+func (c *CommonBase) SusJsonExit(r *ghttp.Request, data ...interface{}) {
+	c.SusJson(true, r, "success", data...)
+}
+
+// JsonExit 输出json并中断
+func (c *CommonBase) JsonExit(r *ghttp.Request, code int, msg string, data ...interface{}) {
+	library.JsonExit(r, code, msg, data...)
+}

+ 25 - 0
app/common/dao/casbin_rule.go

@@ -0,0 +1,25 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package dao
+
+import (
+	"gfast/app/common/dao/internal"
+)
+
+// casbinRuleDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// 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.CasbinRule,
+	}
+)
+
+// Fill with you ideas below.

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

@@ -0,0 +1,395 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+
+	"gfast/app/common/model"
+)
+
+// CasbinRuleDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type CasbinRuleDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns casbinRuleColumns
+}
+
+// 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 //
+}
+
+var (
+	// CasbinRule is globally public accessible object for table casbin_rule operations.
+	CasbinRule = CasbinRuleDao{
+		M:     g.DB("default").Model("casbin_rule").Safe(),
+		DB:    g.DB("default"),
+		Table: "casbin_rule",
+		Columns: casbinRuleColumns{
+			Ptype: "ptype",
+			V0:    "v0",
+			V1:    "v1",
+			V2:    "v2",
+			V3:    "v3",
+			V4:    "v4",
+			V5:    "v5",
+		},
+	}
+)
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *CasbinRuleDao) Ctx(ctx context.Context) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *CasbinRuleDao) As(as string) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *CasbinRuleDao) TX(tx *gdb.TX) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *CasbinRuleDao) Master() *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *CasbinRuleDao) Slave() *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *CasbinRuleDao) Args(args ...interface{}) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *CasbinRuleDao) LeftJoin(table ...string) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *CasbinRuleDao) RightJoin(table ...string) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *CasbinRuleDao) InnerJoin(table ...string) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *CasbinRuleDao) Fields(fieldNamesOrMapStruct ...interface{}) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *CasbinRuleDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *CasbinRuleDao) Option(option int) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *CasbinRuleDao) OmitEmpty() *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *CasbinRuleDao) Filter() *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *CasbinRuleDao) Where(where interface{}, args ...interface{}) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *CasbinRuleDao) WherePri(where interface{}, args ...interface{}) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *CasbinRuleDao) And(where interface{}, args ...interface{}) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *CasbinRuleDao) Or(where interface{}, args ...interface{}) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *CasbinRuleDao) Group(groupBy string) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *CasbinRuleDao) Order(orderBy ...string) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *CasbinRuleDao) Limit(limit ...int) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *CasbinRuleDao) Offset(offset int) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *CasbinRuleDao) Page(page, limit int) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *CasbinRuleDao) Batch(batch int) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *CasbinRuleDao) Cache(duration time.Duration, name ...string) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *CasbinRuleDao) Data(data ...interface{}) *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.CasbinRule.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *CasbinRuleDao) All(where ...interface{}) ([]*model.CasbinRule, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.CasbinRule
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.CasbinRule.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *CasbinRuleDao) One(where ...interface{}) (*model.CasbinRule, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.CasbinRule
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *CasbinRuleDao) FindOne(where ...interface{}) (*model.CasbinRule, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.CasbinRule
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *CasbinRuleDao) FindAll(where ...interface{}) ([]*model.CasbinRule, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.CasbinRule
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *CasbinRuleDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *CasbinRuleDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *CasbinRuleDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *CasbinRuleDao) Chunk(limit int, callback func(entities []*model.CasbinRule, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*model.CasbinRule
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *CasbinRuleDao) LockUpdate() *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *CasbinRuleDao) LockShared() *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *CasbinRuleDao) Unscoped() *CasbinRuleDao {
+	return &CasbinRuleDao{M: d.M.Unscoped()}
+}

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

@@ -0,0 +1,57 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysConfigDao is the manager for logic model data accessing and custom defined data operations functions management.
+type SysConfigDao struct {
+	gmvc.M                  // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	C      sysConfigColumns // C is the short type for Columns, which contains all the column names of Table for convenient usage.
+	DB     gdb.DB           // DB is the raw underlying database management object.
+	Table  string           // Table is the underlying table name of the DAO.
+}
+
+// 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 // 修改时间
+	DeletedAt   string // 删除时间
+}
+
+// NewSysConfigDao creates and returns a new DAO object for table data access.
+func NewSysConfigDao() *SysConfigDao {
+	columns := 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",
+		DeletedAt:   "deleted_at",
+	}
+	return &SysConfigDao{
+		C:     columns,
+		M:     g.DB("default").Model("sys_config").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_config",
+	}
+}

+ 26 - 0
app/common/dao/sys_config.go

@@ -0,0 +1,26 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"gfast/app/common/dao/internal"
+)
+
+// sysConfigDao 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 sysConfigDao struct {
+	*internal.SysConfigDao
+}
+
+var (
+	// SysConfig is globally public accessible object for table sys_config operations.
+	SysConfig sysConfigDao
+)
+
+func init() {
+	SysConfig = sysConfigDao{
+		internal.NewSysConfigDao(),
+	}
+}

+ 22 - 0
app/common/global/cache_key.go

@@ -0,0 +1,22 @@
+package global
+
+const (
+	//缓存前缀
+	cachePrefix = "cache_"
+
+	// SysAuthMenu 缓存菜单KEY
+	SysAuthMenu = cachePrefix + "sysAuthMenu"
+	// SysDict 字典缓存菜单KEY
+	SysDict = cachePrefix + "sysDict"
+	// SysRole 角色缓存key
+	SysRole = cachePrefix + "sysRole"
+	// SysWebSet 站点配置缓存key
+	SysWebSet = cachePrefix + "sysWebSet"
+
+	// SysAuthTag 权限缓存TAG标签
+	SysAuthTag = cachePrefix + "sysAuthTag"
+	// SysDictTag 字典缓存标签
+	SysDictTag = cachePrefix + "sysDictTag"
+	// SysConfigTag 系统参数配置
+	SysConfigTag = cachePrefix + "sysConfigTag"
+)

+ 14 - 0
app/common/model/casbin_rule.go

@@ -0,0 +1,14 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package model
+
+import (
+	"gfast/app/common/model/internal"
+)
+
+// CasbinRule is the golang structure for table casbin_rule.
+type CasbinRule internal.CasbinRule
+
+// Fill with you ideas below.

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

@@ -0,0 +1,16 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+// CasbinRule is the golang structure for table casbin_rule.
+type CasbinRule struct {
+	Ptype string `orm:"ptype" json:"ptype"` //
+	V0    string `orm:"v0"    json:"v0"`    //
+	V1    string `orm:"v1"    json:"v1"`    //
+	V2    string `orm:"v2"    json:"v2"`    //
+	V3    string `orm:"v3"    json:"v3"`    //
+	V4    string `orm:"v4"    json:"v4"`    //
+	V5    string `orm:"v5"    json:"v5"`    //
+}

+ 13 - 0
app/common/model/req.go

@@ -0,0 +1,13 @@
+package model
+
+import "context"
+
+const PageSize = 10
+
+type PageReq struct {
+	BeginTime string `p:"beginTime"` //开始时间
+	EndTime   string `p:"endTime"`   //结束时间
+	PageNum   int    `p:"PageNum"`   //当前页码
+	PageSize  int    `p:"pageSize"`  //每页数
+	Ctx       context.Context
+}

+ 51 - 0
app/common/model/sys_config.go

@@ -0,0 +1,51 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package model
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysConfig is the golang structure for table sys_config.
+type SysConfig struct {
+	ConfigId    uint        `orm:"config_id,primary" json:"configId"`    // 参数主键
+	ConfigName  string      `orm:"config_name"       json:"configName"`  // 参数名称
+	ConfigKey   string      `orm:"config_key,unique" json:"configKey"`   // 参数键名
+	ConfigValue string      `orm:"config_value"      json:"configValue"` // 参数键值
+	ConfigType  int         `orm:"config_type"       json:"configType"`  // 系统内置(Y是 N否)
+	CreateBy    uint        `orm:"create_by"         json:"createBy"`    // 创建者
+	UpdateBy    uint        `orm:"update_by"         json:"updateBy"`    // 更新者
+	Remark      string      `orm:"remark"            json:"remark"`      // 备注
+	CreatedAt   *gtime.Time `orm:"created_at"        json:"createdAt"`   // 创建时间
+	UpdatedAt   *gtime.Time `orm:"updated_at"        json:"updatedAt"`   // 修改时间
+	DeletedAt   *gtime.Time `orm:"deleted_at"        json:"deletedAt"`   // 删除时间
+}
+
+//分页请求参数
+type SysConfigSearchReq struct {
+	ConfigName string `p:"configName"` //参数名称
+	ConfigKey  string `p:"configKey"`  //参数键名
+	ConfigType string `p:"configType"` //状态
+	BeginTime  string `p:"beginTime"`  //开始时间
+	EndTime    string `p:"endTime"`    //结束时间
+	PageReq
+}
+
+//新增页面请求参数
+type SysConfigAddReq 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"`
+	CreateBy    uint64
+}
+
+//修改页面请求参数
+type SysConfigEditReq struct {
+	ConfigId int64 `p:"configId" v:"required|min:1#主键ID不能为空|主键ID参数错误"`
+	UpdateBy uint64
+	SysConfigAddReq
+}

+ 244 - 0
app/common/service/cache.go

@@ -0,0 +1,244 @@
+package service
+
+import (
+	"context"
+	"fmt"
+	"github.com/gogf/gcache-adapter/adapter"
+	"github.com/gogf/gf/crypto/gmd5"
+	"github.com/gogf/gf/encoding/gjson"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/os/gcache"
+	"github.com/gogf/gf/util/gconv"
+	"reflect"
+	"sync"
+	"time"
+)
+
+type cache struct {
+}
+
+type cacheTagService struct {
+	tagKey    interface{}
+	cache     *gcache.Cache
+	tagSetMux *sync.Mutex
+}
+
+var (
+	Cache     = new(cache)
+	userRedis = g.Cfg().GetBool("redis.open")
+	gChe      = gcache.New()
+)
+
+func (s *cache) New() *cacheTagService {
+	gChe.Ctx(context.Background())
+	if userRedis {
+		adapter := adapter.NewRedis(g.Redis())
+		gChe.SetAdapter(adapter)
+	}
+	return &cacheTagService{
+		cache:     gChe,
+		tagSetMux: new(sync.Mutex),
+	}
+}
+
+//设置tag缓存的keys
+func (c *cacheTagService) cacheTagKey(key interface{}, tag interface{}) {
+	c.setTagKey(tag)
+	if c.tagKey != nil {
+		tagValue := []interface{}{key}
+		value, _ := c.cache.Get(c.tagKey)
+		if value != nil {
+			var keyValue []interface{}
+			//若是字符串
+			if kStr, ok := value.(string); ok {
+				js, err := gjson.DecodeToJson(kStr)
+				if err != nil {
+					g.Log().Error(err)
+					return
+				}
+				keyValue = gconv.SliceAny(js.Value())
+			} else {
+				keyValue = gconv.SliceAny(value)
+			}
+			for _, v := range keyValue {
+				if !reflect.DeepEqual(key, v) {
+					tagValue = append(tagValue, v)
+				}
+			}
+		}
+		c.cache.Set(c.tagKey, tagValue, 0)
+	}
+}
+
+//获取带标签的键名
+func (c *cacheTagService) setTagKey(tag interface{}) {
+	if tag != nil {
+		c.tagKey = interface{}(fmt.Sprintf("cache_tag_%s", gmd5.MustEncryptString(gconv.String(tag))))
+	}
+}
+
+// Set sets cache with <tagKey>-<value> pair, which is expired after <duration>.
+// It does not expire if <duration> <= 0.
+func (c *cacheTagService) Set(key interface{}, value interface{}, duration time.Duration, tag ...interface{}) {
+	c.tagSetMux.Lock()
+	if len(tag) > 0 {
+		c.cacheTagKey(key, tag[0])
+	}
+	err := c.cache.Set(key, value, duration)
+	if err != nil {
+		g.Log().Error(err)
+	}
+	c.tagSetMux.Unlock()
+}
+
+// SetIfNotExist sets cache with <tagKey>-<value> pair if <tagKey> does not exist in the cache,
+// which is expired after <duration>. It does not expire if <duration> <= 0.
+func (c *cacheTagService) SetIfNotExist(key interface{}, value interface{}, duration time.Duration, tag interface{}) bool {
+	c.tagSetMux.Lock()
+	defer c.tagSetMux.Unlock()
+	c.cacheTagKey(key, tag)
+	v, _ := c.cache.SetIfNotExist(key, value, duration)
+	return v
+}
+
+// Sets batch sets cache with tagKey-value pairs by <data>, which is expired after <duration>.
+//
+// It does not expire if <duration> <= 0.
+func (c *cacheTagService) Sets(data map[interface{}]interface{}, duration time.Duration, tag interface{}) {
+	c.tagSetMux.Lock()
+	if tag != nil {
+		for k, _ := range data {
+			c.cacheTagKey(k, tag)
+		}
+		c.cache.Sets(data, duration)
+	} else {
+		c.cache.Sets(data, duration)
+	}
+	c.tagSetMux.Unlock()
+}
+
+// Get returns the value of <tagKey>.
+// It returns nil if it does not exist or its value is nil.
+func (c *cacheTagService) Get(key interface{}) interface{} {
+	v, err := c.cache.Get(key)
+	if err != nil {
+		g.Log().Error(err)
+	}
+	return v
+}
+
+// GetOrSet returns the value of <tagKey>,
+// or sets <tagKey>-<value> pair and returns <value> if <tagKey> does not exist in the cache.
+// The tagKey-value pair expires after <duration>.
+//
+// It does not expire if <duration> <= 0.
+func (c *cacheTagService) GetOrSet(key interface{}, value interface{}, duration time.Duration, tag interface{}) interface{} {
+	c.tagSetMux.Lock()
+	defer c.tagSetMux.Unlock()
+	c.cacheTagKey(key, tag)
+	v, _ := c.cache.GetOrSet(key, value, duration)
+	return v
+}
+
+// GetOrSetFunc returns the value of <tagKey>, or sets <tagKey> with result of function <f>
+// and returns its result if <tagKey> does not exist in the cache. The tagKey-value pair expires
+// after <duration>. It does not expire if <duration> <= 0.
+func (c *cacheTagService) GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration, tag interface{}) interface{} {
+	c.tagSetMux.Lock()
+	defer c.tagSetMux.Unlock()
+	c.cacheTagKey(key, tag)
+	v, _ := c.cache.GetOrSetFunc(key, f, duration)
+	return v
+}
+
+// GetOrSetFuncLock returns the value of <tagKey>, or sets <tagKey> with result of function <f>
+// and returns its result if <tagKey> does not exist in the cache. The tagKey-value pair expires
+// after <duration>. It does not expire if <duration> <= 0.
+//
+// Note that the function <f> is executed within writing mutex lock.
+func (c *cacheTagService) GetOrSetFuncLock(key interface{}, f func() (interface{}, error), duration time.Duration, tag interface{}) interface{} {
+	c.tagSetMux.Lock()
+	defer c.tagSetMux.Unlock()
+	c.cacheTagKey(key, tag)
+	v, _ := c.cache.GetOrSetFuncLock(key, f, duration)
+	return v
+}
+
+// Contains returns true if <tagKey> exists in the cache, or else returns false.
+func (c *cacheTagService) Contains(key interface{}) bool {
+	v, _ := c.cache.Contains(key)
+	return v
+}
+
+// Remove deletes the <tagKey> in the cache, and returns its value.
+func (c *cacheTagService) Remove(key interface{}) interface{} {
+	v, _ := c.cache.Remove(key)
+	return v
+}
+
+// Removes deletes <keys> in the cache.
+func (c *cacheTagService) Removes(keys []interface{}) {
+	c.cache.Remove(keys...)
+}
+
+// Remove deletes the <tag> in the cache, and returns its value.
+func (c *cacheTagService) RemoveByTag(tag interface{}) {
+	c.tagSetMux.Lock()
+	c.setTagKey(tag)
+	//删除tagKey 对应的 key和值
+	keys := c.Get(c.tagKey)
+	if keys != nil {
+		//如果是字符串
+		if kStr, ok := keys.(string); ok {
+			js, err := gjson.DecodeToJson(kStr)
+			if err != nil {
+				g.Log().Error(err)
+				return
+			}
+			ks := gconv.SliceAny(js.Value())
+			c.Removes(ks)
+		} else {
+			ks := gconv.SliceAny(keys)
+			c.Removes(ks)
+		}
+	}
+	c.Remove(c.tagKey)
+	c.tagSetMux.Unlock()
+}
+
+// Removes deletes <tags> in the cache.
+func (c *cacheTagService) RemoveByTags(tag []interface{}) {
+	for _, v := range tag {
+		c.RemoveByTag(v)
+	}
+}
+
+// Data returns a copy of all tagKey-value pairs in the cache as map type.
+func (c *cacheTagService) Data() map[interface{}]interface{} {
+	v, _ := c.cache.Data()
+	return v
+}
+
+// Keys returns all keys in the cache as slice.
+func (c *cacheTagService) Keys() []interface{} {
+	v, _ := c.cache.Keys()
+	return v
+}
+
+// KeyStrings returns all keys in the cache as string slice.
+func (c *cacheTagService) KeyStrings() []string {
+	v, _ := c.cache.KeyStrings()
+	return v
+}
+
+// Values returns all values in the cache as slice.
+func (c *cacheTagService) Values() []interface{} {
+	v, _ := c.cache.Values()
+	return v
+}
+
+// Size returns the size of the cache.
+func (c *cacheTagService) Size() int {
+	v, _ := c.cache.Size()
+	return v
+}

+ 41 - 0
app/common/service/captcha.go

@@ -0,0 +1,41 @@
+package service
+
+import (
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/text/gstr"
+	"github.com/mojocn/base64Captcha"
+)
+
+type captcha struct{}
+
+var Captcha = new(captcha)
+
+//获取字母数字混合验证码
+func (s *captcha) GetVerifyImgString() (idKeyC string, base64stringC string) {
+	driver := &base64Captcha.DriverString{
+		Height:          80,
+		Width:           240,
+		NoiseCount:      50,
+		ShowLineOptions: 20,
+		Length:          4,
+		Source:          "abcdefghjkmnpqrstuvwxyz23456789",
+		Fonts:           []string{"chromohv.ttf"},
+	}
+	driver = driver.ConvertFonts()
+	store := base64Captcha.DefaultMemStore
+	c := base64Captcha.NewCaptcha(driver, store)
+	idKeyC, base64stringC, err := c.Generate()
+	if err != nil {
+		g.Log().Error(err)
+	}
+	return
+}
+
+//验证输入的验证码是否正确
+func (s *captcha) VerifyString(id, answer string) bool {
+	driver := new(base64Captcha.DriverString)
+	store := base64Captcha.DefaultMemStore
+	c := base64Captcha.NewCaptcha(driver, store)
+	answer = gstr.ToLower(answer)
+	return c.Verify(id, answer, true)
+}

+ 237 - 0
app/common/service/casbin.go

@@ -0,0 +1,237 @@
+package service
+
+import (
+	"gfast/app/common/dao"
+	dbModel "gfast/app/common/model"
+	"github.com/casbin/casbin/v2"
+	"github.com/casbin/casbin/v2/model"
+	"github.com/casbin/casbin/v2/persist"
+	"github.com/gogf/gf/frame/g"
+	"sync"
+)
+
+type cabin struct{}
+
+type adapterCasbin struct {
+	Enforcer    *casbin.SyncedEnforcer
+	EnforcerErr error
+}
+
+var (
+	Casbin = new(cabin)
+	once   sync.Once
+	m      sync.RWMutex
+	ac     *adapterCasbin
+)
+
+// GetEnforcer 获取adapter单例对象
+func (s *cabin) GetEnforcer() (enforcer *casbin.SyncedEnforcer, err error) {
+	once.Do(func() {
+		ac = s.newAdapter()
+	})
+	enforcer = ac.Enforcer
+	err = ac.EnforcerErr
+	return
+}
+
+//初始化adapter操作
+func (s *cabin) newAdapter() (a *adapterCasbin) {
+	a = new(adapterCasbin)
+	a.initPolicy()
+	return
+}
+
+func (a *adapterCasbin) initPolicy() {
+	// 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().GetString("casbin.modelFile"),
+		g.Cfg().GetString("casbin.policyFile"))
+
+	if err != nil {
+		a.EnforcerErr = err
+		return
+	}
+
+	// This is a trick to save the current policy to the DB.
+	// We can't call e.SavePolicy() because the adapter in the enforcer is still the file adapter.
+	// The current policy means the policy in the Casbin enforcer (aka in memory).
+	//err = a.SavePolicy(e.GetModel())
+	//if err != nil {
+	//	return err
+	//}
+	//set adapter
+	e.SetAdapter(a)
+	// Clear the current policy.
+	e.ClearPolicy()
+	a.Enforcer = e
+	// Load the policy from DB.
+	err = a.LoadPolicy(e.GetModel())
+	if err != nil {
+		a.EnforcerErr = err
+		return
+	}
+}
+
+// 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.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.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 []*dbModel.CasbinRule
+	if err := dao.CasbinRule.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.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 := &dbModel.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 *dbModel.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) *dbModel.CasbinRule {
+	line := &dbModel.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 *dbModel.CasbinRule) error {
+	db := dao.CasbinRule.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
+}

+ 150 - 0
app/common/service/sys_config.go

@@ -0,0 +1,150 @@
+/*
+* @desc:系统参数设置
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/5 18:00
+ */
+
+package service
+
+import (
+	"gfast/app/common/dao"
+	"gfast/app/common/global"
+	"gfast/app/common/model"
+	"github.com/gogf/gf/errors/gerror"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/util/gconv"
+)
+
+type sysConfig struct {
+}
+
+var SysConfig = new(sysConfig)
+
+func (s *sysConfig) SelectListByPage(req *model.SysConfigSearchReq) (total, page int, list []*model.SysConfig, err error) {
+	m := dao.SysConfig.Ctx(req.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 req.BeginTime != "" {
+			m = m.Where("create_time >= ? ", req.BeginTime)
+		}
+
+		if req.EndTime != "" {
+			m = m.Where("create_time<=?", req.EndTime)
+		}
+	}
+	total, err = m.Count()
+	if err != nil {
+		g.Log().Error(err)
+		err = gerror.New("获取总行数失败")
+		return
+	}
+	if req.PageNum == 0 {
+		req.PageNum = 1
+	}
+	page = req.PageNum
+	if req.PageSize == 0 {
+		req.PageSize = model.PageSize
+	}
+	err = m.Page(page, req.PageSize).Order("config_id asc").Scan(&list)
+	if err != nil {
+		g.Log().Error(err)
+		err = gerror.New("获取数据失败")
+		return
+	}
+	return
+}
+
+// CheckConfigKeyUniqueAll 验证参数键名是否存在
+func (s *sysConfig) CheckConfigKeyUniqueAll(configKey string) error {
+	entity, err := dao.SysConfig.Fields(dao.SysConfig.C.ConfigId).FindOne(dao.SysConfig.C.ConfigKey, configKey)
+	if err != nil {
+		g.Log().Error(err)
+		return gerror.New("校验数据失败")
+	}
+	if entity != nil {
+		return gerror.New("参数键名已经存在")
+	}
+	return nil
+}
+
+// AddSave 添加操作
+func (s *sysConfig) AddSave(req *model.SysConfigAddReq) (err error) {
+	_, err = dao.SysConfig.Insert(req)
+	return
+}
+
+func (s *sysConfig) GetById(id int) (data *model.SysConfig, err error) {
+	err = dao.SysConfig.WherePri(id).Scan(&data)
+	return
+}
+
+// CheckConfigKeyUnique 检查键是否已经存在
+func (s *sysConfig) CheckConfigKeyUnique(configKey string, configId int64) error {
+	entity, err := dao.SysConfig.Fields(dao.SysConfig.C.ConfigId).
+		FindOne(dao.SysConfig.C.ConfigKey+"=? and "+dao.SysConfig.C.ConfigId+"!=?",
+			configKey, configId)
+	if err != nil {
+		g.Log().Error(err)
+		return gerror.New("校验数据失败")
+	}
+	if entity != nil {
+		return gerror.New("参数键名已经存在")
+	}
+	return nil
+}
+
+// EditSave 修改系统参数
+func (s *sysConfig) EditSave(req *model.SysConfigEditReq) (err error) {
+	_, err = dao.SysConfig.FieldsEx(dao.SysConfig.C.ConfigId, dao.SysConfig.C.CreateBy).
+		WherePri(req.ConfigId).Data(req).Update()
+	return
+}
+
+// DeleteByIds 删除
+func (s *sysConfig) DeleteByIds(ids []int) error {
+	_, err := dao.SysConfig.Delete(dao.SysConfig.C.ConfigId+" in (?)", ids)
+	if err != nil {
+		g.Log().Error(err)
+		return gerror.New("删除失败")
+	}
+	return nil
+}
+
+// GetConfigByKey 通过key获取参数(从缓存获取)
+func (s *sysConfig) GetConfigByKey(key string) (config *model.SysConfig, err error) {
+	if key == "" {
+		err = gerror.New("参数key不能为空")
+		return
+	}
+	cache := Cache.New()
+	cf := cache.Get(global.SysConfigTag + key)
+	if cf != nil {
+		err = gconv.Struct(cf, &config)
+		return
+	}
+	config, err = s.GetByKey(key)
+	if err != nil {
+		return
+	}
+	cache.Set(global.SysConfigTag+key, config, 0, global.SysConfigTag)
+	return
+}
+
+// GetByKey 通过key获取参数(从数据库获取)
+func (s *sysConfig) GetByKey(key string) (config *model.SysConfig, err error) {
+	err = dao.SysConfig.Where("config_key", key).Scan(&config)
+	if err != nil {
+		g.Log().Error(err)
+		err = gerror.New("获取配置失败")
+	}
+	return
+}

+ 228 - 0
app/system/api/auth.go

@@ -0,0 +1,228 @@
+package api
+
+import (
+	"gfast/app/common/api"
+	comModel "gfast/app/common/model"
+	commonService "gfast/app/common/service"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"gfast/library"
+	"github.com/goflyfox/gtoken/gtoken"
+	"github.com/gogf/gf/crypto/gmd5"
+	"github.com/gogf/gf/encoding/gjson"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/os/gcache"
+	"github.com/gogf/gf/os/genv"
+	"github.com/gogf/gf/os/gtime"
+	"github.com/gogf/gf/util/gconv"
+	"github.com/gogf/gf/util/gvalid"
+	"github.com/mssola/user_agent"
+	"strings"
+)
+
+type auth struct {
+	api.CommonBase
+}
+
+var (
+	Auth       = new(auth)
+	MultiLogin = g.Cfg().GetBool("gToken.system.MultiLogin")
+	GfToken    = &gtoken.GfToken{
+		CacheMode:        g.Cfg().GetInt8("gToken.system.CacheMode"),
+		CacheKey:         g.Cfg().GetString("gToken.system.CacheKey"),
+		Timeout:          g.Cfg().GetInt("gToken.system.Timeout"),
+		MaxRefresh:       g.Cfg().GetInt("gToken.system.MaxRefresh"),
+		TokenDelimiter:   g.Cfg().GetString("gToken.system.TokenDelimiter"),
+		EncryptKey:       g.Cfg().GetBytes("gToken.system.EncryptKey"),
+		AuthFailMsg:      g.Cfg().GetString("gToken.system.AuthFailMsg"),
+		MultiLogin:       MultiLogin,
+		LoginPath:        "/login",
+		LoginBeforeFunc:  Auth.login,
+		LoginAfterFunc:   Auth.loginAfter,
+		LogoutPath:       "/logout",
+		AuthExcludePaths: g.SliceStr{"/login"},
+		AuthAfterFunc:    Auth.authAfterFunc,
+		LogoutBeforeFunc: Auth.loginOut,
+	}
+)
+
+//后台用户登陆验证
+func (c *auth) login(r *ghttp.Request) (string, interface{}) {
+	var ctx = r.GetCtx()
+	var apiReq *model.LoginParamsReq
+	if err := r.Parse(&apiReq); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	//判断验证码是否正确
+	debug := genv.GetWithCmd("gf.debug")
+	if debug.Int() != 1 {
+		if !commonService.Captcha.VerifyString(apiReq.VerifyKey, apiReq.VerifyCode) {
+			c.FailJson(true, r, "验证码输入错误")
+		}
+	}
+	ip := library.GetClientIp(r)
+	userAgent := r.Header.Get("User-Agent")
+	if user, err := service.SysUser.GetAdminUserByUsernamePassword(ctx, apiReq); err != nil {
+		//保存日志(异步)
+		service.SysLoginLog.Invoke(&model.LoginLogParams{
+			Status:    0,
+			Username:  apiReq.Username,
+			Ip:        ip,
+			UserAgent: userAgent,
+			Msg:       err.Error(),
+			Module:    "系统后台",
+		})
+		c.FailJsonExit(r, err.Error())
+	} else if user != nil {
+		r.SetParam("userInfo", user)
+		//更新用户登录记录 写入日志信息
+		service.SysUser.UpdateLoginInfo(user.Id, apiReq.Username, ip, userAgent, "登录成功", "系统后台")
+		var keys string
+		if MultiLogin {
+			keys = gconv.String(user.Id) + "-" + gmd5.MustEncryptString(user.UserName) + gmd5.MustEncryptString(user.UserPassword+ip)
+		} else {
+			keys = gconv.String(user.Id) + "-" + gmd5.MustEncryptString(user.UserName) + gmd5.MustEncryptString(user.UserPassword)
+		}
+		return keys, user
+	}
+	return "", nil
+}
+
+//登录成功返回
+func (c *auth) loginAfter(r *ghttp.Request, respData gtoken.Resp) {
+	if !respData.Success() {
+		r.Response.WriteJson(respData)
+	} else {
+		token := respData.GetString("token")
+		uuid := respData.GetString("uuid")
+		var userInfo *model.LoginUserRes
+		r.GetParamVar("userInfo").Struct(&userInfo)
+		//保存用户在线状态token到数据库
+		userAgent := r.Header.Get("User-Agent")
+		ua := user_agent.New(userAgent)
+		os := ua.OS()
+		explorer, _ := ua.Browser()
+		onlineData := &model.SysUserOnline{
+			Uuid:       uuid,
+			Token:      token,
+			CreateTime: gtime.Now(),
+			UserName:   userInfo.UserName,
+			Ip:         library.GetClientIp(r),
+			Explorer:   explorer,
+			Os:         os,
+		}
+		//保存用户在线状态(异步)
+		service.Online.Invoke(onlineData)
+		c.SusJsonExit(r, g.Map{
+			"token": token,
+		})
+	}
+}
+
+//gToken验证后返回
+func (c *auth) authAfterFunc(r *ghttp.Request, respData gtoken.Resp) {
+	if r.Method == "OPTIONS" || respData.Success() {
+		r.Middleware.Next()
+	} else {
+		c.JsonExit(r, respData.Code, "用户信息验证失败")
+	}
+}
+
+//后台退出登陆
+func (c *auth) loginOut(r *ghttp.Request) bool {
+	//删除在线用户状态
+	authHeader := r.Header.Get("Authorization")
+	if authHeader != "" {
+		parts := strings.SplitN(authHeader, " ", 2)
+		if len(parts) == 2 && parts[0] == "Bearer" && parts[1] != "" {
+			//删除在线用户状态操作
+			service.Online.DeleteOnlineByToken(parts[1])
+		}
+	}
+	authHeader = r.GetString("token")
+	if authHeader != "" {
+		//删除在线用户状态操作
+		service.Online.DeleteOnlineByToken(authHeader)
+	}
+	return true
+}
+
+// CheckUserOnline 检查在线用户
+func (c *auth) CheckUserOnline() {
+	param := &model.SysUserOnlineSearchReq{
+		PageReq: comModel.PageReq{
+			PageNum:  1,
+			PageSize: 50,
+		},
+	}
+	var total int
+	for {
+		var (
+			list []*model.SysUserOnline
+			err  error
+		)
+		total, _, list, err = service.Online.GetOnlineListPage(param, true)
+		if err != nil {
+			g.Log().Error(err)
+			break
+		}
+		if list == nil {
+			break
+		}
+		for _, v := range list {
+			if b := c.UserIsOnline(v.Token); !b {
+				service.Online.DeleteOnlineByToken(v.Token)
+			}
+		}
+		if param.PageNum*param.PageSize >= total {
+			break
+		}
+		param.PageNum++
+	}
+}
+
+// UserIsOnline 判断用户是否在线
+func (c *auth) UserIsOnline(token string) bool {
+	uuid, userKey := c.GetUuidUserKeyByToken(token)
+	cacheKey := GfToken.CacheKey + userKey
+	switch GfToken.CacheMode {
+	case gtoken.CacheModeCache:
+		userCacheValue, _ := gcache.Get(cacheKey)
+		if userCacheValue == nil {
+			return false
+		}
+		return true
+	case gtoken.CacheModeRedis:
+		var userCache g.Map
+		userCacheJson, err := g.Redis().Do("GET", cacheKey)
+		if err != nil {
+			g.Log().Error("[GToken]cache get error", err)
+			return false
+		}
+		if userCacheJson == nil {
+			return false
+		}
+		err = gjson.DecodeTo(userCacheJson, &userCache)
+		if err != nil {
+			g.Log().Error("[GToken]cache get json error", err)
+			return false
+		}
+		if uuid != userCache["uuid"] {
+			return false
+		}
+		return true
+	}
+	return false
+}
+
+// GetUuidUserKeyByToken 通过token获取uuid和userKey
+func (c *auth) GetUuidUserKeyByToken(token string) (uuid, userKey string) {
+	decryptToken := GfToken.DecryptToken(token)
+	if !decryptToken.Success() {
+		return
+	}
+	userKey = decryptToken.GetString("userKey")
+	uuid = decryptToken.GetString("uuid")
+	return
+}

+ 158 - 0
app/system/api/sys_auth_rule.go

@@ -0,0 +1,158 @@
+package api
+
+import (
+	"gfast/app/common/global"
+	CommService "gfast/app/common/service"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type authRule struct {
+	systemBase
+}
+
+var AuthRule = new(authRule)
+
+func (c *authRule) MenuList(r *ghttp.Request) {
+
+	var (
+		req          *model.SysAuthRuleReqSearch
+		listEntities []*model.SysAuthRuleInfoRes
+		err          error
+	)
+
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+
+	listEntities, err = service.Rule.GetMenuListSearch(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+
+	list := make([]*model.SysAuthRuleTreeRes, 0, len(listEntities))
+	if !req.IsEmpty() {
+		for _, menu := range listEntities {
+			list = append(list, &model.SysAuthRuleTreeRes{
+				SysAuthRuleInfoRes: menu,
+			})
+		}
+	} else {
+		list = service.Rule.GetMenuListTree(0, listEntities)
+	}
+	c.SusJsonExit(r, g.Map{
+		"list": list,
+	})
+}
+
+func (c *authRule) GetMenus(r *ghttp.Request) {
+	listEntities, err := service.Rule.GetIsMenuList()
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, g.Map{
+		"parentList": listEntities,
+	})
+}
+
+func (c *authRule) AddMenuPost(r *ghttp.Request) {
+	var menu *model.MenuReq
+	if err := r.Parse(&menu); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	//判断菜单规则是否存在
+	if !service.Rule.CheckMenuNameUnique(menu.Name, 0) {
+		c.FailJsonExit(r, "菜单规则名称已经存在")
+	}
+
+	//判断路由是否已经存在
+	if !service.Rule.CheckMenuPathUnique(menu.Path, 0) {
+		c.FailJsonExit(r, "路由地址已经存在")
+	}
+	err, _ := service.Rule.AddMenu(menu)
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, "添加菜单失败")
+	}
+	CommService.Cache.New().RemoveByTag(global.SysAuthTag)
+	c.SusJsonExit(r, "添加菜单成功")
+}
+
+func (c *authRule) ModelOptions(r *ghttp.Request) {
+	module := r.GetString("module")
+	models, err := service.Rule.ModelOptions(module)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+
+	c.SusJsonExit(r, models)
+}
+
+func (c *authRule) GetMenu(r *ghttp.Request) {
+	id := r.GetUint64("menuId")
+	menuEntity, err := service.Rule.One(id)
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, err.Error())
+	}
+	listEntities, err := service.Rule.GetIsMenuList()
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	list := service.Rule.ParentSonSort(listEntities, 0)
+	var models []*model.SysModelInfo
+	if menuEntity.ModuleType != "" {
+		models, err = service.Rule.ModelOptions(menuEntity.ModuleType)
+		if err != nil {
+			c.FailJsonExit(r, err.Error())
+		}
+	}
+	c.SusJsonExit(r, g.Map{
+		"parentList":   list,
+		"menu":         menuEntity,
+		"modelOptions": models,
+	})
+}
+
+func (c *authRule) EditPost(r *ghttp.Request) {
+	id := r.GetInt("menuId")
+	menu := new(model.MenuReq)
+	if err := r.Parse(menu); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	//判断菜单规则是否存在
+	if !service.Rule.CheckMenuNameUnique(menu.Name, id) {
+		c.FailJsonExit(r, "菜单规则名称已经存在")
+	}
+
+	//判断路由是否已经存在
+	if !service.Rule.CheckMenuPathUnique(menu.Path, id) {
+		c.FailJsonExit(r, "路由地址已经存在")
+	}
+
+	err, _ := service.Rule.EditMenu(menu, id)
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, "修改菜单失败")
+	}
+
+	CommService.Cache.New().RemoveByTag(global.SysAuthTag)
+	c.SusJsonExit(r, "修改菜单成功")
+}
+
+func (c *authRule) DeleteMenu(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	if len(ids) == 0 {
+		c.FailJsonExit(r, "删除失败,参数错误")
+	}
+	err := service.Rule.DeleteMenuByIds(ids)
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, "删除失败")
+	}
+	CommService.Cache.New().RemoveByTag(global.SysAuthTag)
+	c.SusJsonExit(r, "删除成功")
+}

+ 18 - 0
app/system/api/sys_base.go

@@ -0,0 +1,18 @@
+package api
+
+import (
+	"context"
+	"gfast/app/common/api"
+	"gfast/app/system/dao"
+	"gfast/app/system/service"
+)
+
+type systemBase struct {
+	api.CommonBase
+}
+
+// GetCurrentUser 获取当前登陆用户信息
+func (c *systemBase) GetCurrentUser(ctx context.Context) *dao.CtxUser {
+	context := service.Context.Get(ctx)
+	return context.User
+}

+ 109 - 0
app/system/api/sys_config.go

@@ -0,0 +1,109 @@
+/*
+* @desc:系统配置
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/5 17:46
+ */
+
+package api
+
+import (
+	"gfast/app/common/global"
+	"gfast/app/common/model"
+	"gfast/app/common/service"
+	commonService "gfast/app/common/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type sysConfig struct {
+	systemBase
+}
+
+var SysConfig = new(sysConfig)
+
+// List 系统参数配置列表
+func (c *sysConfig) List(r *ghttp.Request) {
+	var req *model.SysConfigSearchReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	req.Ctx = r.GetCtx()
+	total, page, list, err := service.SysConfig.SelectListByPage(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+
+	result := g.Map{
+		"currentPage": page,
+		"total":       total,
+		"list":        list,
+	}
+	c.SusJsonExit(r, result)
+}
+
+// Add 添加
+func (c *sysConfig) Add(r *ghttp.Request) {
+	var req *model.SysConfigAddReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	err := service.SysConfig.CheckConfigKeyUniqueAll(req.ConfigKey)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	req.CreateBy = c.GetCurrentUser(r.GetCtx()).GetUserId() //获取登陆用户id
+	err = service.SysConfig.AddSave(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	commonService.Cache.New().Remove(global.SysConfigTag + req.ConfigKey)
+	c.SusJsonExit(r, "添加参数成功")
+}
+
+// Get 获取参数信息
+func (c *sysConfig) Get(r *ghttp.Request) {
+	id := r.GetInt("id")
+	params, err := service.SysConfig.GetById(id)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, params)
+}
+
+// Edit 修改系统参数
+func (c *sysConfig) Edit(r *ghttp.Request) {
+	var req *model.SysConfigEditReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	err := service.SysConfig.CheckConfigKeyUnique(req.ConfigKey, req.ConfigId)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	req.UpdateBy = c.GetCurrentUser(r.Context()).GetUserId()
+	err = service.SysConfig.EditSave(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	commonService.Cache.New().Remove(global.SysConfigTag + req.ConfigKey)
+	c.SusJsonExit(r, "修改参数成功")
+}
+
+// Delete 删除参数
+func (c *sysConfig) Delete(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	if len(ids) == 0 {
+		c.FailJsonExit(r, "删除失败")
+	}
+	err := service.SysConfig.DeleteByIds(ids)
+	if err != nil {
+		c.FailJsonExit(r, "删除失败")
+	}
+	commonService.Cache.New().RemoveByTag(global.SysConfigTag)
+	c.SusJsonExit(r, "删除成功")
+}

+ 124 - 0
app/system/api/sys_dept.go

@@ -0,0 +1,124 @@
+package api
+
+import (
+	"gfast/app/common/global"
+	CommService "gfast/app/common/service"
+	"gfast/app/system/dao"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type dept struct {
+	systemBase
+}
+
+var Dept = new(dept)
+
+// List 部门列表
+func (c *dept) List(r *ghttp.Request) {
+	var searchParams *dao.SysDeptSearchParams
+	if err := r.Parse(&searchParams); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	if list, err := service.Dept.GetList(searchParams); err != nil {
+		c.FailJsonExit(r, err.Error())
+	} else {
+		if list != nil {
+			c.SusJsonExit(r, list)
+		} else {
+			c.SusJsonExit(r, []*model.SysDept{})
+		}
+	}
+}
+
+func (c *dept) Add(r *ghttp.Request) {
+	var addParams *dao.SysDeptAddParams
+	if err := r.Parse(&addParams); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	addParams.CreatedBy = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	if err := service.Dept.AddDept(addParams); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	CommService.Cache.New().RemoveByTag(global.SysAuthTag)
+	c.SusJsonExit(r, "添加成功")
+}
+
+func (c *dept) Get(r *ghttp.Request) {
+	id := r.GetUint64("id")
+	if id == 0 {
+		c.FailJsonExit(r, "参数错误")
+	}
+	if dept, err := service.Dept.GetDeptById(id); err != nil {
+		c.FailJsonExit(r, err.Error())
+	} else {
+		c.SusJsonExit(r, dept)
+	}
+}
+
+func (c *dept) Edit(r *ghttp.Request) {
+	var editParams *dao.EditParams
+	if err := r.Parse(&editParams); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	editParams.UpdatedBy = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	if err := service.Dept.EditDept(editParams); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	CommService.Cache.New().RemoveByTag(global.SysAuthTag)
+	c.SusJsonExit(r, "编辑成功")
+}
+
+func (c *dept) Delete(r *ghttp.Request) {
+	id := r.GetInt64("id")
+	if id == 0 {
+		c.FailJsonExit(r, "删除失败")
+	}
+	err := service.Dept.DelDept(id)
+	if err != nil {
+		c.FailJsonExit(r, "删除失败")
+	}
+	CommService.Cache.New().RemoveByTag(global.SysAuthTag)
+	c.SusJsonExit(r, "删除成功")
+}
+
+func (c *dept) RoleDeptTreeSelect(r *ghttp.Request) {
+	id := r.GetInt64("roleId")
+	if id == 0 {
+		c.FailJsonExit(r, "参数错误")
+	}
+	list, err := service.Dept.GetList(&dao.SysDeptSearchParams{
+		Status: "1",
+	})
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+
+	//获取关联的角色数据权限
+	checkedKeys, err := service.Dept.GetRoleDepts(id)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	dList := service.Dept.GetDeptListTree(0, list)
+	res := g.Map{
+		"depts":       dList,
+		"checkedKeys": checkedKeys,
+	}
+	c.SusJsonExit(r, res)
+}
+
+func (c *dept) TreeSelect(r *ghttp.Request) {
+	//获取正常状态部门数据
+	list, err := service.Dept.GetList(&dao.SysDeptSearchParams{Status: "1"})
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	dList := service.Dept.GetDeptListTree(0, list)
+	res := g.Map{
+		"depts": dList,
+	}
+	c.SusJsonExit(r, res)
+}

+ 119 - 0
app/system/api/sys_dict_data.go

@@ -0,0 +1,119 @@
+/*
+* @desc:字典数据
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/4/3 11:52
+ */
+
+package api
+
+import (
+	"gfast/app/common/global"
+	commonService "gfast/app/common/service"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type dictData struct {
+	systemBase
+}
+
+var DictData = new(dictData)
+
+// List 字典列表
+func (c *dictData) List(r *ghttp.Request) {
+	var req *model.SelectDictPageReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	req.Ctx = r.GetCtx()
+	total, page, list, err := service.SysDictData.DictDataList(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	result := g.Map{
+		"currentPage": page,
+		"total":       total,
+		"list":        list,
+	}
+	c.SusJsonExit(r, result)
+}
+
+// Add 添加字典数据
+func (c *dictData) Add(r *ghttp.Request) {
+	var req *model.DictDataAddReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	req.CreateBy = c.GetCurrentUser(r.GetCtx()).GetUserId() //获取登陆用户id
+	_, err := service.SysDictData.AddSave(req)
+	if err != nil {
+		g.Log().Error(err.Error())
+		c.FailJsonExit(r, "字典数据添加失败")
+	}
+	//清除tag缓存
+	commonService.Cache.New().RemoveByTag(global.SysDictTag)
+	c.SusJsonExit(r, "添加字典数据成功")
+}
+
+// Get 获取字典数据信息
+func (c *dictData) Get(r *ghttp.Request) {
+	dictCode := r.GetInt("dictCode")
+	data, err := service.SysDictData.GetDictDataById(dictCode)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, data)
+}
+
+// Edit 修改字典数据
+func (c *dictData) Edit(r *ghttp.Request) {
+	var req *model.EditDictDataReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	req.UpdateBy = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	err := service.SysDictData.EditSaveData(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	//清除tag缓存
+	commonService.Cache.New().RemoveByTag(global.SysDictTag)
+	c.SusJsonExit(r, "修改字典数据成功")
+}
+
+// Delete 删除字典数据
+func (c *dictData) Delete(r *ghttp.Request) {
+	dictCodes := r.GetInts("ids")
+	if len(dictCodes) == 0 {
+		c.FailJsonExit(r, "删除失败")
+	}
+	err := service.SysDictData.DeleteDictDataByIds(dictCodes)
+	if err != nil {
+		c.FailJsonExit(r, "删除失败")
+	}
+	//清除tag缓存
+	commonService.Cache.New().RemoveByTag(global.SysDictTag)
+	c.SusJsonExit(r, "删除成功")
+}
+
+// GetDictData 获取字典数据
+func (c *dictData) GetDictData(r *ghttp.Request) {
+	var req *model.GetDictReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	req.Ctx = r.GetCtx()
+	dict, err := service.SysDictData.GetDictWithDataByType(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, dict)
+}

+ 96 - 0
app/system/api/sys_dict_type.go

@@ -0,0 +1,96 @@
+package api
+
+import (
+	"gfast/app/common/global"
+	comService "gfast/app/common/service"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type dictType struct {
+	systemBase
+}
+
+var DictType = new(dictType)
+
+func (c *dictType) List(r *ghttp.Request) {
+	var req *model.ListSysDictTypeReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	req.Ctx = r.GetCtx()
+	total, page, list, err := service.SysDictType.SelectList(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, g.Map{
+		"total": total,
+		"page":  page,
+		"list":  list,
+	})
+}
+
+func (c *dictType) Get(r *ghttp.Request) {
+	id := r.GetInt("dictId")
+	entity, err := service.SysDictType.GetDictById(id)
+	if err != nil {
+		c.FailJsonExit(r, "字典数据获取失败")
+	}
+	c.SusJsonExit(r, entity)
+}
+
+func (c *dictType) Add(r *ghttp.Request) {
+	var req *model.SysDictTypeAddReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	if service.SysDictType.ExistsDictType(req.DictType) {
+		c.FailJsonExit(r, "字典类型已经存在")
+	}
+	req.CreateBy = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	err := service.SysDictType.Add(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	//清除缓存
+	comService.Cache.New().RemoveByTag(global.SysDictTag)
+	c.SusJsonExit(r)
+}
+
+func (c *dictType) Edit(r *ghttp.Request) {
+	var req *model.SysDictTypeEditReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	if service.SysDictType.ExistsDictType(req.DictType, req.DictId) {
+		c.FailJsonExit(r, "字典类型已经存在")
+	}
+	ctx := r.GetCtx()
+	req.UpdateBy = c.GetCurrentUser(ctx).Id
+	err := service.SysDictType.Edit(ctx, req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	//清除缓存
+	comService.Cache.New().RemoveByTag(global.SysDictTag)
+	c.SusJsonExit(r)
+}
+
+func (c *dictType) Delete(r *ghttp.Request) {
+	dictIds := r.GetInts("dictIds")
+	if len(dictIds) == 0 {
+		c.FailJsonExit(r, "参数错误")
+	}
+	if err := service.SysDictType.Delete(r.GetCtx(), dictIds); err != nil {
+		c.FailJsonExit(r, "删除失败")
+	}
+	//清除缓存
+	comService.Cache.New().RemoveByTag(global.SysDictTag)
+	c.SusJsonExit(r)
+}

+ 116 - 0
app/system/api/sys_job.go

@@ -0,0 +1,116 @@
+/*
+* @desc:定时任务
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/14 9:02
+ */
+
+package api
+
+import (
+	"gfast/app/system/dao"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type sysJob struct {
+	systemBase
+}
+
+var SysJob = new(sysJob)
+
+// List 任务列表
+func (c *sysJob) List(r *ghttp.Request) {
+	var req *dao.SysJobSearchReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	total, page, list, err := service.SysJob.JobList(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	result := g.Map{
+		"currentPage": page,
+		"total":       total,
+		"list":        list,
+	}
+	c.SusJsonExit(r, result)
+}
+
+func (c *sysJob) Add(r *ghttp.Request) {
+	var req *dao.SysJobAddReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	req.CreateBy = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	err := service.SysJob.AddJob(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "任务添加成功")
+}
+
+func (c *sysJob) Get(r *ghttp.Request) {
+	id := r.GetInt64("id")
+	job, err := service.SysJob.GetJobInfoById(id)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, job)
+}
+
+func (c *sysJob) Edit(r *ghttp.Request) {
+	var req *dao.SysJobEditReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	req.UpdateBy = c.GetCurrentUser(r.GetCtx()).GetUserId() //获取登陆用户id
+	err := service.SysJob.EditJob(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "修改任务成功")
+}
+
+// Start 启动任务
+func (c *sysJob) Start(r *ghttp.Request) {
+	id := r.GetInt64("id")
+	job, err := service.SysJob.GetJobInfoById(id)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	err = service.SysJob.JobStart(job)
+	if err != nil {
+		c.FailJsonExit(r, "定时任务管理启动"+err.Error())
+	}
+	c.SusJsonExit(r, "定时任务管理启动成功")
+}
+
+// Stop 停止任务
+func (c *sysJob) Stop(r *ghttp.Request) {
+	id := r.GetInt64("id")
+	job, err := service.SysJob.GetJobInfoById(id)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	err = service.SysJob.JobStop(job)
+	if err != nil {
+		c.FailJsonExit(r, "定时任务管理停止"+err.Error())
+	}
+	c.SusJsonExit(r, "定时任务管理停止成功")
+}
+
+// Delete 删除任务
+func (c *sysJob) Delete(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	err := service.SysJob.DeleteJobByIds(ids)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "删除成功")
+}

+ 60 - 0
app/system/api/sys_login_log.go

@@ -0,0 +1,60 @@
+/*
+* @desc:登录日志
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/19 10:21
+ */
+
+package api
+
+import (
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type sysLoginLog struct {
+	systemBase
+}
+
+var SysLoginLog = new(sysLoginLog)
+
+// List 获取日志列表
+func (c sysLoginLog) List(r *ghttp.Request) {
+	var req *model.SysLoginLogSearchReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	total, page, list, err := service.SysLoginLog.LoginLogListByPage(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	result := g.Map{
+		"currentPage": page,
+		"total":       total,
+		"list":        list,
+	}
+	c.SusJsonExit(r, result)
+}
+
+// Delete 删除日志
+func (c *sysLoginLog) Delete(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	err := service.SysLoginLog.DeleteLoginLogByIds(ids)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "删除成功")
+}
+
+// Clear 清空日志
+func (c *sysLoginLog) Clear(r *ghttp.Request) {
+	err := service.SysLoginLog.ClearLoginLog()
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "清除成功")
+}

+ 150 - 0
app/system/api/sys_monitor.go

@@ -0,0 +1,150 @@
+/*
+* @desc:系统服务信息
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/19 9:03
+ */
+
+package api
+
+import (
+	"fmt"
+	"gfast/library"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/os/gtime"
+	"github.com/gogf/gf/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"
+	"os"
+	"runtime"
+	"strconv"
+	"time"
+)
+
+type sysMonitor struct {
+	systemBase
+	startTime *gtime.Time
+}
+
+var SysMonitor = &sysMonitor{
+	startTime: gtime.Now(),
+}
+
+// Info 服务监控信息
+func (c *sysMonitor) Info(r *ghttp.Request) {
+	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 := library.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 := g.Map{
+		"cpuNum":          cpuNum,
+		"cpuUsed":         cpuUsed,
+		"cpuAvg5":         cpuAvg5,
+		"cpuAvg15":        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,
+	}
+	c.SusJsonExit(r, res)
+}

+ 110 - 0
app/system/api/sys_oper_log.go

@@ -0,0 +1,110 @@
+/*
+* @desc:操作日志管理
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/19 14:50
+ */
+
+package api
+
+import (
+	"gfast/app/system/dao"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"gfast/library"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/text/gstr"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type sysOperLog struct {
+	systemBase
+}
+
+var SysOperLog = new(sysOperLog)
+
+// List 操作日志列表
+func (c *sysOperLog) List(r *ghttp.Request) {
+	var req *dao.SysOperLogSearchReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	total, page, list, err := service.SysOperLog.OperationLogListByPage(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	result := g.Map{
+		"currentPage": page,
+		"total":       total,
+		"list":        list,
+	}
+	c.SusJsonExit(r, result)
+}
+
+// Detail 日志详细
+func (c *sysOperLog) Detail(r *ghttp.Request) {
+	id := r.GetInt64("id")
+	log, err := service.SysOperLog.GetOperationLogById(id)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, g.Map{
+		"info": log,
+	})
+}
+
+// Delete 删除
+func (c *sysOperLog) Delete(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	err := service.SysOperLog.DeleteOperationLogByIds(ids)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "删除成功")
+}
+
+// Clear 清空
+func (c *sysOperLog) Clear(r *ghttp.Request) {
+	err := service.SysOperLog.ClearOperationLog()
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "清除成功")
+}
+
+// OperationLog 操作日志记录
+func (c *sysOperLog) OperationLog(r *ghttp.Request) {
+	user := c.GetCurrentUser(r.GetCtx())
+	if user == nil {
+		return
+	}
+	url := r.Request.URL //请求地址
+	//获取菜单
+	//获取地址对应的菜单id
+	menuList, err := service.Rule.GetMenuList()
+	if err != nil {
+		g.Log().Error(err)
+		return
+	}
+	var menu *model.SysAuthRuleInfoRes
+	path := gstr.TrimLeft(url.Path, "/")
+	for _, m := range menuList {
+		if gstr.Equal(m.Name, path) {
+			menu = m
+			break
+		}
+	}
+
+	data := &dao.SysOperLogAdd{
+		User:         user,
+		Menu:         menu,
+		Url:          url,
+		Params:       r.GetMap(),
+		Method:       r.Method,
+		ClientIp:     library.GetClientIp(r),
+		OperatorType: 1,
+	}
+	service.SysOperLog.Invoke(data)
+}

+ 88 - 0
app/system/api/sys_post.go

@@ -0,0 +1,88 @@
+/*
+* @desc:岗位管理
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/12 10:32
+ */
+
+package api
+
+import (
+	"gfast/app/system/dao"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type sysPost struct {
+	systemBase
+}
+
+var SysPost = new(sysPost)
+
+func (c *sysPost) List(r *ghttp.Request) {
+	var req *dao.SysPostSearchParams
+
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	total, page, list, err := service.SysPost.List(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	result := g.Map{
+		"total": total,
+		"list":  list,
+		"page":  page,
+	}
+	c.SusJsonExit(r, result)
+}
+
+func (c *sysPost) Add(r *ghttp.Request) {
+	var addParams *dao.SysPostAddParams
+	if err := r.Parse(&addParams); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	addParams.CreatedBy = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	if err := service.SysPost.Add(addParams); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "添加成功")
+}
+
+func (c *sysPost) Get(r *ghttp.Request) {
+	id := r.GetInt64("id")
+	if id == 0 {
+		c.FailJsonExit(r, "id必须")
+	}
+	if post, err := service.SysPost.GetOneById(id); err != nil {
+		c.FailJsonExit(r, err.Error())
+	} else {
+		c.SusJsonExit(r, post)
+	}
+}
+
+func (c *sysPost) Edit(r *ghttp.Request) {
+	var editParams *dao.SysPostEditParams
+	if err := r.Parse(&editParams); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	editParams.UpdatedBy = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	if err := service.SysPost.Edit(editParams); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "修改成功")
+}
+
+func (c *sysPost) Delete(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	if len(ids) == 0 {
+		c.FailJsonExit(r, "删除失败")
+	}
+	err := service.SysPost.Delete(ids)
+	if err != nil {
+		c.FailJsonExit(r, "删除失败")
+	}
+	c.SusJsonExit(r, "删除信息成功")
+}

+ 138 - 0
app/system/api/sys_role.go

@@ -0,0 +1,138 @@
+package api
+
+import (
+	"gfast/app/common/global"
+	CommService "gfast/app/common/service"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type sysRole struct {
+	systemBase
+}
+
+var SysRole = new(sysRole)
+
+// RoleList 角色列表
+func (c *sysRole) RoleList(r *ghttp.Request) {
+	var req *model.SelectPageReq
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	total, page, list, err := service.SysRole.GetRoleListSearch(req)
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, "获取数据失败")
+	}
+	c.SusJsonExit(r, g.Map{
+		"currentPage": page,
+		"total":       total,
+		"list":        list,
+	})
+}
+
+// GetRoleMenu GetRole 新增角色
+func (c *sysRole) GetRoleMenu(r *ghttp.Request) {
+	mListEntities, err := service.Rule.GetMenuList()
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, "获取数据失败")
+	}
+	mList := service.Rule.GetMenuListTree(0, mListEntities)
+	res := g.Map{
+		"menuList": mList,
+	}
+	c.SusJsonExit(r, res)
+}
+
+// AddRole 新增角色提交
+func (c *sysRole) AddRole(r *ghttp.Request) {
+	res := r.GetFormMap()
+	if err := service.SysRole.AddRolePost(res); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "添加角色成功")
+}
+
+// 获取修改的角色
+func (c *sysRole) GetRole(r *ghttp.Request) {
+	id := r.GetRequestInt("roleId")
+	//获取角色信息
+	role, err := service.SysRole.One(id)
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, "获取角色数据失败")
+	}
+	//获取菜单信息
+	mListEntities, err := service.Rule.GetMenuList()
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, "获取菜单数据失败")
+	}
+	mList := service.Rule.GetMenuListTree(0, mListEntities)
+	//获取角色关联的菜单规则
+	gpSlice, err := service.SysRole.GetFilteredNamedPolicy(id)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, g.Map{
+		"menuList":     mList,
+		"role":         role,
+		"checkedRules": gpSlice,
+	})
+}
+
+// EditRole 编辑角色提交
+func (c *sysRole) EditRole(r *ghttp.Request) {
+	id := r.GetRequestInt("roleId")
+	res := r.GetFormMap()
+	if err := service.SysRole.EditRolePost(res, id); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "修改角色成功")
+}
+
+// StatusSetRole 设置角色状态
+func (c *sysRole) StatusSetRole(r *ghttp.Request) {
+	var req *model.StatusSetReq
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	err := service.SysRole.StatusSetRole(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "状态设置成功")
+}
+
+// RoleDataScope 角色数据权限分配
+func (c *sysRole) RoleDataScope(r *ghttp.Request) {
+	var req *model.DataScopeReq
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).Current().Error())
+	}
+	err := service.SysRole.RoleDataScope(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	CommService.Cache.New().RemoveByTag(global.SysAuthTag)
+	c.SusJsonExit(r, req)
+}
+
+// DeleteRole 删除角色
+func (c *sysRole) DeleteRole(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	if len(ids) == 0 {
+		c.FailJsonExit(r, "删除失败,参数错误")
+	}
+	err := service.SysRole.DeleteByIds(ids)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	CommService.Cache.New().RemoveByTag(global.SysAuthTag)
+	c.SusJsonExit(r, "删除成功")
+
+}

+ 233 - 0
app/system/api/sys_user.go

@@ -0,0 +1,233 @@
+package api
+
+import (
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gconv"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type user struct {
+	systemBase
+}
+
+var User = new(user)
+
+// UserList 获取用户列表
+func (c *user) UserList(r *ghttp.Request) {
+	var req *model.SysUserSearchReq
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+
+	if err := service.SysUser.WriteDeptIdsOfSearchReq(req); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+
+	total, page, userList, err := service.SysUser.GetUserList(req)
+	if err != nil {
+		c.FailJsonExit(r, "获取用户列表数据失败")
+	}
+
+	users, err := service.SysUser.GetUsersRoleDept(userList)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+
+	c.SusJsonExit(r, g.Map{
+		"total":       total,
+		"currentPage": page,
+		"userList":    users,
+	})
+}
+
+// Get 获取添加用户信息
+func (c *user) Get(r *ghttp.Request) {
+	roleListEntities, err := service.SysRole.GetRoleList()
+	if err != nil {
+		g.Log().Error(err)
+		c.FailJsonExit(r, "获取角色数据失败")
+	}
+	posts, err := service.SysUser.GetUsedPost()
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, g.Map{
+		"roleList": roleListEntities,
+		"posts":    posts,
+	})
+}
+
+// AddUser 添加用户提交
+func (c *user) AddUser(r *ghttp.Request) {
+	var req *model.AddUserReq
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	err := service.SysUser.AddUser(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "添加管理员成功")
+}
+
+// GetEditUser 获取编辑的用户
+func (c *user) GetEditUser(r *ghttp.Request) {
+	id := r.GetUint64("id")
+	res, err := service.SysUser.GetEditUser(id)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, res)
+}
+
+// EditUser 编辑用户提交
+func (c *user) EditUser(r *ghttp.Request) {
+	var req *model.EditUserReq
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	err := service.SysUser.EditUser(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "修改管理员成功")
+}
+
+// GetInfo 获取登陆用户信息
+func (c *user) GetInfo(r *ghttp.Request) {
+	userInfo := c.GetCurrentUser(r.Context())
+	rolesList := make([]string, 0, 10)
+	var permissions []string
+	userId := userInfo.Id
+	allRoles, err := service.SysRole.GetRoleList()
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	roles, err := service.SysUser.GetAdminRole(userId, allRoles)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	name := make([]string, len(roles))
+	roleIds := make([]uint, len(roles))
+	for k, v := range roles {
+		name[k] = v.Name
+		roleIds[k] = v.Id
+	}
+	isSuperAdmin := false
+	service.SysUser.NotCheckAuthAdminIds.Iterator(func(v interface{}) bool {
+		if gconv.Uint64(v) == userId {
+			isSuperAdmin = true
+			return false
+		}
+		return true
+	})
+	if isSuperAdmin {
+		permissions = []string{"*/*/*"}
+	} else {
+		permissions, err = service.SysUser.GetPermissions(roleIds)
+	}
+	rolesList = name
+	c.SusJsonExit(r, g.Map{
+		"user":        userInfo,
+		"roles":       rolesList,
+		"permissions": permissions,
+	})
+}
+
+// GetRouters 获取用户菜单
+func (c *user) GetRouters(r *ghttp.Request) {
+	//获取用户信息
+	userInfo := c.GetCurrentUser(r.Context())
+	//是否超管
+	isSuperAdmin := false
+	userId := userInfo.Id
+	//获取无需验证权限的用户id
+	service.SysUser.NotCheckAuthAdminIds.Iterator(func(v interface{}) bool {
+		if gconv.Uint64(v) == userId {
+			isSuperAdmin = true
+			return false
+		}
+		return true
+	})
+	//获取用户角色信息
+	allRoles, err := service.SysRole.GetRoleList()
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	roles, e := service.SysUser.GetAdminRole(userId, allRoles)
+	if e != nil {
+		c.FailJsonExit(r, e.Error())
+	}
+	name := make([]string, len(roles))
+	roleIds := make([]uint, len(roles))
+	for k, v := range roles {
+		name[k] = v.Name
+		roleIds[k] = v.Id
+	}
+	var menuList []service.UserMenus
+	//获取菜单信息
+	if isSuperAdmin {
+		//超管获取所有菜单
+		menuList, err = service.SysUser.GetAllMenus()
+	} else {
+		menuList, err = service.SysUser.GetAdminMenusByRoleIds(roleIds)
+	}
+	if err != nil {
+		c.FailJsonExit(r, e.Error())
+	}
+	if menuList == nil {
+		menuList = make([]service.UserMenus, 0)
+	}
+	adminMenus := make([]service.UserMenus, 0, len(menuList))
+	//过滤非后台模块的菜单
+	for _, v := range menuList {
+		if v.ModuleType == "sys_admin" {
+			adminMenus = append(adminMenus, v)
+		}
+	}
+	c.SusJsonExit(r, adminMenus)
+}
+
+func (c *user) ResetUserPwd(r *ghttp.Request) {
+	var req *model.SysUserResetPwdReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	if err := service.SysUser.ResetUserPwd(req); err != nil {
+		c.FailJsonExit(r, err.Error())
+	} else {
+		c.SusJsonExit(r, "用户密码重置成功")
+	}
+}
+
+func (c *user) ChangeUserStatus(r *ghttp.Request) {
+	var req *model.SysUserStatusReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	if err := service.SysUser.ChangeUserStatus(req); err != nil {
+		c.FailJsonExit(r, err.Error())
+	} else {
+		c.SusJsonExit(r, "用户状态设置成功")
+	}
+}
+
+func (c *user) DeleteUser(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	if len(ids) > 0 {
+		err := service.SysUser.DeleteUser(r.GetCtx(), ids)
+		if err != nil {
+			g.Log().Error(err)
+			c.FailJsonExit(r, "删除失败")
+		}
+	} else {
+		c.FailJsonExit(r, "删除失败,参数错误")
+	}
+
+	c.SusJsonExit(r, "删除成功")
+}

+ 57 - 0
app/system/api/sys_user_online.go

@@ -0,0 +1,57 @@
+/*
+* @desc:在线用户管理
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/13 15:10
+ */
+
+package api
+
+import (
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type sysUserOnline struct {
+	systemBase
+}
+
+var SysUserOnline = new(sysUserOnline)
+
+// List 在线用户列表
+func (c *sysUserOnline) List(r *ghttp.Request) {
+	var req *model.SysUserOnlineSearchReq
+	//获取参数
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	total, page, list, err := service.Online.GetOnlineListPage(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	result := g.Map{
+		"currentPage": page,
+		"total":       total,
+		"list":        list,
+	}
+	c.SusJsonExit(r, result)
+}
+
+// ForceLogout 强退用户
+func (c *sysUserOnline) ForceLogout(r *ghttp.Request) {
+	ids := r.GetInts("ids")
+	if len(ids) == 0 {
+		c.FailJsonExit(r, "参数错误")
+	}
+	tokens, err := service.Online.ForceLogout(ids)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	for _, token := range tokens {
+		GfToken.RemoveToken(token)
+	}
+	c.SusJsonExit(r, "用户已退出")
+}

+ 45 - 0
app/system/api/sys_web_set.go

@@ -0,0 +1,45 @@
+/*
+* @desc:站点设置
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/6 15:41
+ */
+
+package api
+
+import (
+	"gfast/app/common/global"
+	commonService "gfast/app/common/service"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type sysWebSet struct {
+	systemBase
+}
+
+var SysWebSet = new(sysWebSet)
+
+func (c *sysWebSet) Update(r *ghttp.Request) {
+	var req *model.SysWebSetUpdateReq
+	err := r.Parse(&req)
+	if err != nil {
+		c.FailJson(true, r, err.(gvalid.Error).FirstString())
+	}
+	err = service.SysWebSet.UpdateSave(req)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	commonService.Cache.New().Remove(global.SysWebSet)
+	c.SusJsonExit(r, "更新成功!")
+}
+
+func (c *sysWebSet) Get(r *ghttp.Request) {
+	data, err := service.SysWebSet.Get()
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, data)
+}

+ 33 - 0
app/system/api/upload.go

@@ -0,0 +1,33 @@
+/*
+* @desc:后台上传
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/7 15:10
+ */
+
+package api
+
+import (
+	"gfast/app/common/adapter"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+)
+
+type upload struct {
+	systemBase
+}
+
+var Upload = new(upload)
+
+// UpImg 单图上传
+func (c *upload) UpImg(r *ghttp.Request) {
+	upFile := r.GetUploadFile("file")
+	info, err := adapter.Upload.UpImg(upFile)
+	if err != nil {
+		c.FailJsonExit(r, "上传失败,"+err.Error())
+	}
+	res := g.Map{
+		"fileInfo": info,
+	}
+	c.SusJsonExit(r, res)
+}

+ 82 - 0
app/system/api/user_Profile.go

@@ -0,0 +1,82 @@
+/*
+* @desc:个人中心
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/7/12 22:14
+ */
+
+package api
+
+import (
+	"gfast/app/common/adapter"
+	"gfast/app/system/model"
+	"gfast/app/system/service"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+	"github.com/gogf/gf/util/gvalid"
+)
+
+type userProfile struct {
+	systemBase
+}
+
+var UserProfile = new(userProfile)
+
+// Profile 获取个人信息
+func (c *userProfile) Profile(r *ghttp.Request) {
+	//获取用户信息
+	user, err := service.SysUser.GetUserInfoById(c.GetCurrentUser(r.GetCtx()).GetUserId())
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	userInfo, err := service.SysUser.GetUserRoleDeptPost(user)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, userInfo)
+}
+
+// Avatar 修改头像
+func (c *userProfile) Avatar(r *ghttp.Request) {
+	upFile := r.GetUploadFile("avatarfile")
+	info, err := adapter.Upload.UpImg(upFile)
+	if err != nil {
+		c.FailJsonExit(r, "上传失败,"+err.Error())
+	}
+	res := g.Map{
+		"fileInfo": info,
+	}
+	userId := c.GetCurrentUser(r.GetCtx()).GetUserId()
+	err = service.SysUser.SetAvatar(userId, info.FileUrl)
+	if err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, res)
+}
+
+// Edit 修改个人信息
+func (c *userProfile) Edit(r *ghttp.Request) {
+	var req *model.ProfileUpReq
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	req.UserId = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	if err := service.SysUser.ProfileEdit(req); err != nil {
+		c.FailJsonExit(r, err.Error())
+	}
+	c.SusJsonExit(r, "修改成功")
+}
+
+// UpdatePwd 修改密码
+func (c *userProfile) UpdatePwd(r *ghttp.Request) {
+	var req *model.ProfileUpdatePwdReq
+	if err := r.Parse(&req); err != nil {
+		c.FailJsonExit(r, err.(gvalid.Error).FirstString())
+	}
+	req.UserId = c.GetCurrentUser(r.GetCtx()).GetUserId()
+	if err := service.SysUser.ProfileUpdatePwd(req); err != nil {
+		c.FailJsonExit(r, err.Error())
+	} else {
+		c.SusJsonExit(r, "修改成功")
+	}
+}

+ 0 - 0
app/system/dao/.gitkeep


+ 41 - 0
app/system/dao/context.go

@@ -0,0 +1,41 @@
+package dao
+
+import (
+	"gfast/app/system/model"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+)
+
+const (
+	// CtxKey 上下文变量存储键名,前后端系统共享
+	CtxKey = "GFastContext"
+)
+
+// Context 请求上下文结构
+type Context struct {
+	Session *ghttp.Session // 当前Session管理对象
+	User    *CtxUser       // 上下文用户信息
+	Data    g.Map          // 自定KV变量,业务模块根据需要设置,不固定
+}
+
+// CtxUser 请求上下文中的用户信息
+type CtxUser struct {
+	Id           uint64 `json:"id"`           // 用户id
+	UserName     string `json:"userName"`     // 用户名
+	DeptId       uint64 `json:"deptId"`       // 部门id
+	UserNickname string `json:"userNickname"` // 用户昵称
+	UserStatus   uint   `json:"userStatus"`   // 用户状态;0:禁用,1:正常,2:未验证
+	IsAdmin      int    `json:"isAdmin"`      // 是否后台管理员 1 是  0   否
+	Avatar       string `json:"avatar"`       //头像
+}
+
+// GetUserId 获取登录用户id
+func (ctxUser *CtxUser) GetUserId() (id uint64) {
+	return ctxUser.Id
+}
+
+// GetDept 获取登录用户所属部门
+func (ctxUser *CtxUser) GetDept() (err error, dept *model.SysDept) {
+	err = g.DB().Model(SysDept.Table).WherePri(ctxUser.DeptId).Scan(&dept)
+	return
+}

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

@@ -0,0 +1,420 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"database/sql"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+)
+
+// SysAuthRuleDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysAuthRuleDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns sysAuthRuleColumns
+}
+
+// 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 // 权重
+	Status     string // 状态
+	AlwaysShow string // 显示状态
+	Path       string // 路由地址
+	JumpPath   string // 跳转路由
+	Component  string // 组件路径
+	IsFrame    string // 是否外链 1是 0否
+	ModuleType string // 所属模块
+	ModelId    string // 模型ID
+	CreatedAt  string // 创建日期
+	UpdatedAt  string // 修改日期
+	DeletedAt  string // 删除日期
+}
+
+var (
+	// SysAuthRule is globally public accessible object for table sys_auth_rule operations.
+	SysAuthRule = SysAuthRuleDao{
+		M:     g.DB("default").Model("sys_auth_rule").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_auth_rule",
+		Columns: sysAuthRuleColumns{
+			Id:         "id",
+			Pid:        "pid",
+			Name:       "name",
+			Title:      "title",
+			Icon:       "icon",
+			Condition:  "condition",
+			Remark:     "remark",
+			MenuType:   "menu_type",
+			Weigh:      "weigh",
+			Status:     "status",
+			AlwaysShow: "always_show",
+			Path:       "path",
+			JumpPath:   "jump_path",
+			Component:  "component",
+			IsFrame:    "is_frame",
+			ModuleType: "module_type",
+			ModelId:    "model_id",
+			CreatedAt:  "created_at",
+			UpdatedAt:  "updated_at",
+			DeletedAt:  "deleted_at",
+		},
+	}
+)
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *SysAuthRuleDao) Ctx(ctx context.Context) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *SysAuthRuleDao) As(as string) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *SysAuthRuleDao) TX(tx *gdb.TX) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *SysAuthRuleDao) Master() *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *SysAuthRuleDao) Slave() *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *SysAuthRuleDao) Args(args ...interface{}) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysAuthRuleDao) LeftJoin(table ...string) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysAuthRuleDao) RightJoin(table ...string) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysAuthRuleDao) InnerJoin(table ...string) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysAuthRuleDao) Fields(fieldNamesOrMapStruct ...interface{}) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysAuthRuleDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *SysAuthRuleDao) Option(option int) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *SysAuthRuleDao) OmitEmpty() *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *SysAuthRuleDao) Filter() *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *SysAuthRuleDao) Where(where interface{}, args ...interface{}) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *SysAuthRuleDao) WherePri(where interface{}, args ...interface{}) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *SysAuthRuleDao) And(where interface{}, args ...interface{}) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *SysAuthRuleDao) Or(where interface{}, args ...interface{}) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *SysAuthRuleDao) Group(groupBy string) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *SysAuthRuleDao) Order(orderBy ...string) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *SysAuthRuleDao) Limit(limit ...int) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *SysAuthRuleDao) Offset(offset int) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *SysAuthRuleDao) Page(page, limit int) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *SysAuthRuleDao) Batch(batch int) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *SysAuthRuleDao) Cache(duration time.Duration, name ...string) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *SysAuthRuleDao) Data(data ...interface{}) *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.SysAuthRule.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysAuthRuleDao) All(where ...interface{}) ([]*model.SysAuthRule, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysAuthRule
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.SysAuthRule.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysAuthRuleDao) One(where ...interface{}) (*model.SysAuthRule, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysAuthRule
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *SysAuthRuleDao) FindOne(where ...interface{}) (*model.SysAuthRule, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysAuthRule
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *SysAuthRuleDao) FindAll(where ...interface{}) ([]*model.SysAuthRule, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysAuthRule
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *SysAuthRuleDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *SysAuthRuleDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *SysAuthRuleDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *SysAuthRuleDao) Chunk(limit int, callback func(entities []*model.SysAuthRule, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*model.SysAuthRule
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *SysAuthRuleDao) LockUpdate() *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *SysAuthRuleDao) LockShared() *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *SysAuthRuleDao) Unscoped() *SysAuthRuleDao {
+	return &SysAuthRuleDao{M: d.M.Unscoped()}
+}

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

@@ -0,0 +1,65 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysDeptDao is the manager for logic model data accessing and custom defined data operations functions management.
+type SysDeptDao struct {
+	gmvc.M                // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	C      sysDeptColumns // C is the short type for Columns, which contains all the column names of Table for convenient usage.
+	DB     gdb.DB         // DB is the raw underlying database management object.
+	Table  string         // Table is the underlying table name of the DAO.
+}
+
+// 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停用)
+	DelFlag   string // 删除标志(0代表存在 2代表删除)
+	CreatedBy string // 创建人
+	UpdatedBy string // 修改人
+	CreatedAt string // 创建时间
+	UpdatedAt string // 修改时间
+	DeletedAt string // 删除时间
+}
+
+// NewSysDeptDao creates and returns a new DAO object for table data access.
+func NewSysDeptDao() *SysDeptDao {
+	columns := sysDeptColumns{
+		DeptId:    "dept_id",
+		ParentId:  "parent_id",
+		Ancestors: "ancestors",
+		DeptName:  "dept_name",
+		OrderNum:  "order_num",
+		Leader:    "leader",
+		Phone:     "phone",
+		Email:     "email",
+		Status:    "status",
+		DelFlag:   "del_flag",
+		CreatedBy: "created_by",
+		UpdatedBy: "updated_by",
+		CreatedAt: "created_at",
+		UpdatedAt: "updated_at",
+		DeletedAt: "deleted_at",
+	}
+	return &SysDeptDao{
+		C:     columns,
+		M:     g.DB("default").Model("sys_dept").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_dept",
+	}
+}

+ 411 - 0
app/system/dao/internal/sys_dict_data.go

@@ -0,0 +1,411 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+
+	"gfast/app/system/model"
+)
+
+// SysDictDataDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysDictDataDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns sysDictDataColumns
+}
+
+// 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 // 修改时间
+	DeletedAt string // 删除时间
+}
+
+var (
+	// SysDictData is globally public accessible object for table sys_dict_data operations.
+	SysDictData = SysDictDataDao{
+		M:     g.DB("default").Model("sys_dict_data").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_dict_data",
+		Columns: 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",
+			DeletedAt: "deleted_at",
+		},
+	}
+)
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *SysDictDataDao) Ctx(ctx context.Context) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *SysDictDataDao) As(as string) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *SysDictDataDao) TX(tx *gdb.TX) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *SysDictDataDao) Master() *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *SysDictDataDao) Slave() *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *SysDictDataDao) Args(args ...interface{}) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysDictDataDao) LeftJoin(table ...string) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysDictDataDao) RightJoin(table ...string) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysDictDataDao) InnerJoin(table ...string) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysDictDataDao) Fields(fieldNamesOrMapStruct ...interface{}) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysDictDataDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *SysDictDataDao) Option(option int) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *SysDictDataDao) OmitEmpty() *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *SysDictDataDao) Filter() *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *SysDictDataDao) Where(where interface{}, args ...interface{}) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *SysDictDataDao) WherePri(where interface{}, args ...interface{}) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *SysDictDataDao) And(where interface{}, args ...interface{}) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *SysDictDataDao) Or(where interface{}, args ...interface{}) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *SysDictDataDao) Group(groupBy string) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *SysDictDataDao) Order(orderBy ...string) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *SysDictDataDao) Limit(limit ...int) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *SysDictDataDao) Offset(offset int) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *SysDictDataDao) Page(page, limit int) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *SysDictDataDao) Batch(batch int) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *SysDictDataDao) Cache(duration time.Duration, name ...string) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *SysDictDataDao) Data(data ...interface{}) *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.SysDictData.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysDictDataDao) All(where ...interface{}) ([]*model.SysDictData, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysDictData
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.SysDictData.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysDictDataDao) One(where ...interface{}) (*model.SysDictData, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysDictData
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *SysDictDataDao) FindOne(where ...interface{}) (*model.SysDictData, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysDictData
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *SysDictDataDao) FindAll(where ...interface{}) ([]*model.SysDictData, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysDictData
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *SysDictDataDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *SysDictDataDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *SysDictDataDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *SysDictDataDao) Chunk(limit int, callback func(entities []*model.SysDictData, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*model.SysDictData
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *SysDictDataDao) LockUpdate() *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *SysDictDataDao) LockShared() *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *SysDictDataDao) Unscoped() *SysDictDataDao {
+	return &SysDictDataDao{M: d.M.Unscoped()}
+}

+ 401 - 0
app/system/dao/internal/sys_dict_type.go

@@ -0,0 +1,401 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+
+	"gfast/app/system/model"
+)
+
+// SysDictTypeDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysDictTypeDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns sysDictTypeColumns
+}
+
+// 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 // 修改日期
+	DeletedAt string // 删除日期
+}
+
+var (
+	// SysDictType is globally public accessible object for table sys_dict_type operations.
+	SysDictType = SysDictTypeDao{
+		M:     g.DB("default").Model("sys_dict_type").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_dict_type",
+		Columns: 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",
+			DeletedAt: "deleted_at",
+		},
+	}
+)
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *SysDictTypeDao) Ctx(ctx context.Context) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *SysDictTypeDao) As(as string) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *SysDictTypeDao) TX(tx *gdb.TX) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *SysDictTypeDao) Master() *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *SysDictTypeDao) Slave() *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *SysDictTypeDao) Args(args ...interface{}) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysDictTypeDao) LeftJoin(table ...string) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysDictTypeDao) RightJoin(table ...string) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysDictTypeDao) InnerJoin(table ...string) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysDictTypeDao) Fields(fieldNamesOrMapStruct ...interface{}) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysDictTypeDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *SysDictTypeDao) Option(option int) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *SysDictTypeDao) OmitEmpty() *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *SysDictTypeDao) Filter() *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *SysDictTypeDao) Where(where interface{}, args ...interface{}) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *SysDictTypeDao) WherePri(where interface{}, args ...interface{}) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *SysDictTypeDao) And(where interface{}, args ...interface{}) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *SysDictTypeDao) Or(where interface{}, args ...interface{}) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *SysDictTypeDao) Group(groupBy string) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *SysDictTypeDao) Order(orderBy ...string) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *SysDictTypeDao) Limit(limit ...int) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *SysDictTypeDao) Offset(offset int) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *SysDictTypeDao) Page(page, limit int) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *SysDictTypeDao) Batch(batch int) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *SysDictTypeDao) Cache(duration time.Duration, name ...string) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *SysDictTypeDao) Data(data ...interface{}) *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.SysDictType.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysDictTypeDao) All(where ...interface{}) ([]*model.SysDictType, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysDictType
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.SysDictType.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysDictTypeDao) One(where ...interface{}) (*model.SysDictType, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysDictType
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *SysDictTypeDao) FindOne(where ...interface{}) (*model.SysDictType, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysDictType
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *SysDictTypeDao) FindAll(where ...interface{}) ([]*model.SysDictType, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysDictType
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *SysDictTypeDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *SysDictTypeDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *SysDictTypeDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *SysDictTypeDao) Chunk(limit int, callback func(entities []*model.SysDictType, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*model.SysDictType
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *SysDictTypeDao) LockUpdate() *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *SysDictTypeDao) LockShared() *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *SysDictTypeDao) Unscoped() *SysDictTypeDao {
+	return &SysDictTypeDao{M: d.M.Unscoped()}
+}

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

@@ -0,0 +1,65 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysJobDao is the manager for logic model data accessing and custom defined data operations functions management.
+type SysJobDao struct {
+	gmvc.M               // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	C      sysJobColumns // C is the short type for Columns, which contains all the column names of Table for convenient usage.
+	DB     gdb.DB        // DB is the raw underlying database management object.
+	Table  string        // Table is the underlying table name of the DAO.
+}
+
+// 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 // 计划执行策略(1多次执行 2执行一次)
+	Concurrent     string // 是否并发执行(0允许 1禁止)
+	Status         string // 状态(0正常 1暂停)
+	CreateBy       string // 创建者
+	UpdateBy       string // 更新者
+	Remark         string // 备注信息
+	CreatedAt      string // 创建时间
+	UpdatedAt      string // 更新时间
+	DeletedAt      string // 删除时间
+}
+
+// NewSysJobDao creates and returns a new DAO object for table data access.
+func NewSysJobDao() *SysJobDao {
+	columns := 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",
+		CreateBy:       "create_by",
+		UpdateBy:       "update_by",
+		Remark:         "remark",
+		CreatedAt:      "created_at",
+		UpdatedAt:      "updated_at",
+		DeletedAt:      "deleted_at",
+	}
+	return &SysJobDao{
+		C:     columns,
+		M:     g.DB("default").Model("sys_job").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_job",
+	}
+}

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

@@ -0,0 +1,400 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"database/sql"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+)
+
+// SysLoginLogDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysLoginLogDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns sysLoginLogColumns
+}
+
+// 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 // 登录模块
+}
+
+var (
+	// SysLoginLog is globally public accessible object for table sys_login_log operations.
+	SysLoginLog = SysLoginLogDao{
+		M:     g.DB("default").Model("sys_login_log").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_login_log",
+		Columns: 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",
+		},
+	}
+)
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *SysLoginLogDao) Ctx(ctx context.Context) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *SysLoginLogDao) As(as string) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *SysLoginLogDao) TX(tx *gdb.TX) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *SysLoginLogDao) Master() *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *SysLoginLogDao) Slave() *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *SysLoginLogDao) Args(args ...interface{}) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysLoginLogDao) LeftJoin(table ...string) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysLoginLogDao) RightJoin(table ...string) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysLoginLogDao) InnerJoin(table ...string) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysLoginLogDao) Fields(fieldNamesOrMapStruct ...interface{}) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysLoginLogDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *SysLoginLogDao) Option(option int) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *SysLoginLogDao) OmitEmpty() *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *SysLoginLogDao) Filter() *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *SysLoginLogDao) Where(where interface{}, args ...interface{}) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *SysLoginLogDao) WherePri(where interface{}, args ...interface{}) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *SysLoginLogDao) And(where interface{}, args ...interface{}) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *SysLoginLogDao) Or(where interface{}, args ...interface{}) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *SysLoginLogDao) Group(groupBy string) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *SysLoginLogDao) Order(orderBy ...string) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *SysLoginLogDao) Limit(limit ...int) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *SysLoginLogDao) Offset(offset int) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *SysLoginLogDao) Page(page, limit int) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *SysLoginLogDao) Batch(batch int) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *SysLoginLogDao) Cache(duration time.Duration, name ...string) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *SysLoginLogDao) Data(data ...interface{}) *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.SysLoginLog.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysLoginLogDao) All(where ...interface{}) ([]*model.SysLoginLog, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysLoginLog
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.SysLoginLog.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysLoginLogDao) One(where ...interface{}) (*model.SysLoginLog, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysLoginLog
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *SysLoginLogDao) FindOne(where ...interface{}) (*model.SysLoginLog, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysLoginLog
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *SysLoginLogDao) FindAll(where ...interface{}) ([]*model.SysLoginLog, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysLoginLog
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *SysLoginLogDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *SysLoginLogDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *SysLoginLogDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *SysLoginLogDao) Chunk(limit int, callback func(entities []*model.SysLoginLog, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*model.SysLoginLog
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *SysLoginLogDao) LockUpdate() *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *SysLoginLogDao) LockShared() *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *SysLoginLogDao) Unscoped() *SysLoginLogDao {
+	return &SysLoginLogDao{M: d.M.Unscoped()}
+}

+ 69 - 0
app/system/dao/internal/sys_model_info.go

@@ -0,0 +1,69 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysModelInfoDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysModelInfoDao struct {
+	gmvc.M                      // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	DB      gdb.DB              // DB is the raw underlying database management object.
+	Table   string              // Table is the table name of the DAO.
+	Columns sysModelInfoColumns // Columns contains all the columns of Table that for convenient usage.
+}
+
+// SysModelInfoColumns defines and stores column names for table sys_model_info.
+type sysModelInfoColumns struct {
+	ModelId         string // 模型ID
+	ModelCategoryId string // 模板分类id
+	ModelName       string // 模型标识
+	ModelTitle      string // 模型名称
+	ModelPk         string // 主键字段
+	ModelOrder      string // 默认排序字段
+	ModelSort       string // 表单字段排序
+	ModelList       string // 列表显示字段,为空显示全部
+	ModelEdit       string // 可编辑字段,为空则除主键外均可以编辑
+	ModelIndexes    string // 索引字段
+	SearchList      string // 高级搜索的字段
+	CreateTime      string // 创建时间
+	UpdateTime      string // 更新时间
+	ModelStatus     string // 状态
+	ModelEngine     string // 数据库引擎
+	CreateBy        string // 创建人
+	UpdateBy        string // 修改人
+}
+
+var (
+	// SysModelInfo is globally public accessible object for table sys_model_info operations.
+	SysModelInfo = SysModelInfoDao{
+		M:     g.DB("default").Model("sys_model_info").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_model_info",
+		Columns: sysModelInfoColumns{
+			ModelId:         "model_id",
+			ModelCategoryId: "model_category_id",
+			ModelName:       "model_name",
+			ModelTitle:      "model_title",
+			ModelPk:         "model_pk",
+			ModelOrder:      "model_order",
+			ModelSort:       "model_sort",
+			ModelList:       "model_list",
+			ModelEdit:       "model_edit",
+			ModelIndexes:    "model_indexes",
+			SearchList:      "search_list",
+			CreateTime:      "create_time",
+			UpdateTime:      "update_time",
+			ModelStatus:     "model_status",
+			ModelEngine:     "model_engine",
+			CreateBy:        "create_by",
+			UpdateBy:        "update_by",
+		},
+	}
+)

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

@@ -0,0 +1,67 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysOperLogDao is the manager for logic model data accessing and custom defined data operations functions management.
+type SysOperLogDao struct {
+	gmvc.M                   // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	C      sysOperLogColumns // C is the short type for Columns, which contains all the column names of Table for convenient usage.
+	DB     gdb.DB            // DB is the raw underlying database management object.
+	Table  string            // Table is the underlying table name of the DAO.
+}
+
+// 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 // 请求参数
+	JsonResult    string // 返回参数
+	Status        string // 操作状态(0正常 1异常)
+	ErrorMsg      string // 错误消息
+	OperTime      string // 操作时间
+}
+
+// NewSysOperLogDao creates and returns a new DAO object for table data access.
+func NewSysOperLogDao() *SysOperLogDao {
+	columns := 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",
+		JsonResult:    "json_result",
+		Status:        "status",
+		ErrorMsg:      "error_msg",
+		OperTime:      "oper_time",
+	}
+	return &SysOperLogDao{
+		C:     columns,
+		M:     g.DB("default").Model("sys_oper_log").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_oper_log",
+	}
+}

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

@@ -0,0 +1,57 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysPostDao is the manager for logic model data accessing and custom defined data operations functions management.
+type SysPostDao struct {
+	gmvc.M                // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	C      sysPostColumns // C is the short type for Columns, which contains all the column names of Table for convenient usage.
+	DB     gdb.DB         // DB is the raw underlying database management object.
+	Table  string         // Table is the underlying table name of the DAO.
+}
+
+// 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 // 删除时间
+}
+
+// NewSysPostDao creates and returns a new DAO object for table data access.
+func NewSysPostDao() *SysPostDao {
+	columns := 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",
+	}
+	return &SysPostDao{
+		C:     columns,
+		M:     g.DB("default").Model("sys_post").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_post",
+	}
+}

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

@@ -0,0 +1,393 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+
+	"gfast/app/system/model"
+)
+
+// SysRoleDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysRoleDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns sysRoleColumns
+}
+
+// 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:本部门及以下数据权限)
+}
+
+var (
+	// SysRole is globally public accessible object for table sys_role operations.
+	SysRole = SysRoleDao{
+		M:     g.DB("default").Model("sys_role").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_role",
+		Columns: sysRoleColumns{
+			Id:        "id",
+			Status:    "status",
+			ListOrder: "list_order",
+			Name:      "name",
+			Remark:    "remark",
+			DataScope: "data_scope",
+		},
+	}
+)
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *SysRoleDao) Ctx(ctx context.Context) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *SysRoleDao) As(as string) *SysRoleDao {
+	return &SysRoleDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *SysRoleDao) TX(tx *gdb.TX) *SysRoleDao {
+	return &SysRoleDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *SysRoleDao) Master() *SysRoleDao {
+	return &SysRoleDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *SysRoleDao) Slave() *SysRoleDao {
+	return &SysRoleDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *SysRoleDao) Args(args ...interface{}) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysRoleDao) LeftJoin(table ...string) *SysRoleDao {
+	return &SysRoleDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysRoleDao) RightJoin(table ...string) *SysRoleDao {
+	return &SysRoleDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysRoleDao) InnerJoin(table ...string) *SysRoleDao {
+	return &SysRoleDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysRoleDao) Fields(fieldNamesOrMapStruct ...interface{}) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysRoleDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *SysRoleDao {
+	return &SysRoleDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *SysRoleDao) Option(option int) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *SysRoleDao) OmitEmpty() *SysRoleDao {
+	return &SysRoleDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *SysRoleDao) Filter() *SysRoleDao {
+	return &SysRoleDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *SysRoleDao) Where(where interface{}, args ...interface{}) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *SysRoleDao) WherePri(where interface{}, args ...interface{}) *SysRoleDao {
+	return &SysRoleDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *SysRoleDao) And(where interface{}, args ...interface{}) *SysRoleDao {
+	return &SysRoleDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *SysRoleDao) Or(where interface{}, args ...interface{}) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *SysRoleDao) Group(groupBy string) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *SysRoleDao) Order(orderBy ...string) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *SysRoleDao) Limit(limit ...int) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *SysRoleDao) Offset(offset int) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *SysRoleDao) Page(page, limit int) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *SysRoleDao) Batch(batch int) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *SysRoleDao) Cache(duration time.Duration, name ...string) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *SysRoleDao) Data(data ...interface{}) *SysRoleDao {
+	return &SysRoleDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.SysRole.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysRoleDao) All(where ...interface{}) ([]*model.SysRole, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysRole
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.SysRole.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysRoleDao) One(where ...interface{}) (*model.SysRole, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysRole
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *SysRoleDao) FindOne(where ...interface{}) (*model.SysRole, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysRole
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *SysRoleDao) FindAll(where ...interface{}) ([]*model.SysRole, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysRole
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *SysRoleDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *SysRoleDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *SysRoleDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *SysRoleDao) Chunk(limit int, callback func(entities []*model.SysRole, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*model.SysRole
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *SysRoleDao) LockUpdate() *SysRoleDao {
+	return &SysRoleDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *SysRoleDao) LockShared() *SysRoleDao {
+	return &SysRoleDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *SysRoleDao) Unscoped() *SysRoleDao {
+	return &SysRoleDao{M: d.M.Unscoped()}
+}

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

@@ -0,0 +1,39 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysRoleDeptDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysRoleDeptDao struct {
+	gmvc.M                     // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	DB      gdb.DB             // DB is the raw underlying database management object.
+	Table   string             // Table is the table name of the DAO.
+	Columns sysRoleDeptColumns // Columns contains all the columns of Table that for convenient usage.
+}
+
+// SysRoleDeptColumns defines and stores column names for table sys_role_dept.
+type sysRoleDeptColumns struct {
+	RoleId string // 角色ID
+	DeptId string // 部门ID
+}
+
+var (
+	// SysRoleDept is globally public accessible object for table sys_role_dept operations.
+	SysRoleDept = SysRoleDeptDao{
+		M:     g.DB("default").Model("sys_role_dept").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_role_dept",
+		Columns: sysRoleDeptColumns{
+			RoleId: "role_id",
+			DeptId: "dept_id",
+		},
+	}
+)

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

@@ -0,0 +1,424 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"database/sql"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+)
+
+// SysUserDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysUserDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns sysUserColumns
+}
+
+// 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 // 描述信息
+	PhoneNum      string // 联系电话
+	LastLoginIp   string // 最后登录ip
+	LastLoginTime string // 最后登录时间
+	CreatedAt     string // 创建时间
+	UpdatedAt     string // 更新时间
+	DeletedAt     string // 删除时间
+}
+
+var (
+	// SysUser is globally public accessible object for table sys_user operations.
+	SysUser = SysUserDao{
+		M:     g.DB("default").Model("sys_user").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_user",
+		Columns: 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",
+			PhoneNum:      "phone_num",
+			LastLoginIp:   "last_login_ip",
+			LastLoginTime: "last_login_time",
+			CreatedAt:     "created_at",
+			UpdatedAt:     "updated_at",
+			DeletedAt:     "deleted_at",
+		},
+	}
+)
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *SysUserDao) Ctx(ctx context.Context) *SysUserDao {
+	return &SysUserDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *SysUserDao) As(as string) *SysUserDao {
+	return &SysUserDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *SysUserDao) TX(tx *gdb.TX) *SysUserDao {
+	return &SysUserDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *SysUserDao) Master() *SysUserDao {
+	return &SysUserDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *SysUserDao) Slave() *SysUserDao {
+	return &SysUserDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *SysUserDao) Args(args ...interface{}) *SysUserDao {
+	return &SysUserDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysUserDao) LeftJoin(table ...string) *SysUserDao {
+	return &SysUserDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysUserDao) RightJoin(table ...string) *SysUserDao {
+	return &SysUserDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysUserDao) InnerJoin(table ...string) *SysUserDao {
+	return &SysUserDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysUserDao) Fields(fieldNamesOrMapStruct ...interface{}) *SysUserDao {
+	return &SysUserDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysUserDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *SysUserDao {
+	return &SysUserDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *SysUserDao) Option(option int) *SysUserDao {
+	return &SysUserDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *SysUserDao) OmitEmpty() *SysUserDao {
+	return &SysUserDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *SysUserDao) Filter() *SysUserDao {
+	return &SysUserDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *SysUserDao) Where(where interface{}, args ...interface{}) *SysUserDao {
+	return &SysUserDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *SysUserDao) WherePri(where interface{}, args ...interface{}) *SysUserDao {
+	return &SysUserDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *SysUserDao) And(where interface{}, args ...interface{}) *SysUserDao {
+	return &SysUserDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *SysUserDao) Or(where interface{}, args ...interface{}) *SysUserDao {
+	return &SysUserDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *SysUserDao) Group(groupBy string) *SysUserDao {
+	return &SysUserDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *SysUserDao) Order(orderBy ...string) *SysUserDao {
+	return &SysUserDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *SysUserDao) Limit(limit ...int) *SysUserDao {
+	return &SysUserDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *SysUserDao) Offset(offset int) *SysUserDao {
+	return &SysUserDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *SysUserDao) Page(page, limit int) *SysUserDao {
+	return &SysUserDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *SysUserDao) Batch(batch int) *SysUserDao {
+	return &SysUserDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *SysUserDao) Cache(duration time.Duration, name ...string) *SysUserDao {
+	return &SysUserDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *SysUserDao) Data(data ...interface{}) *SysUserDao {
+	return &SysUserDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.SysUser.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysUserDao) All(where ...interface{}) ([]*model.SysUser, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysUser
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.SysUser.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysUserDao) One(where ...interface{}) (*model.SysUser, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysUser
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *SysUserDao) FindOne(where ...interface{}) (*model.SysUser, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysUser
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *SysUserDao) FindAll(where ...interface{}) ([]*model.SysUser, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysUser
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *SysUserDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *SysUserDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *SysUserDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *SysUserDao) Chunk(limit int, callback func(entities []*model.SysUser, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*model.SysUser
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *SysUserDao) LockUpdate() *SysUserDao {
+	return &SysUserDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *SysUserDao) LockShared() *SysUserDao {
+	return &SysUserDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *SysUserDao) Unscoped() *SysUserDao {
+	return &SysUserDao{M: d.M.Unscoped()}
+}

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

@@ -0,0 +1,397 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"context"
+	"database/sql"
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+	"time"
+
+	"gfast/app/system/model"
+)
+
+// SysUserOnlineDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysUserOnlineDao struct {
+	gmvc.M
+	DB      gdb.DB
+	Table   string
+	Columns sysUserOnlineColumns
+}
+
+// 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 // 操作系统
+}
+
+var (
+	// SysUserOnline is globally public accessible object for table sys_user_online operations.
+	SysUserOnline = SysUserOnlineDao{
+		M:     g.DB("default").Model("sys_user_online").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_user_online",
+		Columns: sysUserOnlineColumns{
+			Id:         "id",
+			Uuid:       "uuid",
+			Token:      "token",
+			CreateTime: "create_time",
+			UserName:   "user_name",
+			Ip:         "ip",
+			Explorer:   "explorer",
+			Os:         "os",
+		},
+	}
+)
+
+// Ctx is a chaining function, which creates and returns a new DB that is a shallow copy
+// of current DB object and with given context in it.
+// Note that this returned DB object can be used only once, so do not assign it to
+// a global or package variable for long using.
+func (d *SysUserOnlineDao) Ctx(ctx context.Context) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Ctx(ctx)}
+}
+
+// As sets an alias name for current table.
+func (d *SysUserOnlineDao) As(as string) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.As(as)}
+}
+
+// TX sets the transaction for current operation.
+func (d *SysUserOnlineDao) TX(tx *gdb.TX) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.TX(tx)}
+}
+
+// Master marks the following operation on master node.
+func (d *SysUserOnlineDao) Master() *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Master()}
+}
+
+// Slave marks the following operation on slave node.
+// Note that it makes sense only if there's any slave node configured.
+func (d *SysUserOnlineDao) Slave() *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Slave()}
+}
+
+// Args sets custom arguments for model operation.
+func (d *SysUserOnlineDao) Args(args ...interface{}) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Args(args...)}
+}
+
+// LeftJoin does "LEFT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysUserOnlineDao) LeftJoin(table ...string) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.LeftJoin(table...)}
+}
+
+// RightJoin does "RIGHT JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").RightJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysUserOnlineDao) RightJoin(table ...string) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.RightJoin(table...)}
+}
+
+// InnerJoin does "INNER JOIN ... ON ..." statement on the model.
+// The parameter <table> can be joined table and its joined condition,
+// and also with its alias name, like:
+// Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid")
+// Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid")
+func (d *SysUserOnlineDao) InnerJoin(table ...string) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.InnerJoin(table...)}
+}
+
+// Fields sets the operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysUserOnlineDao) Fields(fieldNamesOrMapStruct ...interface{}) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Fields(fieldNamesOrMapStruct...)}
+}
+
+// FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','.
+// The parameter <fieldNamesOrMapStruct> can be type of string/map/*map/struct/*struct.
+func (d *SysUserOnlineDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)}
+}
+
+// Option sets the extra operation option for the model.
+func (d *SysUserOnlineDao) Option(option int) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Option(option)}
+}
+
+// OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers
+// the data and where attributes for empty values.
+func (d *SysUserOnlineDao) OmitEmpty() *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.OmitEmpty()}
+}
+
+// Filter marks filtering the fields which does not exist in the fields of the operated table.
+func (d *SysUserOnlineDao) Filter() *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Filter()}
+}
+
+// Where sets the condition statement for the model. The parameter <where> can be type of
+// string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times,
+// multiple conditions will be joined into where statement using "AND".
+// Eg:
+// Where("uid=10000")
+// Where("uid", 10000)
+// Where("money>? AND name like ?", 99999, "vip_%")
+// Where("uid", 1).Where("name", "john")
+// Where("status IN (?)", g.Slice{1,2,3})
+// Where("age IN(?,?)", 18, 50)
+// Where(User{ Id : 1, UserName : "john"})
+func (d *SysUserOnlineDao) Where(where interface{}, args ...interface{}) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Where(where, args...)}
+}
+
+// WherePri does the same logic as M.Where except that if the parameter <where>
+// is a single condition like int/string/float/slice, it treats the condition as the primary
+// key value. That is, if primary key is "id" and given <where> parameter as "123", the
+// WherePri function treats the condition as "id=123", but M.Where treats the condition
+// as string "123".
+func (d *SysUserOnlineDao) WherePri(where interface{}, args ...interface{}) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.WherePri(where, args...)}
+}
+
+// And adds "AND" condition to the where statement.
+func (d *SysUserOnlineDao) And(where interface{}, args ...interface{}) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.And(where, args...)}
+}
+
+// Or adds "OR" condition to the where statement.
+func (d *SysUserOnlineDao) Or(where interface{}, args ...interface{}) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Or(where, args...)}
+}
+
+// Group sets the "GROUP BY" statement for the model.
+func (d *SysUserOnlineDao) Group(groupBy string) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Group(groupBy)}
+}
+
+// Order sets the "ORDER BY" statement for the model.
+func (d *SysUserOnlineDao) Order(orderBy ...string) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Order(orderBy...)}
+}
+
+// Limit sets the "LIMIT" statement for the model.
+// The parameter <limit> can be either one or two number, if passed two number is passed,
+// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"
+// statement.
+func (d *SysUserOnlineDao) Limit(limit ...int) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Limit(limit...)}
+}
+
+// Offset sets the "OFFSET" statement for the model.
+// It only makes sense for some databases like SQLServer, PostgreSQL, etc.
+func (d *SysUserOnlineDao) Offset(offset int) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Offset(offset)}
+}
+
+// Page sets the paging number for the model.
+// The parameter <page> is started from 1 for paging.
+// Note that, it differs that the Limit function start from 0 for "LIMIT" statement.
+func (d *SysUserOnlineDao) Page(page, limit int) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Page(page, limit)}
+}
+
+// Batch sets the batch operation number for the model.
+func (d *SysUserOnlineDao) Batch(batch int) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Batch(batch)}
+}
+
+// Cache sets the cache feature for the model. It caches the result of the sql, which means
+// if there's another same sql request, it just reads and returns the result from cache, it
+// but not committed and executed into the database.
+//
+// If the parameter <duration> < 0, which means it clear the cache with given <name>.
+// If the parameter <duration> = 0, which means it never expires.
+// If the parameter <duration> > 0, which means it expires after <duration>.
+//
+// The optional parameter <name> is used to bind a name to the cache, which means you can later
+// control the cache like changing the <duration> or clearing the cache with specified <name>.
+//
+// Note that, the cache feature is disabled if the model is operating on a transaction.
+func (d *SysUserOnlineDao) Cache(duration time.Duration, name ...string) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Cache(duration, name...)}
+}
+
+// Data sets the operation data for the model.
+// The parameter <data> can be type of string/map/gmap/slice/struct/*struct, etc.
+// Eg:
+// Data("uid=10000")
+// Data("uid", 10000)
+// Data(g.Map{"uid": 10000, "name":"john"})
+// Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"})
+func (d *SysUserOnlineDao) Data(data ...interface{}) *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Data(data...)}
+}
+
+// All does "SELECT FROM ..." statement for the model.
+// It retrieves the records from table and returns the result as []*model.SysUserOnline.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysUserOnlineDao) All(where ...interface{}) ([]*model.SysUserOnline, error) {
+	all, err := d.M.All(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysUserOnline
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// One retrieves one record from table and returns the result as *model.SysUserOnline.
+// It returns nil if there's no record retrieved with the given conditions from table.
+//
+// The optional parameter <where> is the same as the parameter of M.Where function,
+// see M.Where.
+func (d *SysUserOnlineDao) One(where ...interface{}) (*model.SysUserOnline, error) {
+	one, err := d.M.One(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysUserOnline
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindOne retrieves and returns a single Record by M.WherePri and M.One.
+// Also see M.WherePri and M.One.
+func (d *SysUserOnlineDao) FindOne(where ...interface{}) (*model.SysUserOnline, error) {
+	one, err := d.M.FindOne(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entity *model.SysUserOnline
+	if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entity, nil
+}
+
+// FindAll retrieves and returns Result by by M.WherePri and M.All.
+// Also see M.WherePri and M.All.
+func (d *SysUserOnlineDao) FindAll(where ...interface{}) ([]*model.SysUserOnline, error) {
+	all, err := d.M.FindAll(where...)
+	if err != nil {
+		return nil, err
+	}
+	var entities []*model.SysUserOnline
+	if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows {
+		return nil, err
+	}
+	return entities, nil
+}
+
+// Struct retrieves one record from table and converts it into given struct.
+// The parameter <pointer> should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not nil.
+//
+// Eg:
+// user := new(User)
+// err  := dao.User.Where("id", 1).Struct(user)
+//
+// user := (*User)(nil)
+// err  := dao.User.Where("id", 1).Struct(&user)
+func (d *SysUserOnlineDao) Struct(pointer interface{}, where ...interface{}) error {
+	return d.M.Struct(pointer, where...)
+}
+
+// Structs retrieves records from table and converts them into given struct slice.
+// The parameter <pointer> should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions
+// from table and <pointer> is not empty.
+//
+// Eg:
+// users := ([]User)(nil)
+// err   := dao.User.Structs(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Structs(&users)
+func (d *SysUserOnlineDao) Structs(pointer interface{}, where ...interface{}) error {
+	return d.M.Structs(pointer, where...)
+}
+
+// Scan automatically calls Struct or Structs function according to the type of parameter <pointer>.
+// It calls function Struct if <pointer> is type of *struct/**struct.
+// It calls function Structs if <pointer> is type of *[]struct/*[]*struct.
+//
+// The optional parameter <where> is the same as the parameter of Model.Where function,
+// see Model.Where.
+//
+// Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil.
+//
+// Eg:
+// user  := new(User)
+// err   := dao.User.Where("id", 1).Scan(user)
+//
+// user  := (*User)(nil)
+// err   := dao.User.Where("id", 1).Scan(&user)
+//
+// users := ([]User)(nil)
+// err   := dao.User.Scan(&users)
+//
+// users := ([]*User)(nil)
+// err   := dao.User.Scan(&users)
+func (d *SysUserOnlineDao) Scan(pointer interface{}, where ...interface{}) error {
+	return d.M.Scan(pointer, where...)
+}
+
+// Chunk iterates the table with given size and callback function.
+func (d *SysUserOnlineDao) Chunk(limit int, callback func(entities []*model.SysUserOnline, err error) bool) {
+	d.M.Chunk(limit, func(result gdb.Result, err error) bool {
+		var entities []*model.SysUserOnline
+		err = result.Structs(&entities)
+		if err == sql.ErrNoRows {
+			return false
+		}
+		return callback(entities, err)
+	})
+}
+
+// LockUpdate sets the lock for update for current operation.
+func (d *SysUserOnlineDao) LockUpdate() *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.LockUpdate()}
+}
+
+// LockShared sets the lock in share mode for current operation.
+func (d *SysUserOnlineDao) LockShared() *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.LockShared()}
+}
+
+// Unscoped enables/disables the soft deleting feature.
+func (d *SysUserOnlineDao) Unscoped() *SysUserOnlineDao {
+	return &SysUserOnlineDao{M: d.M.Unscoped()}
+}

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

@@ -0,0 +1,39 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysUserPostDao is the manager for logic model data accessing
+// and custom defined data operations functions management.
+type SysUserPostDao struct {
+	gmvc.M                     // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	DB      gdb.DB             // DB is the raw underlying database management object.
+	Table   string             // Table is the table name of the DAO.
+	Columns sysUserPostColumns // Columns contains all the columns of Table that for convenient usage.
+}
+
+// SysUserPostColumns defines and stores column names for table sys_user_post.
+type sysUserPostColumns struct {
+	UserId string // 用户ID
+	PostId string // 岗位ID
+}
+
+var (
+	// SysUserPost is globally public accessible object for table sys_user_post operations.
+	SysUserPost = SysUserPostDao{
+		M:     g.DB("default").Model("sys_user_post").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_user_post",
+		Columns: sysUserPostColumns{
+			UserId: "user_id",
+			PostId: "post_id",
+		},
+	}
+)

+ 39 - 0
app/system/dao/internal/sys_web_set.go

@@ -0,0 +1,39 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/database/gdb"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// SysWebSetDao is the manager for logic model data accessing and custom defined data operations functions management.
+type SysWebSetDao struct {
+	gmvc.M                  // M is the core and embedded struct that inherits all chaining operations from gdb.Model.
+	C      sysWebSetColumns // C is the short type for Columns, which contains all the column names of Table for convenient usage.
+	DB     gdb.DB           // DB is the raw underlying database management object.
+	Table  string           // Table is the underlying table name of the DAO.
+}
+
+// SysWebSetColumns defines and stores column names for table sys_web_set.
+type sysWebSetColumns struct {
+	WebId      string // 主键
+	WebContent string // 站点信息
+}
+
+// NewSysWebSetDao creates and returns a new DAO object for table data access.
+func NewSysWebSetDao() *SysWebSetDao {
+	columns := sysWebSetColumns{
+		WebId:      "web_id",
+		WebContent: "web_content",
+	}
+	return &SysWebSetDao{
+		C:     columns,
+		M:     g.DB("default").Model("sys_web_set").Safe(),
+		DB:    g.DB("default"),
+		Table: "sys_web_set",
+	}
+}

+ 70 - 0
app/system/dao/sys_auth_rule.go

@@ -0,0 +1,70 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/frame/gmvc"
+)
+
+// sysAuthRuleDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// 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.SysAuthRule,
+	}
+)
+
+func (d *sysAuthRuleDao) Scope(f func(m gmvc.M) gmvc.M) *sysAuthRuleDao {
+	nd := *d
+	if m := f(d.M); m != nil {
+		nd.M = m
+	}
+	return &nd
+}
+
+// Fill with you ideas below.
+func (d *sysAuthRuleDao) GetMenuList() (list []*model.SysAuthRuleInfoRes, err error) {
+
+	err = d.Fields(model.SysAuthRuleInfoRes{}).Order("weigh desc,id asc").Scan(&list)
+	return
+}
+
+func (d *sysAuthRuleDao) CheckMenuNameUnique(name string, id int) bool {
+
+	m := d.Where("name=?", name)
+	if id != 0 {
+		m = m.And("id!=?", id)
+	}
+	c, err := m.Count()
+	if err != nil {
+		g.Log().Error(err)
+		return false
+	}
+	return c == 0
+}
+
+//检查菜单路由地址是否已经存在
+func (d *sysAuthRuleDao) CheckMenuPathUnique(path string, id int) bool {
+
+	model := d.Where("path=?", path).Where("menu_type<>?", 2)
+	if id != 0 {
+		model = model.And("id!=?", id)
+	}
+	c, err := model.Count()
+	if err != nil {
+		g.Log().Error(err)
+		return false
+	}
+	return c == 0
+}

+ 58 - 0
app/system/dao/sys_dept.go

@@ -0,0 +1,58 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+	"gfast/app/system/model"
+)
+
+// sysDeptDao 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 sysDeptDao struct {
+	*internal.SysDeptDao
+}
+
+var (
+	// SysDept is globally public accessible object for table sys_dept operations.
+	SysDept sysDeptDao
+)
+
+func init() {
+	SysDept = sysDeptDao{
+		internal.NewSysDeptDao(),
+	}
+}
+
+// Fill with you ideas below.
+
+type SysDeptSearchParams struct {
+	ExcludeId int64  `p:"excludeId"`
+	DeptName  string `p:"deptName"`
+	Status    string `p:"status"`
+}
+
+type SysDeptTreeRes struct {
+	*model.SysDept
+	Children []*SysDeptTreeRes `json:"children"`
+}
+
+type SysDeptAddParams struct {
+	ParentID  int    `json:"parentId" orm:"parent_id"  p:"parentId"  v:"required#父级不能为空"`
+	DeptName  string `json:"deptName" orm:"dept_name" p:"deptName"  v:"required#部门名称不能为空"`
+	OrderNum  int    `json:"orderNum" orm:"order_num"  p:"orderNum"  v:"required#排序不能为空"`
+	Leader    string `json:"leader" orm:"leader" p:"leader"  v:"required#负责人不能为空"`
+	Phone     string `json:"phone" orm:"Phone" p:"phone"  v:"required#电话不能为空"`
+	Email     string `json:"email" orm:"email" p:"email"  v:"required#邮箱不能为空"`
+	Status    string `json:"status" orm:"status" p:"status"  v:"required#状态必须"`
+	Ancestors string `json:"ancestors" p:"ancestors" orm:"ancestors"`
+	CreatedBy uint64 `json:"CreatedBy"  orm:"created_by"`
+}
+
+type EditParams struct {
+	DeptID int64 `json:"deptId" orm:"dept_id" p:"id" v:"integer|min:1#ID只能为整数|ID只能为正数"`
+	SysDeptAddParams
+	UpdatedBy uint64 `json:"updatedBy" orm:"updated_by"`
+}

+ 25 - 0
app/system/dao/sys_dict_data.go

@@ -0,0 +1,25 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+)
+
+// sysDictDataDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// 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.SysDictData,
+	}
+)
+
+// Fill with you ideas below.

+ 23 - 0
app/system/dao/sys_dict_type.go

@@ -0,0 +1,23 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+)
+
+// sysDictTypeDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// 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.SysDictType,
+	}
+)

+ 58 - 0
app/system/dao/sys_job.go

@@ -0,0 +1,58 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	comModel "gfast/app/common/model"
+	"gfast/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 sys_job operations.
+	SysJob sysJobDao
+)
+
+func init() {
+	SysJob = sysJobDao{
+		internal.NewSysJobDao(),
+	}
+}
+
+// Fill with you ideas below.
+
+// SysJobSearchReq 分页请求参数
+type SysJobSearchReq struct {
+	JobName  string `p:"jobName"`  //任务名称
+	JobGroup string `p:"jobGroup"` //任务组名
+	Status   string `p:"status"`   //状态(0正常 1暂停)
+	comModel.PageReq
+}
+
+// SysJobAddReq 添加操作请求参数
+type SysJobAddReq struct {
+	JobName        string `p:"jobName" v:"required#任务名称不能为空"`
+	JobParams      string `p:"jobParams"` // 任务参数
+	JobGroup       string `p:"jobGroup" `
+	InvokeTarget   string `p:"invokeTarget" v:"required#执行方法不能为空"`
+	CronExpression string `p:"cronExpression" v:"required#任务表达式不能为空"`
+	MisfirePolicy  int    `p:"misfirePolicy"`
+	Concurrent     int    `p:"concurrent" `
+	Status         int    `p:"status" v:"required#状态(0正常 1暂停)不能为空"`
+	Remark         string `p:"remark" `
+	CreateBy       uint64
+}
+
+// SysJobEditReq 修改操作请求参数
+type SysJobEditReq struct {
+	JobId int64 `p:"job_id" v:"min:1#任务id不能为空"`
+	SysJobAddReq
+	UpdateBy uint64
+}

+ 35 - 0
app/system/dao/sys_login_log.go

@@ -0,0 +1,35 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/frame/g"
+)
+
+// sysLoginLogDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type sysLoginLogDao struct {
+	internal.SysLoginLogDao
+}
+
+var (
+	// SysLoginLog is globally public accessible object for table sys_login_log operations.
+	SysLoginLog = sysLoginLogDao{
+		internal.SysLoginLog,
+	}
+)
+
+// Fill with you ideas below.
+
+// SaveLog 保存日志信息
+func (d sysLoginLogDao) SaveLog(data *model.SysLoginLog) {
+	_, err := d.Insert(data)
+	if err != nil {
+		g.Log().Error(err)
+	}
+}

+ 39 - 0
app/system/dao/sys_model_info.go

@@ -0,0 +1,39 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"fmt"
+	"gfast/app/system/dao/internal"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/errors/gerror"
+	"github.com/gogf/gf/frame/g"
+)
+
+// sysModelInfoDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type sysModelInfoDao struct {
+	internal.SysModelInfoDao
+}
+
+var (
+	// SysModelInfo is globally public accessible object for table sys_model_info operations.
+	SysModelInfo = sysModelInfoDao{
+		internal.SysModelInfo,
+	}
+)
+
+// Fill with you ideas below.
+func (i *sysModelInfoDao) GetModelsByCateIds(cateIds []int) (models []*model.SysModelInfo, err error) {
+	err = i.Fields(fmt.Sprintf("%s,%s,%s", i.Columns.ModelId, i.Columns.ModelName, i.Columns.ModelTitle)).
+		Where(i.Columns.ModelCategoryId+" in(?)", cateIds).
+		Order(i.Columns.ModelId + " ASC ").Scan(&models)
+	if err != nil {
+		g.Log().Error(err)
+		err = gerror.New("获取模型信息失败")
+	}
+	return
+}

+ 54 - 0
app/system/dao/sys_oper_log.go

@@ -0,0 +1,54 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	comModel "gfast/app/common/model"
+	"gfast/app/system/dao/internal"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/frame/g"
+	"net/url"
+)
+
+// sysOperLogDao 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 sysOperLogDao struct {
+	*internal.SysOperLogDao
+}
+
+var (
+	// SysOperLog is globally public accessible object for table sys_oper_log operations.
+	SysOperLog sysOperLogDao
+)
+
+func init() {
+	SysOperLog = sysOperLogDao{
+		internal.NewSysOperLogDao(),
+	}
+}
+
+// Fill with you ideas below.
+
+// SysOperLogAdd 添加操作日志参数
+type SysOperLogAdd struct {
+	User         *CtxUser
+	Menu         *model.SysAuthRuleInfoRes
+	Url          *url.URL
+	Params       g.Map
+	Method       string
+	ClientIp     string
+	OperatorType int
+}
+
+// SysOperLogSearchReq 查询列表请求参数
+type SysOperLogSearchReq struct {
+	Title         string `p:"title"`         //系统模块
+	OperName      string `p:"operName"`      //操作人员
+	Status        string `p:"status"`        //操作状态
+	SortName      string `p:"orderByColumn"` //排序字段
+	SortOrder     string `p:"isAsc"`         //排序方式
+	RequestMethod string `p:"requestMethod"` //操作类型
+	comModel.PageReq
+}

+ 54 - 0
app/system/dao/sys_post.go

@@ -0,0 +1,54 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	comModel "gfast/app/common/model"
+	"gfast/app/system/dao/internal"
+)
+
+// sysPostDao 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 sysPostDao struct {
+	*internal.SysPostDao
+}
+
+var (
+	// SysPost is globally public accessible object for table sys_post operations.
+	SysPost sysPostDao
+)
+
+func init() {
+	SysPost = sysPostDao{
+		internal.NewSysPostDao(),
+	}
+}
+
+// Fill with you ideas below.
+
+// SysPostSearchParams 搜索参数
+type SysPostSearchParams struct {
+	PostCode string `p:"postCode"` //岗位编码
+	PostName string `p:"postName"` //岗位名称
+	Status   string `p:"status"`   //状态
+	comModel.PageReq
+}
+
+// SysPostAddParams 添加岗位参数
+type SysPostAddParams struct {
+	PostCode  string `p:"postCode" v:"required#岗位编码不能为空"`
+	PostName  string `p:"postName" v:"required#岗位名称不能为空"`
+	PostSort  int    `p:"postSort" v:"required#岗位排序不能为空"`
+	Status    string `p:"status" v:"required#状态不能为空"`
+	Remark    string `p:"remark"`
+	CreatedBy uint64
+}
+
+// SysPostEditParams 修改岗位参数
+type SysPostEditParams struct {
+	PostId int64 `p:"postId" v:"required#id必须"`
+	SysPostAddParams
+	UpdatedBy uint64
+}

+ 25 - 0
app/system/dao/sys_role.go

@@ -0,0 +1,25 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+)
+
+// sysRoleDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type sysRoleDao struct {
+	internal.SysRoleDao
+}
+
+var (
+	// SysRole is globally public accessible object for table sys_role operations.
+	SysRole = sysRoleDao{
+		internal.SysRole,
+	}
+)
+
+// Fill with you ideas below.

+ 25 - 0
app/system/dao/sys_role_dept.go

@@ -0,0 +1,25 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+)
+
+// sysRoleDeptDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type sysRoleDeptDao struct {
+	internal.SysRoleDeptDao
+}
+
+var (
+	// SysRoleDept is globally public accessible object for table sys_role_dept operations.
+	SysRoleDept = sysRoleDeptDao{
+		internal.SysRoleDept,
+	}
+)
+
+// Fill with you ideas below.

+ 52 - 0
app/system/dao/sys_user.go

@@ -0,0 +1,52 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package dao
+
+import (
+	"context"
+	"gfast/app/system/dao/internal"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/errors/gerror"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/os/gtime"
+)
+
+// sysUserDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type sysUserDao struct {
+	internal.SysUserDao
+}
+
+var (
+	// SysUser is globally public accessible object for table sys_user operations.
+	SysUser = sysUserDao{
+		internal.SysUser,
+	}
+)
+
+// Fill with you ideas below.
+
+//通过用户名获取用户信息
+func (d *sysUserDao) FindByUsername(ctx context.Context, username string) (user *model.LoginUserRes, err error) {
+	user = &model.LoginUserRes{}
+	err = d.Ctx(ctx).Fields(user).Where(d.Columns.UserName, username).Scan(user)
+	if err != nil {
+		g.Log().Error(err)
+		err = gerror.New("获取用户信息失败")
+	}
+	return
+}
+
+//更新用户登陆信息
+func (d *sysUserDao) UpLoginInfo(id uint64, ip string) {
+	_, err := d.WherePri(id).Unscoped().Update(g.Map{
+		d.Columns.LastLoginIp:   ip,
+		d.Columns.LastLoginTime: gtime.Now(),
+	})
+	if err != nil {
+		g.Log().Error(err)
+	}
+}

+ 49 - 0
app/system/dao/sys_user_online.go

@@ -0,0 +1,49 @@
+// ============================================================================
+// This is auto-generated by gf cli tool only once. Fill this file as you wish.
+// ============================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+	"gfast/app/system/model"
+	"github.com/gogf/gf/frame/g"
+)
+
+// sysUserOnlineDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type sysUserOnlineDao struct {
+	internal.SysUserOnlineDao
+}
+
+var (
+	// SysUserOnline is globally public accessible object for table sys_user_online operations.
+	SysUserOnline = sysUserOnlineDao{
+		internal.SysUserOnline,
+	}
+)
+
+// Fill with you ideas below.
+
+// SaveOnline 保存登录用户在线状态
+func (d sysUserOnlineDao) SaveOnline(params *model.SysUserOnline) {
+	//查询是否已存在当前用户
+	info, err := d.Fields(d.Columns.Id).FindOne(d.Columns.Token, params.Token)
+	if err != nil {
+		g.Log().Error(err)
+		return
+	}
+	//若已存在则更新
+	if info != nil {
+		_, err := SysUserOnline.Where(SysUserOnline.Columns.Id, info.Id).FieldsEx(SysUserOnline.Columns.Id).Update(params)
+		if err != nil {
+			g.Log().Error(err)
+		}
+	} else { //否则新增
+		_, err := SysUserOnline.FieldsEx(SysUserOnline.Columns.Id).Insert(params)
+		if err != nil {
+			g.Log().Error(err)
+		}
+	}
+}

+ 25 - 0
app/system/dao/sys_user_post.go

@@ -0,0 +1,25 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+)
+
+// sysUserPostDao is the manager for logic model data accessing
+// and custom defined data operations functions management. You can define
+// methods on it to extend its functionality as you wish.
+type sysUserPostDao struct {
+	internal.SysUserPostDao
+}
+
+var (
+	// SysUserPost is globally public accessible object for table sys_user_post operations.
+	SysUserPost = sysUserPostDao{
+		internal.SysUserPost,
+	}
+)
+
+// Fill with you ideas below.

+ 28 - 0
app/system/dao/sys_web_set.go

@@ -0,0 +1,28 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package dao
+
+import (
+	"gfast/app/system/dao/internal"
+)
+
+// sysWebSetDao 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 sysWebSetDao struct {
+	*internal.SysWebSetDao
+}
+
+var (
+	// SysWebSet is globally public accessible object for table sys_web_set operations.
+	SysWebSet sysWebSetDao
+)
+
+func init() {
+	SysWebSet = sysWebSetDao{
+		internal.NewSysWebSetDao(),
+	}
+}
+
+// Fill with you ideas below.

+ 0 - 0
app/system/model/.gitkeep


+ 33 - 0
app/system/model/internal/sys_auth_rule.go

@@ -0,0 +1,33 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysAuthRule is the golang structure for table sys_auth_rule.
+type SysAuthRule struct {
+	Id         uint        `orm:"id,primary"  json:"id"`         //
+	Pid        uint        `orm:"pid"         json:"pid"`        // 父ID
+	Name       string      `orm:"name,unique" json:"name"`       // 规则名称
+	Title      string      `orm:"title"       json:"title"`      // 规则名称
+	Icon       string      `orm:"icon"        json:"icon"`       // 图标
+	Condition  string      `orm:"condition"   json:"condition"`  // 条件
+	Remark     string      `orm:"remark"      json:"remark"`     // 备注
+	MenuType   uint        `orm:"menu_type"   json:"menuType"`   // 类型 0目录 1菜单 2按钮
+	Weigh      int         `orm:"weigh"       json:"weigh"`      // 权重
+	Status     uint        `orm:"status"      json:"status"`     // 状态
+	AlwaysShow uint        `orm:"always_show" json:"alwaysShow"` // 显示状态
+	Path       string      `orm:"path"        json:"path"`       // 路由地址
+	JumpPath   string      `orm:"jump_path"   json:"jumpPath"`   // 跳转路由
+	Component  string      `orm:"component"   json:"component"`  // 组件路径
+	IsFrame    uint        `orm:"is_frame"    json:"isFrame"`    // 是否外链 1是 0否
+	ModuleType string      `orm:"module_type" json:"moduleType"` // 所属模块
+	ModelId    uint        `orm:"model_id"    json:"modelId"`    // 模型ID
+	CreatedAt  *gtime.Time `orm:"created_at"  json:"createdAt"`  // 创建日期
+	UpdatedAt  *gtime.Time `orm:"updated_at"  json:"updatedAt"`  // 修改日期
+	DeletedAt  *gtime.Time `orm:"deleted_at"  json:"deletedAt"`  // 删除日期
+}

+ 28 - 0
app/system/model/internal/sys_dict_data.go

@@ -0,0 +1,28 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysDictData is the golang structure for table sys_dict_data.
+type SysDictData struct {
+	DictCode  int64       `orm:"dict_code,primary" json:"dictCode"`  // 字典编码
+	DictSort  int         `orm:"dict_sort"         json:"dictSort"`  // 字典排序
+	DictLabel string      `orm:"dict_label"        json:"dictLabel"` // 字典标签
+	DictValue string      `orm:"dict_value"        json:"dictValue"` // 字典键值
+	DictType  string      `orm:"dict_type"         json:"dictType"`  // 字典类型
+	CssClass  string      `orm:"css_class"         json:"cssClass"`  // 样式属性(其他样式扩展)
+	ListClass string      `orm:"list_class"        json:"listClass"` // 表格回显样式
+	IsDefault int         `orm:"is_default"        json:"isDefault"` // 是否默认(1是 0否)
+	Status    int         `orm:"status"            json:"status"`    // 状态(0正常 1停用)
+	CreateBy  uint64      `orm:"create_by"         json:"createBy"`  // 创建者
+	UpdateBy  uint64      `orm:"update_by"         json:"updateBy"`  // 更新者
+	Remark    string      `orm:"remark"            json:"remark"`    // 备注
+	CreatedAt *gtime.Time `orm:"created_at"        json:"createdAt"` // 创建时间
+	UpdatedAt *gtime.Time `orm:"updated_at"        json:"updatedAt"` // 修改时间
+	DeletedAt *gtime.Time `orm:"deleted_at"        json:"deletedAt"` // 删除时间
+}

+ 23 - 0
app/system/model/internal/sys_dict_type.go

@@ -0,0 +1,23 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysDictType is the golang structure for table sys_dict_type.
+type SysDictType 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停用)
+	CreateBy  uint        `orm:"create_by"        json:"createBy"`  // 创建者
+	UpdateBy  uint        `orm:"update_by"        json:"updateBy"`  // 更新者
+	Remark    string      `orm:"remark"           json:"remark"`    // 备注
+	CreatedAt *gtime.Time `orm:"created_at"       json:"createdAt"` // 创建日期
+	UpdatedAt *gtime.Time `orm:"updated_at"       json:"updatedAt"` // 修改日期
+	DeletedAt *gtime.Time `orm:"deleted_at"       json:"deletedAt"` // 删除日期
+}

+ 23 - 0
app/system/model/internal/sys_login_log.go

@@ -0,0 +1,23 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysLoginLog is the golang structure for table sys_login_log.
+type SysLoginLog struct {
+	InfoId        int64       `orm:"info_id,primary" json:"infoId"`        // 访问ID
+	LoginName     string      `orm:"login_name"      json:"loginName"`     // 登录账号
+	Ipaddr        string      `orm:"ipaddr"          json:"ipaddr"`        // 登录IP地址
+	LoginLocation string      `orm:"login_location"  json:"loginLocation"` // 登录地点
+	Browser       string      `orm:"browser"         json:"browser"`       // 浏览器类型
+	Os            string      `orm:"os"              json:"os"`            // 操作系统
+	Status        int         `orm:"status"          json:"status"`        // 登录状态(0成功 1失败)
+	Msg           string      `orm:"msg"             json:"msg"`           // 提示消息
+	LoginTime     *gtime.Time `orm:"login_time"      json:"loginTime"`     // 登录时间
+	Module        string      `orm:"module"          json:"module"`        // 登录模块
+}

+ 26 - 0
app/system/model/internal/sys_model_info.go

@@ -0,0 +1,26 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+// SysModelInfo is the golang structure for table sys_model_info.
+type SysModelInfo struct {
+	ModelId         uint   `orm:"model_id,primary"  json:"modelId"`         // 模型ID
+	ModelCategoryId uint   `orm:"model_category_id" json:"modelCategoryId"` // 模板分类id
+	ModelName       string `orm:"model_name,unique" json:"modelName"`       // 模型标识
+	ModelTitle      string `orm:"model_title"       json:"modelTitle"`      // 模型名称
+	ModelPk         string `orm:"model_pk"          json:"modelPk"`         // 主键字段
+	ModelOrder      string `orm:"model_order"       json:"modelOrder"`      // 默认排序字段
+	ModelSort       string `orm:"model_sort"        json:"modelSort"`       // 表单字段排序
+	ModelList       string `orm:"model_list"        json:"modelList"`       // 列表显示字段,为空显示全部
+	ModelEdit       string `orm:"model_edit"        json:"modelEdit"`       // 可编辑字段,为空则除主键外均可以编辑
+	ModelIndexes    string `orm:"model_indexes"     json:"modelIndexes"`    // 索引字段
+	SearchList      string `orm:"search_list"       json:"searchList"`      // 高级搜索的字段
+	CreateTime      uint64 `orm:"create_time"       json:"createTime"`      // 创建时间
+	UpdateTime      uint64 `orm:"update_time"       json:"updateTime"`      // 更新时间
+	ModelStatus     uint   `orm:"model_status"      json:"modelStatus"`     // 状态
+	ModelEngine     string `orm:"model_engine"      json:"modelEngine"`     // 数据库引擎
+	CreateBy        uint64 `orm:"create_by"         json:"createBy"`        // 创建人
+	UpdateBy        uint64 `orm:"update_by"         json:"updateBy"`        // 修改人
+}

+ 15 - 0
app/system/model/internal/sys_role.go

@@ -0,0 +1,15 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+// SysRole is the golang structure for table sys_role.
+type SysRole struct {
+	Id        uint    `orm:"id,primary"  json:"id"`        //
+	Status    uint    `orm:"status"      json:"status"`    // 状态;0:禁用;1:正常
+	ListOrder float64 `orm:"list_order"  json:"listOrder"` // 排序
+	Name      string  `orm:"name"        json:"name"`      // 角色名称
+	Remark    string  `orm:"remark"      json:"remark"`    // 备注
+	DataScope uint    `orm:"data_scope"  json:"dataScope"` // 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
+}

+ 11 - 0
app/system/model/internal/sys_role_dept.go

@@ -0,0 +1,11 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+// SysRoleDept is the golang structure for table sys_role_dept.
+type SysRoleDept struct {
+	RoleId int64 `orm:"role_id,primary" json:"roleId"` // 角色ID
+	DeptId int64 `orm:"dept_id,primary" json:"deptId"` // 部门ID
+}

+ 35 - 0
app/system/model/internal/sys_user.go

@@ -0,0 +1,35 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysUser is the golang structure for table sys_user.
+type SysUser struct {
+	Id            uint64      `orm:"id,primary"       json:"id"`            //
+	UserName      string      `orm:"user_name,unique" json:"userName"`      // 用户名
+	Mobile        string      `orm:"mobile,unique"    json:"mobile"`        // 中国手机不带国家代码,国际手机号格式为:国家代码-手机号
+	UserNickname  string      `orm:"user_nickname"    json:"userNickname"`  // 用户昵称
+	Birthday      int         `orm:"birthday"         json:"birthday"`      // 生日
+	UserPassword  string      `orm:"user_password"    json:"userPassword"`  // 登录密码;cmf_password加密
+	UserSalt      string      `orm:"user_salt"        json:"userSalt"`      // 加密盐
+	UserStatus    uint        `orm:"user_status"      json:"userStatus"`    // 用户状态;0:禁用,1:正常,2:未验证
+	UserEmail     string      `orm:"user_email"       json:"userEmail"`     // 用户登录邮箱
+	Sex           int         `orm:"sex"              json:"sex"`           // 性别;0:保密,1:男,2:女
+	Avatar        string      `orm:"avatar"           json:"avatar"`        // 用户头像
+	DeptId        uint64      `orm:"dept_id"          json:"deptId"`        // 部门id
+	Remark        string      `orm:"remark"           json:"remark"`        // 备注
+	IsAdmin       int         `orm:"is_admin"         json:"isAdmin"`       // 是否后台管理员 1 是  0   否
+	Address       string      `orm:"address"          json:"address"`       // 联系地址
+	Describe      string      `orm:"describe"         json:"describe"`      // 描述信息
+	PhoneNum      string      `orm:"phone_num"        json:"phoneNum"`      // 联系电话
+	LastLoginIp   string      `orm:"last_login_ip"    json:"lastLoginIp"`   // 最后登录ip
+	LastLoginTime *gtime.Time `orm:"last_login_time"  json:"lastLoginTime"` // 最后登录时间
+	CreatedAt     *gtime.Time `orm:"created_at"       json:"createdAt"`     // 创建时间
+	UpdatedAt     *gtime.Time `orm:"updated_at"       json:"updatedAt"`     // 更新时间
+	DeletedAt     *gtime.Time `orm:"deleted_at"       json:"deletedAt"`     // 删除时间
+}

+ 21 - 0
app/system/model/internal/sys_user_online.go

@@ -0,0 +1,21 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY.
+// ==========================================================================
+
+package internal
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysUserOnline is the golang structure for table sys_user_online.
+type SysUserOnline struct {
+	Id         uint64      `orm:"id,primary"   json:"id"`         //
+	Uuid       string      `orm:"uuid"         json:"uuid"`       // 用户标识
+	Token      string      `orm:"token,unique" json:"token"`      // 用户token
+	CreateTime *gtime.Time `orm:"create_time"  json:"createTime"` // 登录时间
+	UserName   string      `orm:"user_name"    json:"userName"`   // 用户名
+	Ip         string      `orm:"ip"           json:"ip"`         // 登录ip
+	Explorer   string      `orm:"explorer"     json:"explorer"`   // 浏览器
+	Os         string      `orm:"os"           json:"os"`         // 操作系统
+}

+ 11 - 0
app/system/model/internal/sys_user_post.go

@@ -0,0 +1,11 @@
+// ==========================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// ==========================================================================
+
+package internal
+
+// SysUserPost is the golang structure for table sys_user_post.
+type SysUserPost struct {
+	UserId int64 `orm:"user_id,primary" json:"userId"` // 用户ID
+	PostId int64 `orm:"post_id,primary" json:"postId"` // 岗位ID
+}

+ 67 - 0
app/system/model/sys_auth_rule.go

@@ -0,0 +1,67 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package model
+
+import (
+	"gfast/app/system/model/internal"
+)
+
+// SysAuthRule is the golang structure for table sys_auth_rule.
+type SysAuthRule internal.SysAuthRule
+
+// Fill with you ideas below.
+type SysAuthRuleInfoRes struct {
+	Id         uint   `orm:"id,primary"  json:"id"`         //
+	Pid        uint   `orm:"pid"         json:"pid"`        // 父ID
+	Name       string `orm:"name,unique" json:"name"`       // 规则名称
+	Title      string `orm:"title"       json:"title"`      // 规则名称
+	Icon       string `orm:"icon"        json:"icon"`       // 图标
+	Condition  string `orm:"condition"   json:"condition"`  // 条件
+	Remark     string `orm:"remark"      json:"remark"`     // 备注
+	MenuType   uint   `orm:"menu_type"   json:"menuType"`   // 类型 0目录 1菜单 2按钮
+	Weigh      int    `orm:"weigh"       json:"weigh"`      // 权重
+	Status     uint   `orm:"status"      json:"status"`     // 状态
+	AlwaysShow uint   `orm:"always_show" json:"alwaysShow"` // 显示状态
+	Path       string `orm:"path"        json:"path"`       // 路由地址
+	JumpPath   string `orm:"jump_path"   json:"jumpPath"`   // 跳转路由
+	Component  string `orm:"component"   json:"component"`  // 组件路径
+	IsFrame    uint   `orm:"is_frame"    json:"isFrame"`    // 是否外链 1是 0否
+	ModuleType string `orm:"module_type" json:"moduleType"` // 所属模块
+	ModelId    uint   `orm:"model_id"    json:"modelId"`    // 模型ID
+}
+
+type SysAuthRuleReqSearch struct {
+	Status string `p:"status" `
+	Title  string `p:"menuName" `
+}
+
+// SysAuthRuleTreeRes 菜单树形结构
+type SysAuthRuleTreeRes struct {
+	*SysAuthRuleInfoRes
+	Children []*SysAuthRuleTreeRes `json:"children"`
+}
+
+func (req *SysAuthRuleReqSearch) IsEmpty() bool {
+	return req.Status == "" && req.Title == ""
+}
+
+//菜单对象
+type MenuReq struct {
+	MenuType   uint   `orm:"menu_type" p:"menuType"  v:"min:0|max:2#菜单类型最小值为:min|菜单类型最大值为:max"`
+	Pid        uint   `orm:"pid"  p:"parentId"  v:"min:0"`
+	Name       string `orm:"name,unique" p:"name" v:"required#请填写规则名称"`
+	Title      string `orm:"title" p:"menuName" v:"required|length:1,100#请填写标题|标题长度在:min到:max位"`
+	Icon       string `orm:"icon"  p:"icon"`
+	Weigh      int    `orm:"weigh"  p:"orderNum" `
+	Condition  string `orm:"condition" p:"condition" `
+	Remark     string `orm:"remark" p:"remark" `
+	Status     uint   `orm:"status"  p:"status" `
+	AlwaysShow uint   `orm:"always_show" p:"visible"`
+	Path       string `orm:"path"   p:"path"`
+	Component  string `orm:"component"  p:"component" v:"required-if:menuType,1#组件路径不能为空"`
+	IsFrame    uint   `orm:"is_frame" p:"is_frame"`
+	ModuleType string `orm:"module_type" p:"moduleType"`
+	ModelId    uint   `orm:"model_id"    p:"modelId"`
+}

+ 27 - 0
app/system/model/sys_dept.go

@@ -0,0 +1,27 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package model
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysDept is the golang structure for table sys_dept.
+type SysDept struct {
+	DeptId    int64       `orm:"dept_id,primary" json:"deptId"`    // 部门id
+	ParentId  int64       `orm:"parent_id"       json:"parentId"`  // 父部门id
+	Ancestors string      `orm:"ancestors"       json:"ancestors"` // 祖级列表
+	DeptName  string      `orm:"dept_name"       json:"deptName"`  // 部门名称
+	OrderNum  int         `orm:"order_num"       json:"orderNum"`  // 显示顺序
+	Leader    string      `orm:"leader"          json:"leader"`    // 负责人
+	Phone     string      `orm:"phone"           json:"phone"`     // 联系电话
+	Email     string      `orm:"email"           json:"email"`     // 邮箱
+	Status    string      `orm:"status"          json:"status"`    // 部门状态(0正常 1停用)
+	CreatedBy uint64      `orm:"created_by"      json:"createdBy"` // 创建人
+	UpdatedBy int64       `orm:"updated_by"      json:"updatedBy"` // 修改人
+	CreatedAt *gtime.Time `orm:"created_at"      json:"createdAt"` // 创建时间
+	UpdatedAt *gtime.Time `orm:"updated_at"      json:"updatedAt"` // 修改时间
+	DeletedAt *gtime.Time `orm:"deleted_at"      json:"deletedAt"` // 删除时间
+}

+ 71 - 0
app/system/model/sys_dict_data.go

@@ -0,0 +1,71 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package model
+
+import (
+	"context"
+	comModel "gfast/app/common/model"
+	"gfast/app/system/model/internal"
+)
+
+// SysDictData is the golang structure for table sys_dict_data.
+type SysDictData internal.SysDictData
+
+// Fill with you ideas below.
+
+// SelectDictPageReq 分页请求参数
+type SelectDictPageReq struct {
+	DictType  string `p:"dictType"`  //字典类型
+	DictLabel string `p:"dictLabel"` //字典标签
+	Status    string `p:"status"`    //状态
+	comModel.PageReq
+}
+
+// GetDictReq 获取字典信息请求参数
+type GetDictReq struct {
+	DictType     string `p:"dictType" v:"required#字典类型不能为空"`
+	DefaultValue string `p:"defaultValue"`
+	Ctx          context.Context
+}
+
+// DictRes 完整的一个字典信息
+type DictRes struct {
+	Info   *DictTypeRes   `json:"info"`
+	Values []*DictDataRes `json:"values"`
+}
+
+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"`
+}
+
+// DictDataAddReq 新增操作请求参数
+type DictDataAddReq 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"`
+	CreateBy  uint64
+}
+
+// EditDictDataReq 修改字典数据操作请求参数
+type EditDictDataReq struct {
+	DictCode int `p:"dictCode" v:"required|min:1#主键ID不能为空|主键ID不能小于1"`
+	UpdateBy uint64
+	DictDataAddReq
+}

+ 47 - 0
app/system/model/sys_dict_type.go

@@ -0,0 +1,47 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package model
+
+import (
+	comModel "gfast/app/common/model"
+	"gfast/app/system/model/internal"
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysDictType is the golang structure for table sys_dict_type.
+type SysDictType internal.SysDictType
+
+// Fill with you ideas below.
+
+type ListSysDictTypeReq struct {
+	DictName string `p:"dictName"` //字典名称
+	DictType string `p:"dictType"` //字典类型
+	Status   string `p:"status"`   //字典状态
+	comModel.PageReq
+}
+
+// SysDictTypeAddReq 新增操作请求参数
+type SysDictTypeAddReq struct {
+	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"`
+	CreateBy uint64
+}
+
+type SysDictTypeEditReq struct {
+	SysDictTypeAddReq
+	DictId   int64 `p:dictId v:required|min:1#主键ID不能为空|主键ID必须为大于0的值`
+	UpdateBy uint64
+}
+
+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"` // 创建日期
+}

+ 28 - 0
app/system/model/sys_job.go

@@ -0,0 +1,28 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package model
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysJob is the golang structure for table sys_job.
+type SysJob struct {
+	JobId          int64       `orm:"job_id,primary"    json:"jobId"`          // 任务ID
+	JobName        string      `orm:"job_name,primary"  json:"jobName"`        // 任务名称
+	JobParams      string      `orm:"job_params"        json:"jobParams"`      // 参数
+	JobGroup       string      `orm:"job_group,primary" json:"jobGroup"`       // 任务组名
+	InvokeTarget   string      `orm:"invoke_target"     json:"invokeTarget"`   // 调用目标字符串
+	CronExpression string      `orm:"cron_expression"   json:"cronExpression"` // cron执行表达式
+	MisfirePolicy  int         `orm:"misfire_policy"    json:"misfirePolicy"`  // 计划执行策略(1多次执行 2执行一次)
+	Concurrent     int         `orm:"concurrent"        json:"concurrent"`     // 是否并发执行(0允许 1禁止)
+	Status         int         `orm:"status"            json:"status"`         // 状态(0正常 1暂停)
+	CreateBy       uint64      `orm:"create_by"         json:"createBy"`       // 创建者
+	UpdateBy       uint64      `orm:"update_by"         json:"updateBy"`       // 更新者
+	Remark         string      `orm:"remark"            json:"remark"`         // 备注信息
+	CreatedAt      *gtime.Time `orm:"created_at"        json:"createdAt"`      // 创建时间
+	UpdatedAt      *gtime.Time `orm:"updated_at"        json:"updatedAt"`      // 更新时间
+	DeletedAt      *gtime.Time `orm:"deleted_at"        json:"deletedAt"`      // 删除时间
+}

+ 36 - 0
app/system/model/sys_login_log.go

@@ -0,0 +1,36 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package model
+
+import (
+	comModel "gfast/app/common/model"
+	"gfast/app/system/model/internal"
+)
+
+// SysLoginLog is the golang structure for table sys_login_log.
+type SysLoginLog internal.SysLoginLog
+
+// Fill with you ideas below.
+
+// LoginLogParams 登录日志写入参数
+type LoginLogParams struct {
+	Status    int
+	Username  string
+	Ip        string
+	UserAgent string
+	Msg       string
+	Module    string
+}
+
+// SysLoginLogSearchReq 查询列表请求参数
+type SysLoginLogSearchReq struct {
+	LoginName     string `p:"userName"`      //登陆名
+	Status        string `p:"status"`        //状态
+	Ipaddr        string `p:"ipaddr"`        //登录地址
+	SortName      string `p:"orderByColumn"` //排序字段
+	SortOrder     string `p:"isAsc"`         //排序方式
+	LoginLocation string `p:"loginLocation"` //登录地点
+	comModel.PageReq
+}

+ 14 - 0
app/system/model/sys_model_info.go

@@ -0,0 +1,14 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package model
+
+import (
+	"gfast/app/system/model/internal"
+)
+
+// SysModelInfo is the golang structure for table sys_model_info.
+type SysModelInfo internal.SysModelInfo
+
+// Fill with you ideas below.

+ 29 - 0
app/system/model/sys_oper_log.go

@@ -0,0 +1,29 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package model
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysOperLog is the golang structure for table sys_oper_log.
+type SysOperLog struct {
+	OperId        uint64      `orm:"oper_id,primary" json:"operId"`        // 日志主键
+	Title         string      `orm:"title"           json:"title"`         // 模块标题
+	BusinessType  int         `orm:"business_type"   json:"businessType"`  // 业务类型(0其它 1新增 2修改 3删除)
+	Method        string      `orm:"method"          json:"method"`        // 方法名称
+	RequestMethod string      `orm:"request_method"  json:"requestMethod"` // 请求方式
+	OperatorType  int         `orm:"operator_type"   json:"operatorType"`  // 操作类别(0其它 1后台用户 2手机端用户)
+	OperName      string      `orm:"oper_name"       json:"operName"`      // 操作人员
+	DeptName      string      `orm:"dept_name"       json:"deptName"`      // 部门名称
+	OperUrl       string      `orm:"oper_url"        json:"operUrl"`       // 请求URL
+	OperIp        string      `orm:"oper_ip"         json:"operIp"`        // 主机地址
+	OperLocation  string      `orm:"oper_location"   json:"operLocation"`  // 操作地点
+	OperParam     string      `orm:"oper_param"      json:"operParam"`     // 请求参数
+	JsonResult    string      `orm:"json_result"     json:"jsonResult"`    // 返回参数
+	Status        int         `orm:"status"          json:"status"`        // 操作状态(0正常 1异常)
+	ErrorMsg      string      `orm:"error_msg"       json:"errorMsg"`      // 错误消息
+	OperTime      *gtime.Time `orm:"oper_time"       json:"operTime"`      // 操作时间
+}

+ 24 - 0
app/system/model/sys_post.go

@@ -0,0 +1,24 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package model
+
+import (
+	"github.com/gogf/gf/os/gtime"
+)
+
+// SysPost is the golang structure for table sys_post.
+type SysPost struct {
+	PostId    int64       `orm:"post_id,primary" json:"postId"`    // 岗位ID
+	PostCode  string      `orm:"post_code"       json:"postCode"`  // 岗位编码
+	PostName  string      `orm:"post_name"       json:"postName"`  // 岗位名称
+	PostSort  int         `orm:"post_sort"       json:"postSort"`  // 显示顺序
+	Status    string      `orm:"status"          json:"status"`    // 状态(0正常 1停用)
+	Remark    string      `orm:"remark"          json:"remark"`    // 备注
+	CreatedBy uint64      `orm:"created_by"      json:"createdBy"` // 创建人
+	UpdatedBy uint64      `orm:"updated_by"      json:"updatedBy"` // 修改人
+	CreatedAt *gtime.Time `orm:"created_at"      json:"createdAt"` // 创建时间
+	UpdatedAt *gtime.Time `orm:"updated_at"      json:"updatedAt"` // 修改时间
+	DeletedAt *gtime.Time `orm:"deleted_at"      json:"deletedAt"` // 删除时间
+}

+ 34 - 0
app/system/model/sys_role.go

@@ -0,0 +1,34 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package model
+
+import (
+	comModel "gfast/app/common/model"
+	"gfast/app/system/model/internal"
+)
+
+// SysRole is the golang structure for table sys_role.
+type SysRole internal.SysRole
+
+// Fill with you ideas below.
+//分页请求参数
+type SelectPageReq struct {
+	RoleName string `p:"roleName"` //参数名称
+	Status   string `p:"status"`   //状态
+	comModel.PageReq
+}
+
+//修改状态参数
+type StatusSetReq struct {
+	RoleId uint `p:"roleId" v:"required#角色ID不能为空"`
+	Status uint `p:"status" v:"required#状态不能为空"`
+}
+
+//角色数据授权参数
+type DataScopeReq struct {
+	RoleId    uint   `p:"roleId" v:"required#角色ID不能为空"`
+	DataScope uint   `p:"dataScope" v:"required#权限范围不能为空"`
+	DeptIds   []uint `p:"deptIds"`
+}

+ 14 - 0
app/system/model/sys_role_dept.go

@@ -0,0 +1,14 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package model
+
+import (
+	"gfast/app/system/model/internal"
+)
+
+// SysRoleDept is the golang structure for table sys_role_dept.
+type SysRoleDept internal.SysRoleDept
+
+// Fill with you ideas below.

+ 114 - 0
app/system/model/sys_user.go

@@ -0,0 +1,114 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package model
+
+import (
+	comModel "gfast/app/common/model"
+	"gfast/app/system/model/internal"
+)
+
+// SysUser is the golang structure for table sys_user.
+type SysUser internal.SysUser
+
+// Fill with you ideas below.
+
+// LoginParamsReq 登陆参数
+type LoginParamsReq struct {
+	Username   string `p:"username" v:"required#用户名不能为空"`
+	Password   string `p:"password" v:"required#密码不能为空"`
+	VerifyCode string `p:"verifyCode" v:"required#验证码不能为空"`
+	VerifyKey  string `p:"verifyKey"`
+}
+
+// LoginUserRes 登录返回
+type LoginUserRes struct {
+	Id           uint64 `orm:"id,primary"       json:"id"`           //
+	UserName     string `orm:"user_name,unique" json:"userName"`     // 用户名
+	UserNickname string `orm:"user_nickname"    json:"userNickname"` // 用户昵称
+	UserPassword string `orm:"user_password"    json:"userPassword"` // 登录密码;cmf_password加密
+	UserSalt     string `orm:"user_salt"        json:"userSalt"`     // 加密盐
+	UserStatus   uint   `orm:"user_status"      json:"userStatus"`   // 用户状态;0:禁用,1:正常,2:未验证
+	IsAdmin      int    `orm:"is_admin"         json:"isAdmin"`      // 是否后台管理员 1 是  0   否
+	Avatar       string `orm:"avatar" json:"avatar"`                 //头像
+	DeptId       uint64 `orm:"dept_id"       json:"deptId"`          //部门id
+}
+
+// SysUserSearchReq 用户搜索请求参数
+type SysUserSearchReq struct {
+	DeptId      string  `p:"deptId"` //部门id
+	DeptIds     []int64 //所属部门id数据
+	Phonenumber string  `p:"phonenumber"`
+	Status      string  `p:"status"`
+	KeyWords    string  `p:"userName"`
+	comModel.PageReq
+}
+
+// SetUserReq 添加修改用户公用请求字段
+type SetUserReq struct {
+	DeptId      uint64  `p:"deptId" v:"required#用户部门不能为空"` //所属部门
+	Email       string  `p:"email" v:"email#邮箱格式错误"`       //邮箱
+	NickName    string  `p:"nickName" v:"required#用户昵称不能为空"`
+	Phonenumber string  `p:"phonenumber" 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   否
+}
+
+// AddUserReq 添加用户参数
+type AddUserReq struct {
+	SetUserReq
+	UserName string `p:"userName" v:"required#用户账号不能为空"`
+	Password string `p:"password" v:"required|password#密码不能为空|密码以字母开头,只能包含字母、数字和下划线,长度在6~18之间"`
+	UserSalt string
+}
+
+type EditUserReq struct {
+	SetUserReq
+	UserId int `p:"userId" v:"required#用户id不能为空"`
+}
+
+type SysUserRoleDeptRes struct {
+	*SysUser
+	Dept     *SysDept `json:"dept"`
+	RoleInfo []*struct {
+		RoleId uint   `json:"roleId"`
+		Name   string `json:"name"`
+	} `json:"roleInfo"`
+	Post []*struct {
+		PostId   int64  `json:"postId"`
+		PostName string `json:"postName"`
+	} `json:"post"`
+}
+
+// SysUserResetPwdReq 重置用户密码状态参数
+type SysUserResetPwdReq struct {
+	Id       uint64 `p:"userId" v:"required#用户id不能为空"`
+	Password string `p:"password" v:"required|password#密码不能为空|密码以字母开头,只能包含字母、数字和下划线,长度在6~18之间"`
+}
+
+// SysUserStatusReq 设置用户状态参数
+type SysUserStatusReq struct {
+	Id         uint64 `p:"userId" v:"required#用户id不能为空"`
+	UserStatus uint   `p:"status" v:"required#用户状态不能为空"`
+}
+
+// ProfileUpReq 个人中心修改用户信息参数
+type ProfileUpReq struct {
+	UserId       uint64
+	UserNickname string `p:"userNickname" v:"required#用户昵称不能为空" orm:"user_nickname"` // 用户昵称
+	Mobile       string `p:"mobile" v:"required|phone#手机号不能为空|手机号格式错误" orm:"mobile,unique"`
+	UserEmail    string `p:"userEmail" v:"email#邮箱格式错误" orm:"user_email"`
+	Sex          int    `p:"sex" orm:"sex"`
+}
+
+// ProfileUpdatePwdReq 个人中心修改用户密码
+type ProfileUpdatePwdReq struct {
+	UserId      uint64
+	OldPassword string `p:"oldPassword" v:"required#旧密码不能为空"`
+	NewPassword string `p:"newPassword" v:"required#新密码不能为空"`
+}

+ 22 - 0
app/system/model/sys_user_online.go

@@ -0,0 +1,22 @@
+// ==========================================================================
+// This is auto-generated by gf cli tool. Fill this file as you wish.
+// ==========================================================================
+
+package model
+
+import (
+	comModel "gfast/app/common/model"
+	"gfast/app/system/model/internal"
+)
+
+// SysUserOnline is the golang structure for table sys_user_online.
+type SysUserOnline internal.SysUserOnline
+
+// Fill with you ideas below.
+
+// SysUserOnlineSearchReq 列表搜索参数
+type SysUserOnlineSearchReq struct {
+	Username string `p:"userName"`
+	Ip       string `p:"ipaddr"`
+	comModel.PageReq
+}

+ 14 - 0
app/system/model/sys_user_post.go

@@ -0,0 +1,14 @@
+// =================================================================================
+// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
+// =================================================================================
+
+package model
+
+import (
+	"gfast/app/system/model/internal"
+)
+
+// SysUserPost is the golang structure for table sys_user_post.
+type SysUserPost internal.SysUserPost
+
+// Fill with you ideas below.

+ 19 - 0
app/system/model/sys_web_set.go

@@ -0,0 +1,19 @@
+// =================================================================================
+// Code generated by GoFrame CLI tool. DO NOT EDIT.
+// =================================================================================
+
+package model
+
+import "github.com/gogf/gf/frame/g"
+
+// SysWebSet is the golang structure for table sys_web_set.
+type SysWebSet struct {
+	WebId      int    `orm:"web_id,primary" json:"webId"`      // 主键
+	WebContent string `orm:"web_content"    json:"webContent"` // 站点信息
+}
+
+// updateReq 用于存储页面更新(新增、修改)网址的信息
+type SysWebSetUpdateReq struct {
+	WebId      int   `p:"web_id"`
+	WebContent g.Map `p:"webContent" v:"required#站点信息不能为空"` // 站点信息
+}

+ 152 - 0
app/system/router/router.go

@@ -0,0 +1,152 @@
+/*
+* @desc: admin router
+* @company:云南省奇讯科技有限公司
+* @Author: yixiaohu
+* @Date:   2021/3/11 10:55
+ */
+
+package router
+
+import (
+	"gfast/app/system/api"
+	"gfast/middleware"
+	"github.com/gogf/gf/frame/g"
+	"github.com/gogf/gf/net/ghttp"
+)
+
+func init() {
+	s := g.Server()
+	s.Group("/", func(group *ghttp.RouterGroup) {
+		group.Group("/system", func(group *ghttp.RouterGroup) {
+			//gToken拦截器
+			api.GfToken.Middleware(group)
+			//context拦截器
+			group.Middleware(middleware.Ctx, middleware.Auth)
+			//后台操作日志记录
+			group.Hook("/*", ghttp.HookAfterOutput, api.SysOperLog.OperationLog)
+			//后台上传
+			group.Group("/upload", func(group *ghttp.RouterGroup) {
+				//单图上传
+				group.POST("/upImg", api.Upload.UpImg)
+			})
+			//用户相关
+			group.Group("/user", func(group *ghttp.RouterGroup) {
+				//获取用户信息
+				group.GET("/getInfo", api.User.GetInfo)
+				//获取用户菜单
+				group.GET("/getRouters", api.User.GetRouters)
+				//个人中心
+				group.GET("/profile", api.UserProfile.Profile)
+				//头像上传
+				group.POST("/avatar", api.UserProfile.Avatar)
+				//修改用户信息
+				group.PUT("/edit", api.UserProfile.Edit)
+				//修改密码
+				group.PUT("/updatePwd", api.UserProfile.UpdatePwd)
+			})
+			//配置相关
+			group.Group("/config", func(group *ghttp.RouterGroup) {
+				//获取字典分类列表
+				group.GET("/dict/type/list", api.DictType.List)
+				group.POST("/dict/type/add", api.DictType.Add)
+				group.GET("/dict/type/one", api.DictType.Get)
+				group.PUT("/dict/type/edit", api.DictType.Edit)
+				group.DELETE("/dict/type/delete", api.DictType.Delete)
+				//字典数据
+				group.GET("/dict/data/GetDictData", api.DictData.GetDictData)
+				group.GET("/dict/data/list", api.DictData.List)
+				group.POST("/dict/data/add", api.DictData.Add)
+				group.GET("/dict/data/one", api.DictData.Get)
+				group.PUT("/dict/data/edit", api.DictData.Edit)
+				group.DELETE("/dict/data/delete", api.DictData.Delete)
+				//系统参数管理
+				group.GET("/sysConfig/list", api.SysConfig.List)
+				group.POST("/sysConfig/add", api.SysConfig.Add)
+				group.GET("/sysConfig/one", api.SysConfig.Get)
+				group.PUT("/sysConfig/edit", api.SysConfig.Edit)
+				group.DELETE("/sysConfig/delete", api.SysConfig.Delete)
+				//站点设置
+				group.GET("/sysWebSet", api.SysWebSet.Get)
+				group.POST("/sysWebSet/update", api.SysWebSet.Update)
+			})
+			// 权限管理
+			group.Group("/auth", func(group *ghttp.RouterGroup) {
+				//菜单管理
+				group.GET("menuList", api.AuthRule.MenuList)
+				group.GET("getMenus", api.AuthRule.GetMenus)
+				group.POST("addMenu", api.AuthRule.AddMenuPost)
+				group.GET("modelOptions", api.AuthRule.ModelOptions)
+				group.GET("menu", api.AuthRule.GetMenu)
+				group.PUT("editMenu", api.AuthRule.EditPost)
+				group.DELETE("deleteMenu", api.AuthRule.DeleteMenu)
+				//角色管理
+				group.GET("roleList", api.SysRole.RoleList)
+				group.GET("addRole", api.SysRole.GetRoleMenu)
+				group.POST("addRole", api.SysRole.AddRole)
+				group.GET("editRole", api.SysRole.GetRole)
+				group.PUT("editRole", api.SysRole.EditRole)
+				group.PUT("statusSetRole", api.SysRole.StatusSetRole)
+				group.PUT("roleDataScope", api.SysRole.RoleDataScope)
+				group.DELETE("deleteRole", api.SysRole.DeleteRole)
+				// 部门管理
+				group.GET("deptList", api.Dept.List)
+				group.POST("deptAdd", api.Dept.Add)
+				group.GET("deptGet", api.Dept.Get)
+				group.PUT("deptEdit", api.Dept.Edit)
+				group.DELETE("deptDelete", api.Dept.Delete)
+				group.GET("deptTreeSelect", api.Dept.TreeSelect)
+				group.GET("roleDeptTreeSelect", api.Dept.RoleDeptTreeSelect)
+				//岗位管理
+				group.GET("postList", api.SysPost.List)
+				group.GET("postGet", api.SysPost.Get)
+				group.POST("postAdd", api.SysPost.Add)
+				group.PUT("postEdit", api.SysPost.Edit)
+				group.DELETE("postDelete", api.SysPost.Delete)
+				//用户管理
+				group.GET("userList", api.User.UserList)
+				group.GET("userGet", api.User.Get)
+				group.POST("addUser", api.User.AddUser)
+				group.GET("getEditUser", api.User.GetEditUser)
+				group.PUT("editUser", api.User.EditUser)
+				group.PUT("resetUserPwd", api.User.ResetUserPwd)
+				group.PUT("changeUserStatus", api.User.ChangeUserStatus)
+				group.DELETE("deleteUser", api.User.DeleteUser)
+			})
+			//系统监控
+			group.Group("/monitor", func(group *ghttp.RouterGroup) {
+				//在线用户管理
+				group.Group("/online", func(group *ghttp.RouterGroup) {
+					group.GET("list", api.SysUserOnline.List)
+					group.PUT("forceLogout", api.SysUserOnline.ForceLogout)
+				})
+				//定时任务管理
+				group.Group("/job", func(group *ghttp.RouterGroup) {
+					group.GET("list", api.SysJob.List)
+					group.POST("add", api.SysJob.Add)
+					group.GET("get", api.SysJob.Get)
+					group.PUT("edit", api.SysJob.Edit)
+					group.PUT("start", api.SysJob.Start)
+					group.PUT("stop", api.SysJob.Stop)
+					group.DELETE("delete", api.SysJob.Delete)
+				})
+				//服务监控
+				group.Group("/server", func(group *ghttp.RouterGroup) {
+					group.GET("info", api.SysMonitor.Info)
+				})
+				//登录日志
+				group.Group("/loginLog", func(group *ghttp.RouterGroup) {
+					group.GET("list", api.SysLoginLog.List)
+					group.DELETE("delete", api.SysLoginLog.Delete)
+					group.DELETE("clear", api.SysLoginLog.Clear)
+				})
+				//操作日志
+				group.Group("/operLog", func(group *ghttp.RouterGroup) {
+					group.GET("list", api.SysOperLog.List)
+					group.GET("detail", api.SysOperLog.Detail)
+					group.DELETE("delete", api.SysOperLog.Delete)
+					group.DELETE("clear", api.SysOperLog.Clear)
+				})
+			})
+		})
+	})
+}

+ 0 - 0
app/system/service/.gitkeep


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