diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..c7ea37b
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* linguist-language=GO
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b3b0b38
--- /dev/null
+++ b/.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
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..25c8139
--- /dev/null
+++ b/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
diff --git a/README.MD b/README.MD
new file mode 100644
index 0000000..c2f1b68
--- /dev/null
+++ b/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)
+
+## 演示图
+
+
+
+ ![](https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg) |
+ ![](https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg) |
+
+
+ ![](https://oscimg.oschina.net/oscnet/707825ad3f29de74a8d6d02fbd73ad631ea.jpg) |
+ ![](https://oscimg.oschina.net/oscnet/46be40cc6f01aa300eed53a19b5012bf484.jpg) |
+
+
+ ![](https://oscimg.oschina.net/oscnet/4284796d4cea240d181b8f2201813dda710.jpg) |
+ ![](https://oscimg.oschina.net/oscnet/3ecfac87a049f7fe36abbcaafb2c40d36cf.jpg) |
+
+
+ ![](https://oscimg.oschina.net/oscnet/71c2d48905221a09a728df4aff4160b8607.jpg) |
+ ![](https://oscimg.oschina.net/oscnet/c14c1ee9a64a6a9c2c22f67d43198767dbe.jpg) |
+
+
+ ![](https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg) |
+ ![](https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg) |
+
+
+ ![](https://oscimg.oschina.net/oscnet/fdea1d8bb8625c27bf964176a2c8ebc6945.jpg) |
+ ![](https://oscimg.oschina.net/oscnet/509d2708cfd762b6e6339364cac1cc1970c.jpg) |
+
+
+ ![](https://oscimg.oschina.net/oscnet/up-f1fd681cc9d295db74e85ad6d2fe4389454.png) |
+ ![](https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png) |
+
+
+
+## 感谢(排名不分先后)
+> 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群
+
+>
+
+> 快来加入群聊【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 表名
+```
+
diff --git a/app/common/adapter/upload.go b/app/common/adapter/upload.go
new file mode 100644
index 0000000..d045219
--- /dev/null
+++ b/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)
+}
diff --git a/app/common/adapter/upload_local_apapter.go b/app/common/adapter/upload_local_apapter.go
new file mode 100644
index 0000000..33fde70
--- /dev/null
+++ b/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
+}
diff --git a/app/common/adapter/upload_tencent_cos_adapter.go b/app/common/adapter/upload_tencent_cos_adapter.go
new file mode 100644
index 0000000..21e6337
--- /dev/null
+++ b/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
+}
diff --git a/app/common/api/captcha.go b/app/common/api/captcha.go
new file mode 100644
index 0000000..750927d
--- /dev/null
+++ b/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})
+}
diff --git a/app/common/api/common_base.go b/app/common/api/common_base.go
new file mode 100644
index 0000000..d670b31
--- /dev/null
+++ b/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...)
+}
diff --git a/app/common/dao/casbin_rule.go b/app/common/dao/casbin_rule.go
new file mode 100644
index 0000000..2db608f
--- /dev/null
+++ b/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.
diff --git a/app/common/dao/internal/casbin_rule.go b/app/common/dao/internal/casbin_rule.go
new file mode 100644
index 0000000..11defc3
--- /dev/null
+++ b/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 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 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 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 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 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 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
+// 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 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 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 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 < 0, which means it clear the cache with given .
+// If the parameter = 0, which means it never expires.
+// If the parameter > 0, which means it expires after .
+//
+// The optional parameter is used to bind a name to the cache, which means you can later
+// control the cache like changing the or clearing the cache with specified .
+//
+// 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 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 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 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 should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter 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 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 should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter 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 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 .
+// It calls function Struct if is type of *struct/**struct.
+// It calls function Structs if is type of *[]struct/*[]*struct.
+//
+// The optional parameter 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()}
+}
diff --git a/app/common/dao/internal/sys_config.go b/app/common/dao/internal/sys_config.go
new file mode 100644
index 0000000..759dfed
--- /dev/null
+++ b/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",
+ }
+}
diff --git a/app/common/dao/sys_config.go b/app/common/dao/sys_config.go
new file mode 100644
index 0000000..e360ec7
--- /dev/null
+++ b/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(),
+ }
+}
diff --git a/app/common/global/cache_key.go b/app/common/global/cache_key.go
new file mode 100644
index 0000000..8925aae
--- /dev/null
+++ b/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"
+)
diff --git a/app/common/model/casbin_rule.go b/app/common/model/casbin_rule.go
new file mode 100644
index 0000000..f1970c7
--- /dev/null
+++ b/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.
diff --git a/app/common/model/internal/casbin_rule.go b/app/common/model/internal/casbin_rule.go
new file mode 100644
index 0000000..b75f131
--- /dev/null
+++ b/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"` //
+}
diff --git a/app/common/model/req.go b/app/common/model/req.go
new file mode 100644
index 0000000..86c1984
--- /dev/null
+++ b/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
+}
diff --git a/app/common/model/sys_config.go b/app/common/model/sys_config.go
new file mode 100644
index 0000000..5083b2d
--- /dev/null
+++ b/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
+}
diff --git a/app/common/service/cache.go b/app/common/service/cache.go
new file mode 100644
index 0000000..6a6b687
--- /dev/null
+++ b/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 - pair, which is expired after .
+// It does not expire if <= 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 - pair if does not exist in the cache,
+// which is expired after . It does not expire if <= 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 , which is expired after .
+//
+// It does not expire if <= 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 .
+// 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 ,
+// or sets - pair and returns if does not exist in the cache.
+// The tagKey-value pair expires after .
+//
+// It does not expire if <= 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 , or sets with result of function
+// and returns its result if does not exist in the cache. The tagKey-value pair expires
+// after . It does not expire if <= 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 , or sets with result of function
+// and returns its result if does not exist in the cache. The tagKey-value pair expires
+// after . It does not expire if <= 0.
+//
+// Note that the function 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 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 in the cache, and returns its value.
+func (c *cacheTagService) Remove(key interface{}) interface{} {
+ v, _ := c.cache.Remove(key)
+ return v
+}
+
+// Removes deletes in the cache.
+func (c *cacheTagService) Removes(keys []interface{}) {
+ c.cache.Remove(keys...)
+}
+
+// Remove deletes the 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 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
+}
diff --git a/app/common/service/captcha.go b/app/common/service/captcha.go
new file mode 100644
index 0000000..281cf7b
--- /dev/null
+++ b/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)
+}
diff --git a/app/common/service/casbin.go b/app/common/service/casbin.go
new file mode 100644
index 0000000..dd48c55
--- /dev/null
+++ b/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
+}
diff --git a/app/common/service/sys_config.go b/app/common/service/sys_config.go
new file mode 100644
index 0000000..116707c
--- /dev/null
+++ b/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
+}
diff --git a/app/system/api/auth.go b/app/system/api/auth.go
new file mode 100644
index 0000000..f153653
--- /dev/null
+++ b/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 = >oken.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
+}
diff --git a/app/system/api/sys_auth_rule.go b/app/system/api/sys_auth_rule.go
new file mode 100644
index 0000000..1c83bcd
--- /dev/null
+++ b/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, "删除成功")
+}
diff --git a/app/system/api/sys_base.go b/app/system/api/sys_base.go
new file mode 100644
index 0000000..716e71a
--- /dev/null
+++ b/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
+}
diff --git a/app/system/api/sys_config.go b/app/system/api/sys_config.go
new file mode 100644
index 0000000..aedbf48
--- /dev/null
+++ b/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, "删除成功")
+}
diff --git a/app/system/api/sys_dept.go b/app/system/api/sys_dept.go
new file mode 100644
index 0000000..dca3a72
--- /dev/null
+++ b/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)
+}
diff --git a/app/system/api/sys_dict_data.go b/app/system/api/sys_dict_data.go
new file mode 100644
index 0000000..c552c9d
--- /dev/null
+++ b/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)
+}
diff --git a/app/system/api/sys_dict_type.go b/app/system/api/sys_dict_type.go
new file mode 100644
index 0000000..52af686
--- /dev/null
+++ b/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)
+}
diff --git a/app/system/api/sys_job.go b/app/system/api/sys_job.go
new file mode 100644
index 0000000..8f066d4
--- /dev/null
+++ b/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, "删除成功")
+}
diff --git a/app/system/api/sys_login_log.go b/app/system/api/sys_login_log.go
new file mode 100644
index 0000000..7391405
--- /dev/null
+++ b/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, "清除成功")
+}
diff --git a/app/system/api/sys_monitor.go b/app/system/api/sys_monitor.go
new file mode 100644
index 0000000..8ad819e
--- /dev/null
+++ b/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)
+}
diff --git a/app/system/api/sys_oper_log.go b/app/system/api/sys_oper_log.go
new file mode 100644
index 0000000..446e552
--- /dev/null
+++ b/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)
+}
diff --git a/app/system/api/sys_post.go b/app/system/api/sys_post.go
new file mode 100644
index 0000000..05a6391
--- /dev/null
+++ b/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, "删除信息成功")
+}
diff --git a/app/system/api/sys_role.go b/app/system/api/sys_role.go
new file mode 100644
index 0000000..4696205
--- /dev/null
+++ b/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, "删除成功")
+
+}
diff --git a/app/system/api/sys_user.go b/app/system/api/sys_user.go
new file mode 100644
index 0000000..eba58b5
--- /dev/null
+++ b/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, "删除成功")
+}
diff --git a/app/system/api/sys_user_online.go b/app/system/api/sys_user_online.go
new file mode 100644
index 0000000..b2e0d54
--- /dev/null
+++ b/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, "用户已退出")
+}
diff --git a/app/system/api/sys_web_set.go b/app/system/api/sys_web_set.go
new file mode 100644
index 0000000..1db3dc5
--- /dev/null
+++ b/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)
+}
diff --git a/app/system/api/upload.go b/app/system/api/upload.go
new file mode 100644
index 0000000..bb4f90f
--- /dev/null
+++ b/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)
+}
diff --git a/app/system/api/user_Profile.go b/app/system/api/user_Profile.go
new file mode 100644
index 0000000..8664a3e
--- /dev/null
+++ b/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, "修改成功")
+ }
+}
diff --git a/app/system/dao/.gitkeep b/app/system/dao/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/app/system/dao/context.go b/app/system/dao/context.go
new file mode 100644
index 0000000..3a25e92
--- /dev/null
+++ b/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
+}
diff --git a/app/system/dao/internal/sys_auth_rule.go b/app/system/dao/internal/sys_auth_rule.go
new file mode 100644
index 0000000..6868efc
--- /dev/null
+++ b/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 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 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 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 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 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 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
+// 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 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 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 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 < 0, which means it clear the cache with given .
+// If the parameter = 0, which means it never expires.
+// If the parameter > 0, which means it expires after .
+//
+// The optional parameter is used to bind a name to the cache, which means you can later
+// control the cache like changing the or clearing the cache with specified .
+//
+// 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 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 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 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 should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter 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 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 should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter 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 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 .
+// It calls function Struct if is type of *struct/**struct.
+// It calls function Structs if is type of *[]struct/*[]*struct.
+//
+// The optional parameter 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()}
+}
diff --git a/app/system/dao/internal/sys_dept.go b/app/system/dao/internal/sys_dept.go
new file mode 100644
index 0000000..5ea8ecc
--- /dev/null
+++ b/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",
+ }
+}
diff --git a/app/system/dao/internal/sys_dict_data.go b/app/system/dao/internal/sys_dict_data.go
new file mode 100644
index 0000000..69cf33a
--- /dev/null
+++ b/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 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 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 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 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 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 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
+// 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 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 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 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 < 0, which means it clear the cache with given .
+// If the parameter = 0, which means it never expires.
+// If the parameter > 0, which means it expires after .
+//
+// The optional parameter is used to bind a name to the cache, which means you can later
+// control the cache like changing the or clearing the cache with specified .
+//
+// 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 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 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 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 should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter 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 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 should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter 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 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 .
+// It calls function Struct if is type of *struct/**struct.
+// It calls function Structs if is type of *[]struct/*[]*struct.
+//
+// The optional parameter 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()}
+}
diff --git a/app/system/dao/internal/sys_dict_type.go b/app/system/dao/internal/sys_dict_type.go
new file mode 100644
index 0000000..5576bc4
--- /dev/null
+++ b/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 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 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 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 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 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 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
+// 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 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 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 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 < 0, which means it clear the cache with given .
+// If the parameter = 0, which means it never expires.
+// If the parameter > 0, which means it expires after .
+//
+// The optional parameter is used to bind a name to the cache, which means you can later
+// control the cache like changing the or clearing the cache with specified .
+//
+// 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 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 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 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 should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter 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 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 should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter 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 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 .
+// It calls function Struct if is type of *struct/**struct.
+// It calls function Structs if is type of *[]struct/*[]*struct.
+//
+// The optional parameter 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()}
+}
diff --git a/app/system/dao/internal/sys_job.go b/app/system/dao/internal/sys_job.go
new file mode 100644
index 0000000..9c1f9ae
--- /dev/null
+++ b/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",
+ }
+}
diff --git a/app/system/dao/internal/sys_login_log.go b/app/system/dao/internal/sys_login_log.go
new file mode 100644
index 0000000..c043c68
--- /dev/null
+++ b/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 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 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 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 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 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 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
+// 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 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 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 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 < 0, which means it clear the cache with given .
+// If the parameter = 0, which means it never expires.
+// If the parameter > 0, which means it expires after .
+//
+// The optional parameter is used to bind a name to the cache, which means you can later
+// control the cache like changing the or clearing the cache with specified .
+//
+// 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 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 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 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 should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter 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 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 should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter 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 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 .
+// It calls function Struct if is type of *struct/**struct.
+// It calls function Structs if is type of *[]struct/*[]*struct.
+//
+// The optional parameter 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()}
+}
diff --git a/app/system/dao/internal/sys_model_info.go b/app/system/dao/internal/sys_model_info.go
new file mode 100644
index 0000000..e9fc368
--- /dev/null
+++ b/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",
+ },
+ }
+)
diff --git a/app/system/dao/internal/sys_oper_log.go b/app/system/dao/internal/sys_oper_log.go
new file mode 100644
index 0000000..62d6aa6
--- /dev/null
+++ b/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",
+ }
+}
diff --git a/app/system/dao/internal/sys_post.go b/app/system/dao/internal/sys_post.go
new file mode 100644
index 0000000..ef6045c
--- /dev/null
+++ b/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",
+ }
+}
diff --git a/app/system/dao/internal/sys_role.go b/app/system/dao/internal/sys_role.go
new file mode 100644
index 0000000..5bb4f86
--- /dev/null
+++ b/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 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 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 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 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 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 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
+// 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 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 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 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 < 0, which means it clear the cache with given .
+// If the parameter = 0, which means it never expires.
+// If the parameter > 0, which means it expires after .
+//
+// The optional parameter is used to bind a name to the cache, which means you can later
+// control the cache like changing the or clearing the cache with specified .
+//
+// 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 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 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 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 should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter 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 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 should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter 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 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 .
+// It calls function Struct if is type of *struct/**struct.
+// It calls function Structs if is type of *[]struct/*[]*struct.
+//
+// The optional parameter 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()}
+}
diff --git a/app/system/dao/internal/sys_role_dept.go b/app/system/dao/internal/sys_role_dept.go
new file mode 100644
index 0000000..32928fd
--- /dev/null
+++ b/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",
+ },
+ }
+)
diff --git a/app/system/dao/internal/sys_user.go b/app/system/dao/internal/sys_user.go
new file mode 100644
index 0000000..4e77f7d
--- /dev/null
+++ b/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 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 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 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 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 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 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
+// 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 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 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 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 < 0, which means it clear the cache with given .
+// If the parameter = 0, which means it never expires.
+// If the parameter > 0, which means it expires after .
+//
+// The optional parameter is used to bind a name to the cache, which means you can later
+// control the cache like changing the or clearing the cache with specified .
+//
+// 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 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 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 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 should be type of *struct/**struct. If type **struct is given,
+// it can create the struct internally during converting.
+//
+// The optional parameter 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 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 should be type of *[]struct/*[]*struct. It can create and fill the struct
+// slice internally during converting.
+//
+// The optional parameter 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 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 .
+// It calls function Struct if is type of *struct/**struct.
+// It calls function Structs if