├── boot ├── .gitkeep └── boot.go ├── i18n └── .gitkeep ├── app ├── dao │ ├── .gitkeep │ ├── user.go │ ├── relation.go │ ├── role_resource.go │ ├── role.go │ ├── resource.go │ └── internal │ │ ├── role.go │ │ ├── user.go │ │ ├── relation.go │ │ ├── resource.go │ │ └── role_resource.go ├── model │ ├── .gitkeep │ ├── role_resource.go │ ├── relation.go │ ├── internal │ │ ├── relation.go │ │ ├── role.go │ │ ├── role_resource.go │ │ ├── user.go │ │ └── resource.go │ ├── role.go │ ├── user.go │ └── resource.go ├── service │ ├── .gitkeep │ ├── user_test.go │ ├── resource_test.go │ ├── relation_test.go │ ├── relation.go │ ├── user.go │ ├── role.go │ └── resource.go ├── api │ ├── hello │ │ └── hello.go │ └── v1 │ │ ├── user.go │ │ ├── relation.go │ │ ├── resource.go │ │ └── role.go └── middleware │ ├── common.go │ └── jwt.go ├── config ├── .gitkeep ├── config.yaml └── configDev.yaml ├── docker └── .gitkeep ├── document └── .gitkeep ├── router ├── .gitkeep └── router.go ├── template └── .gitkeep ├── public ├── html │ └── .gitkeep ├── plugin │ └── .gitkeep └── resource │ ├── css │ └── .gitkeep │ ├── js │ └── .gitkeep │ └── image │ └── .gitkeep ├── packed ├── packed.go └── swagger.go ├── .gitattributes ├── main.go ├── .gitignore ├── go.mod ├── library ├── common │ ├── id.go │ ├── page.go │ ├── tree_test.go │ └── tree.go └── response │ └── response.go ├── Dockerfile ├── README.MD ├── LICENSE └── swagger └── swagger.json /boot/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /i18n/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/dao/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/model/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docker/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /document/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /router/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/service/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/html/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/plugin/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/resource/css/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/resource/js/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/resource/image/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packed/packed.go: -------------------------------------------------------------------------------- 1 | package packed 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-language=GO 2 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "gf-react-admin-server/boot" 5 | _ "gf-react-admin-server/router" 6 | 7 | "github.com/gogf/gf/frame/g" 8 | ) 9 | 10 | func main() { 11 | g.Server().Run() 12 | } 13 | -------------------------------------------------------------------------------- /boot/boot.go: -------------------------------------------------------------------------------- 1 | package boot 2 | 3 | import ( 4 | _ "gf-react-admin-server/packed" 5 | "github.com/gogf/gf/frame/g" 6 | "github.com/gogf/swagger" 7 | ) 8 | 9 | func init() { 10 | s := g.Server() 11 | s.Plugin(&swagger.Swagger{}) 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .hgignore.swp 3 | .project 4 | .orig 5 | .swp 6 | .idea/ 7 | .settings/ 8 | .vscode/ 9 | vender/ 10 | log/ 11 | composer.lock 12 | gitpush.sh 13 | pkg/ 14 | bin/ 15 | cbuild 16 | */.DS_Store 17 | main 18 | .vscode 19 | go.sum -------------------------------------------------------------------------------- /app/api/hello/hello.go: -------------------------------------------------------------------------------- 1 | package hello 2 | 3 | import ( 4 | "github.com/gogf/gf/net/ghttp" 5 | ) 6 | 7 | // Hello is a demonstration route handler for output "Hello World!". 8 | func Hello(r *ghttp.Request) { 9 | r.Response.Writeln("Hello World!") 10 | } 11 | -------------------------------------------------------------------------------- /app/service/user_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gogf/gf/test/gtest" 6 | "testing" 7 | ) 8 | 9 | func TestGetUserInfos(t *testing.T) { 10 | gtest.C(t, func(*gtest.T) { 11 | userInfos, _ := User.GetUserInfos(1) 12 | fmt.Printf("%v \n", userInfos) 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module gf-react-admin-server 2 | 3 | require ( 4 | github.com/bwmarrin/snowflake v0.3.0 5 | github.com/gogf/gcache-adapter v0.1.1 6 | github.com/gogf/gf v1.15.7-0.20210416023255-30b60754e3e4 7 | github.com/gogf/gf-jwt v1.1.2 8 | github.com/gogf/swagger v1.2.0 9 | golang.org/x/crypto v0.1.0 10 | ) 11 | 12 | go 1.15 13 | -------------------------------------------------------------------------------- /library/common/id.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import "github.com/bwmarrin/snowflake" 4 | 5 | type idUtils struct{} 6 | 7 | var ( 8 | Id = &idUtils{} 9 | ) 10 | 11 | // GenerateUUID 采用雪花算法生成id 12 | func (i *idUtils) GenerateUUID() (int64, error) { 13 | node, err := snowflake.NewNode(1) 14 | if err != nil { 15 | return 0, err 16 | } 17 | return int64(node.Generate()), nil 18 | } 19 | -------------------------------------------------------------------------------- /app/service/resource_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gogf/gf/test/gtest" 6 | "testing" 7 | ) 8 | 9 | func TestGetUserMenu(t *testing.T) { 10 | gtest.C(t, func(*gtest.T) { 11 | menus, _ := Resource.GetMenuByUserId(1) 12 | fmt.Printf("%v \n", menus) 13 | }) 14 | } 15 | 16 | func TestGetUserMenuTree(t *testing.T) { 17 | gtest.C(t, func(*gtest.T) { 18 | treeNode, _ := Resource.GetMenuTreeByUserId(1) 19 | fmt.Print(treeNode) 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /app/model/role_resource.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. Fill this file as you wish. 3 | // ========================================================================== 4 | 5 | package model 6 | 7 | import ( 8 | "gf-react-admin-server/app/model/internal" 9 | ) 10 | 11 | // RoleResource is the golang structure for table admin_role_resource. 12 | type RoleResource internal.RoleResource 13 | 14 | // Fill with you ideas below. 15 | -------------------------------------------------------------------------------- /app/middleware/common.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gogf/gf/frame/g" 5 | "github.com/gogf/gf/net/ghttp" 6 | ) 7 | 8 | // 允许接口跨域请求中间件 9 | func CORS(r *ghttp.Request) { 10 | r.Response.CORSDefault() 11 | r.Middleware.Next() 12 | } 13 | 14 | // 异常记录中间件 15 | func ErrorLog(r *ghttp.Request) { 16 | r.Middleware.Next() 17 | if err := r.GetError(); err != nil { 18 | g.Log().Error(err) 19 | } 20 | } 21 | 22 | func GetPath(r *ghttp.Request) { 23 | // 获取请求路径 24 | g.Log().Infof("请求路径:[%v],请求方法:[%v], router-method:[%v], router-uri:[%v], router-regNames [%v], router-regRule:[%v]", 25 | r.RequestURI, r.Method, r.Router.Method, r.Router.Uri, r.Router.RegNames, r.Router.RegRule) 26 | r.Middleware.Next() 27 | } 28 | -------------------------------------------------------------------------------- /app/model/relation.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. Fill this file as you wish. 3 | // ========================================================================== 4 | 5 | package model 6 | 7 | import ( 8 | "gf-react-admin-server/app/model/internal" 9 | ) 10 | 11 | // Relation is the golang structure for table admin_relation. 12 | type Relation internal.Relation 13 | 14 | // Fill with you ideas below. 15 | 16 | // SaveRelationReq 创建用户关系参数 17 | type SaveRelationReq struct { 18 | UserId int `json:"userId" v:"required|min:1#用户id不能为空|用户id长度有误"` // 用户id 19 | RoleIds []int `json:"roleIds" v:"required|min-length:1#待关联角色id不能为空|至少关联一个角色id"` // 角色id slice 20 | } 21 | -------------------------------------------------------------------------------- /library/common/page.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type PageReq struct { 4 | PageNo int `json:"pageNo" d:"1" v:"required|min:1#分页页数不能为空|分页页数参数非法"` // 分页页数 5 | PageSize int `json:"pageSize" d:"10" v:"required|min:1#分页大小不能为空|分页大小参数非法"` // 分页大小 6 | } 7 | 8 | // 分页统一返回体 9 | type PageResult struct { 10 | PageNo int `json:"pageNo"` // 分页页数 11 | PageSize int `json:"pageSize"` // 分页大小 12 | Total int `json:"total"` // 总记录数 13 | Records interface{} `json:"records"` // 对应数据 14 | } 15 | 16 | // NewResult init page result. 创建一个分页返回体 17 | func NewResult(pageNo, pageSize, total int, records interface{}) PageResult { 18 | return PageResult{ 19 | PageNo: pageNo, 20 | PageSize: pageSize, 21 | Total: total, 22 | Records: records, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/dao/user.go: -------------------------------------------------------------------------------- 1 | // ============================================================================ 2 | // This is auto-generated by gf cli tool only once. Fill this file as you wish. 3 | // ============================================================================ 4 | 5 | package dao 6 | 7 | import ( 8 | "gf-react-admin-server/app/dao/internal" 9 | ) 10 | 11 | // userDao is the manager for logic model data accessing 12 | // and custom defined data operations functions management. You can define 13 | // methods on it to extend its functionality as you wish. 14 | type userDao struct { 15 | *internal.UserDao 16 | } 17 | 18 | var ( 19 | // User is globally public accessible object for table admin_user operations. 20 | User = &userDao{ 21 | internal.User, 22 | } 23 | ) 24 | 25 | // Fill with you ideas below. 26 | -------------------------------------------------------------------------------- /app/dao/relation.go: -------------------------------------------------------------------------------- 1 | // ============================================================================ 2 | // This is auto-generated by gf cli tool only once. Fill this file as you wish. 3 | // ============================================================================ 4 | 5 | package dao 6 | 7 | import ( 8 | "gf-react-admin-server/app/dao/internal" 9 | ) 10 | 11 | // relationDao is the manager for logic model data accessing 12 | // and custom defined data operations functions management. You can define 13 | // methods on it to extend its functionality as you wish. 14 | type relationDao struct { 15 | *internal.RelationDao 16 | } 17 | 18 | var ( 19 | // Relation is globally public accessible object for table admin_relation operations. 20 | Relation = &relationDao{ 21 | internal.Relation, 22 | } 23 | ) 24 | 25 | // Fill with you ideas below. 26 | -------------------------------------------------------------------------------- /app/model/internal/relation.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "github.com/gogf/gf/os/gtime" 9 | ) 10 | 11 | // Relation is the golang structure for table admin_relation. 12 | type Relation struct { 13 | Id int64 `orm:"id,primary" json:"id"` // 14 | UserId int64 `orm:"user_id" json:"userId"` // 用户id 15 | RoleId int64 `orm:"role_id" json:"roleId"` // 角色id 16 | CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 创建时间 17 | UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间 18 | DeletedAt *gtime.Time `orm:"deleted_at" json:"deletedAt"` // 删除时间 19 | } 20 | -------------------------------------------------------------------------------- /app/dao/role_resource.go: -------------------------------------------------------------------------------- 1 | // ============================================================================ 2 | // This is auto-generated by gf cli tool only once. Fill this file as you wish. 3 | // ============================================================================ 4 | 5 | package dao 6 | 7 | import ( 8 | "gf-react-admin-server/app/dao/internal" 9 | ) 10 | 11 | // roleResourceDao is the manager for logic model data accessing 12 | // and custom defined data operations functions management. You can define 13 | // methods on it to extend its functionality as you wish. 14 | type roleResourceDao struct { 15 | *internal.RoleResourceDao 16 | } 17 | 18 | var ( 19 | // RoleResource is globally public accessible object for table admin_role_resource operations. 20 | RoleResource = &roleResourceDao{ 21 | internal.RoleResource, 22 | } 23 | ) 24 | 25 | // Fill with you ideas below. 26 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM loads/alpine:3.8 2 | 3 | LABEL maintainer="john@goframe.org" 4 | 5 | ############################################################################### 6 | # INSTALLATION 7 | ############################################################################### 8 | 9 | # 设置固定的项目路径 10 | ENV WORKDIR /var/www/gf-react-admin-server 11 | 12 | # 添加应用可执行文件,并设置执行权限 13 | ADD ./bin/linux_amd64/main $WORKDIR/main 14 | RUN chmod +x $WORKDIR/main 15 | 16 | # 添加I18N多语言文件、静态文件、配置文件、模板文件 17 | ADD i18n $WORKDIR/i18n 18 | ADD public $WORKDIR/public 19 | ADD config $WORKDIR/config 20 | ADD template $WORKDIR/template 21 | 22 | ############################################################################### 23 | # START 24 | ############################################################################### 25 | WORKDIR $WORKDIR 26 | CMD ./main 27 | -------------------------------------------------------------------------------- /app/model/internal/role.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "github.com/gogf/gf/os/gtime" 9 | ) 10 | 11 | // Role is the golang structure for table admin_role. 12 | type Role struct { 13 | Id int64 `orm:"id,primary" json:"id"` // 14 | ParentId string `orm:"parent_id" json:"parentId"` // 父角色id 15 | RoleName string `orm:"role_name" json:"roleName"` // 角色名称 16 | Alias string `orm:"alias" json:"alias"` // 角色别名 17 | CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 创建时间 18 | UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间 19 | DeletedAt *gtime.Time `orm:"deleted_at" json:"deletedAt"` // 删除时间时间 20 | } 21 | -------------------------------------------------------------------------------- /app/api/v1/user.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "gf-react-admin-server/app/service" 5 | "gf-react-admin-server/library/response" 6 | "github.com/gogf/gf/net/ghttp" 7 | "github.com/gogf/gf/util/gconv" 8 | "github.com/gogf/gf/util/gvalid" 9 | ) 10 | 11 | // apiUser is user api and func receiver 12 | type userApi struct{} 13 | 14 | var ( 15 | // User to global call 16 | User = &userApi{} 17 | ) 18 | 19 | // GetUserInfos 20 | // @summary 用户详情 21 | // @tags 用户服务 22 | // @produce json 23 | // @param id path int true "用户id" 24 | // @router /v1/user/{id} [GET] 25 | func (u *userApi) GetUserInfos(r *ghttp.Request) { 26 | id := r.Get("id") 27 | if err := gvalid.Check(id, "required|integer|min:1", "用户id为空|参数类型非法|用户id长度非法"); err != nil { 28 | response.FailMsgExit(r, err.Error()) 29 | } 30 | userInfos, err := service.User.GetUserInfos(gconv.Int(id)) 31 | if err != nil { 32 | response.FailMsgExit(r, err.Error()) 33 | } 34 | response.SuccessData(r, userInfos) 35 | } 36 | -------------------------------------------------------------------------------- /config/config.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | Address: ':8199' 3 | ServerRoot: public 4 | ServerAgent: gf-react-admin-server 5 | LogPath: ./log/gf-react-admin-server/server 6 | logger: 7 | Path: ./log/gf-react-admin-server/log 8 | Level: all 9 | Stdout: true 10 | database: 11 | default: 12 | - type: mysql 13 | link: 'root:123456@tcp(127.0.0.1:3306)/go_test' 14 | debug: true 15 | logger: 16 | Path: ./log/gf-react-admin-server/sql 17 | Level: all 18 | Stdout: true 19 | redis: 20 | default: '127.0.0.1:6379,0' 21 | cache: '127.0.0.1:6379,1' 22 | jwt: 23 | ExpireTime: 60 24 | RefreshTime: 480 25 | SignKey: gf-react-admin-server 26 | Realm: gf-react-admin-server zone 27 | IdentityKey: JWT_USER_ID 28 | TokenLookup: 'header: Authorization' 29 | TokenHeadName: Bearer 30 | gfcli: 31 | gen: 32 | dao: 33 | - link: 'mysql:root:123456@tcp(127.0.0.1:3306)/go_test' 34 | tables: admin_role_resource 35 | removePrefix: admin_ 36 | -------------------------------------------------------------------------------- /config/configDev.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | Address: ':8199' 3 | ServerRoot: public 4 | ServerAgent: gf-react-admin-server 5 | LogPath: ./log/gf-react-admin-server/server 6 | logger: 7 | Path: ./log/gf-react-admin-server/log 8 | Level: all 9 | Stdout: true 10 | database: 11 | default: 12 | - type: mysql 13 | link: 'root:123456@tcp(127.0.0.1:3306)/go_test' 14 | debug: true 15 | logger: 16 | Path: ./log/gf-react-admin-server/sql 17 | Level: all 18 | Stdout: true 19 | redis: 20 | default: '127.0.0.1:6379,0' 21 | cache: '127.0.0.1:6379,1' 22 | jwt: 23 | ExpireTime: 60 24 | RefreshTime: 480 25 | SignKey: gf-react-admin-server 26 | Realm: gf-react-admin-server zone 27 | IdentityKey: JWT_USER_ID 28 | TokenLookup: 'header: Authorization' 29 | TokenHeadName: Bearer 30 | gfcli: 31 | gen: 32 | dao: 33 | - link: 'mysql:root:123456@tcp(127.0.0.1:3306)/go_test' 34 | tables: admin_resource 35 | removePrefix: admin_ 36 | -------------------------------------------------------------------------------- /app/service/relation_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "gf-react-admin-server/app/model" 5 | "github.com/gogf/gf/test/gtest" 6 | "testing" 7 | ) 8 | 9 | func TestCreateRelation(t *testing.T) { 10 | gtest.C(t, func(t *gtest.T) { 11 | req := &model.SaveRelationReq{ 12 | UserId: 1, 13 | RoleIds: []int{1, 2, 4}, 14 | } 15 | t.Assert(Relation.SaveRelation(req), nil) 16 | }) 17 | } 18 | 19 | func TestCreateRelationErr1(t *testing.T) { 20 | gtest.C(t, func(t *gtest.T) { 21 | req := &model.SaveRelationReq{ 22 | UserId: 1, 23 | } 24 | if err := Relation.SaveRelation(req); err != nil { 25 | t.Log(err) 26 | } else { 27 | t.Error("测试失败") 28 | } 29 | }) 30 | } 31 | 32 | func TestCreateRelationErr2(t *testing.T) { 33 | gtest.C(t, func(t *gtest.T) { 34 | req := &model.SaveRelationReq{ 35 | RoleIds: []int{1}, 36 | } 37 | if err := Relation.SaveRelation(req); err != nil { 38 | t.Log(err) 39 | } else { 40 | t.Error("测试失败") 41 | } 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /app/api/v1/relation.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "gf-react-admin-server/app/model" 5 | "gf-react-admin-server/app/service" 6 | "gf-react-admin-server/library/response" 7 | "github.com/gogf/gf/errors/gerror" 8 | "github.com/gogf/gf/net/ghttp" 9 | "github.com/gogf/gf/util/gvalid" 10 | ) 11 | 12 | type relationApi struct{} 13 | 14 | var ( 15 | Relation = &relationApi{} 16 | ) 17 | 18 | // @summary 保存用户关系 19 | // @tags 用户关系服务 20 | // @produce json 21 | // @param entity body model.SaveRelationReq true "保存用户关系参数" 22 | // @router /v1/relation [PUT] 23 | func (r *relationApi) SaveRelation(req *ghttp.Request) { 24 | saveRelationReq := &model.SaveRelationReq{} 25 | if err := req.Parse(saveRelationReq); err != nil { 26 | if _, ok := err.(*gvalid.Error); ok { 27 | // 参数校验失败 28 | response.FailCodeAndMsgExit(req, response.ParamValidErr, err.Error()) 29 | } 30 | response.FailMsgExit(req, err.Error()) 31 | } 32 | if err := service.Relation.SaveRelation(saveRelationReq); err != nil { 33 | response.FailCodeAndMsgExit(req, gerror.Code(err), err.Error()) 34 | } 35 | response.SuccessMsgExit(req, "保存成功") 36 | } 37 | -------------------------------------------------------------------------------- /app/model/internal/role_resource.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "github.com/gogf/gf/os/gtime" 9 | ) 10 | 11 | // RoleResource is the golang structure for table admin_role_resource. 12 | type RoleResource struct { 13 | Id int64 `orm:"id,primary" json:"id"` // 14 | RoleId int64 `orm:"role_id" json:"roleId"` // 角色id 15 | ResourceId int64 `orm:"resource_id" json:"resourceId"` // 资源id 16 | CreateBy int64 `orm:"create_by" json:"createBy"` // 创建人 17 | CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 创建时间 18 | UpdatedBy int64 `orm:"updated_by" json:"updatedBy"` // 更新人 19 | UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间 20 | DeleteBy int64 `orm:"delete_by" json:"deleteBy"` // 删除人 21 | DeletedAt *gtime.Time `orm:"deleted_at" json:"deletedAt"` // 删除时间时间 22 | } 23 | -------------------------------------------------------------------------------- /app/dao/role.go: -------------------------------------------------------------------------------- 1 | // ============================================================================ 2 | // This is auto-generated by gf cli tool only once. Fill this file as you wish. 3 | // ============================================================================ 4 | 5 | package dao 6 | 7 | import ( 8 | "gf-react-admin-server/app/dao/internal" 9 | "gf-react-admin-server/app/model" 10 | ) 11 | 12 | // roleDao is the manager for logic model data accessing 13 | // and custom defined data operations functions management. You can define 14 | // methods on it to extend its functionality as you wish. 15 | type roleDao struct { 16 | *internal.RoleDao 17 | } 18 | 19 | var ( 20 | // Role is globally public accessible object for table admin_role operations. 21 | Role = &roleDao{ 22 | internal.Role, 23 | } 24 | ) 25 | 26 | // Fill with you ideas below. 27 | func (r *roleDao) FindByNameOrAlias(name, alias string) (role *model.Role, err error) { 28 | dao := r.Safe() 29 | if len(name) > 0 { 30 | dao = dao.Where(r.Columns.RoleName+" like ?", "%"+name+"%") 31 | } 32 | if len(alias) > 0 { 33 | dao = dao.Or(r.Columns.Alias+" like ?", "%"+alias+"%") 34 | } 35 | err = dao.Scan(&role) 36 | return 37 | } 38 | -------------------------------------------------------------------------------- /app/dao/resource.go: -------------------------------------------------------------------------------- 1 | // ============================================================================ 2 | // This is auto-generated by gf cli tool only once. Fill this file as you wish. 3 | // ============================================================================ 4 | 5 | package dao 6 | 7 | import ( 8 | "gf-react-admin-server/app/dao/internal" 9 | "gf-react-admin-server/app/model" 10 | ) 11 | 12 | // resourceDao is the manager for logic model data accessing 13 | // and custom defined data operations functions management. You can define 14 | // methods on it to extend its functionality as you wish. 15 | type resourceDao struct { 16 | *internal.ResourceDao 17 | } 18 | 19 | var ( 20 | // Resource is globally public accessible object for table admin_resource operations. 21 | Resource = &resourceDao{ 22 | internal.Resource, 23 | } 24 | ) 25 | 26 | // Fill with you ideas below. 27 | 28 | // FindByNameAndType find resource by name and type 29 | func (r *resourceDao) FindByNameAndType(name, types string) (resource *model.Resource, err error) { 30 | if len(name) <= 0 || len(types) <= 0 { 31 | return nil, nil 32 | } 33 | 34 | err = r.Where(r.Columns.Name, name).And(r.Columns.Type, types).Scan(&resource) 35 | return 36 | } 37 | -------------------------------------------------------------------------------- /app/model/internal/user.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "github.com/gogf/gf/os/gtime" 9 | ) 10 | 11 | // User is the golang structure for table admin_user. 12 | type User struct { 13 | Id int64 `orm:"id,primary" json:"id"` // 14 | FullName string `orm:"full_name" json:"fullName"` // 姓名 15 | Account string `orm:"account" json:"account"` // 账号 16 | Password string `orm:"password" json:"password"` // 密码 17 | Email string `orm:"email" json:"email"` // 邮箱 18 | Mobile string `orm:"mobile" json:"mobile"` // 手机号码 19 | Wechat string `orm:"wechat" json:"wechat"` // 微信号 20 | Avatar string `orm:"avatar" json:"avatar"` // 头像 21 | Sex int `orm:"sex" json:"sex"` // 性别:0:未知,1:男,2:女 22 | Status int `orm:"status" json:"status"` // 0:禁用,1正常 23 | CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 创建时间 24 | UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间 25 | DeletedAt *gtime.Time `orm:"deleted_at" json:"deletedAt"` // 删除时间时间 26 | } 27 | -------------------------------------------------------------------------------- /library/common/tree_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "github.com/gogf/gf/test/gtest" 7 | "testing" 8 | ) 9 | 10 | type Tee struct { 11 | Id int 12 | Name string 13 | ParentId int 14 | } 15 | 16 | func (r Tee) GetPrimKey() int { 17 | return r.Id 18 | } 19 | 20 | func (r Tee) GetParentPrimKey() int { 21 | return r.ParentId 22 | } 23 | 24 | func (r Tee) GetName() string { 25 | return r.Name 26 | } 27 | 28 | func (r Tee) GetData() interface{} { 29 | return r 30 | } 31 | 32 | func (r Tee) Root() bool { 33 | return r.ParentId == 0 34 | } 35 | 36 | func getData(datas []Tee) (iTrees []ITreeNode) { 37 | for _, v := range datas { 38 | iTrees = append(iTrees, v) 39 | } 40 | return 41 | } 42 | 43 | func TestCreateRelation(t *testing.T) { 44 | gtest.C(t, func(t *gtest.T) { 45 | datas := []Tee{ 46 | {Id: 1, Name: "根节点1", ParentId: 0}, 47 | {Id: 2, Name: "根节点2", ParentId: 0}, 48 | {Id: 3, Name: "根节点3", ParentId: 0}, 49 | {Id: 21, Name: "子节点1", ParentId: 2}, 50 | {Id: 11, Name: "子节点2", ParentId: 1}, 51 | {Id: 31, Name: "子节点3", ParentId: 3}, 52 | {Id: 211, Name: "子节点4", ParentId: 21}, 53 | {Id: 111, Name: "子节点5", ParentId: 11}, 54 | {Id: 311, Name: "子节点6", ParentId: 31}, 55 | {Id: 1111, Name: "子节点7", ParentId: 111}, 56 | } 57 | tree := GenerateTree(getData(datas)) 58 | by, _ := json.Marshal(tree) 59 | fmt.Print(string(by)) 60 | t.AssertNE(tree, nil) 61 | }) 62 | } 63 | -------------------------------------------------------------------------------- /app/service/relation.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "gf-react-admin-server/app/dao" 5 | "gf-react-admin-server/app/model" 6 | "gf-react-admin-server/library/common" 7 | "github.com/gogf/gf/util/gvalid" 8 | ) 9 | 10 | type relationService struct{} 11 | 12 | var ( 13 | // Relation 供外部调用 14 | Relation = &relationService{} 15 | ) 16 | 17 | // SaveRelation 保存用户关系 18 | func (r *relationService) SaveRelation(req *model.SaveRelationReq) error { 19 | if err := gvalid.CheckStruct(&req, nil); err != nil { 20 | return err 21 | } 22 | 23 | // 删除旧关系 24 | deleteParam := map[string]interface{}{ 25 | dao.Relation.Columns.UserId: req.UserId, 26 | dao.Relation.Columns.RoleId + " not in (?)": req.RoleIds, 27 | } 28 | _, _ = dao.Relation.Delete(deleteParam) 29 | 30 | for _, v := range req.RoleIds { 31 | // 根据用户id和需要新增的角色id查询是否已存在该关联关系 32 | queryParam := map[string]interface{}{ 33 | dao.Relation.Columns.UserId: req.UserId, 34 | dao.Relation.Columns.RoleId: v, 35 | } 36 | count, err := dao.Relation.Where(queryParam).Count() 37 | if err != nil { 38 | return err 39 | } 40 | if count > 0 { 41 | continue 42 | } 43 | 44 | var relation = &model.Relation{ 45 | UserId: int64(req.UserId), 46 | RoleId: int64(v), 47 | } 48 | relation.Id, err = common.Id.GenerateUUID() 49 | if err != nil { 50 | return err 51 | } 52 | // 创建 53 | _, err = dao.Relation.Insert(relation) 54 | if err != nil { 55 | return err 56 | } 57 | } 58 | 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /app/model/internal/resource.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "github.com/gogf/gf/os/gtime" 9 | ) 10 | 11 | // Resource is the golang structure for table admin_resource. 12 | type Resource struct { 13 | Id int64 `orm:"id,primary" json:"id"` // 14 | ParentId int64 `orm:"parent_id" json:"parentId"` // 父资源id 15 | Name string `orm:"name" json:"name"` // 资源名称 16 | Alias string `orm:"alias" json:"alias"` // 资源别称 17 | Url string `orm:"url" json:"url"` // 资源路径 18 | Enable bool `orm:"enable" json:"enable"` // 0:不显示,1显示 19 | Icon string `orm:"icon" json:"icon"` // 资源图标 20 | Type string `orm:"type" json:"type"` // 资源类型:menu-菜单;button-按钮;link-链接 21 | Sn int `orm:"sn" json:"sn"` // 排序 22 | CreateBy int64 `orm:"create_by" json:"createBy"` // 创建人 23 | CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"` // 创建时间 24 | UpdatedBy int64 `orm:"updated_by" json:"updatedBy"` // 更新人 25 | UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"` // 更新时间 26 | DeleteBy int64 `orm:"delete_by" json:"deleteBy"` // 删除人 27 | DeletedAt *gtime.Time `orm:"deleted_at" json:"deletedAt"` // 删除时间时间 28 | } 29 | -------------------------------------------------------------------------------- /app/model/role.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. Fill this file as you wish. 3 | // ========================================================================== 4 | 5 | package model 6 | 7 | import ( 8 | "gf-react-admin-server/app/model/internal" 9 | "gf-react-admin-server/library/common" 10 | "github.com/gogf/gf/os/gtime" 11 | ) 12 | 13 | // Role is the golang structure for table admin_role. 14 | type Role internal.Role 15 | 16 | // Fill with you ideas below. 17 | 18 | // CreateRoleReq 用于接受创建角色请求参数 19 | type CreateRoleReq struct { 20 | ParentId string `json:"parentId"` // 父角色id 21 | RoleName string `json:"roleName" v:"roleName@required#角色名不能为空"` // 角色名称 22 | Alias string `json:"alias"` // 角色别名 23 | } 24 | 25 | // EditRoleReq 编辑角色请求参数 26 | type EditRoleReq struct { 27 | *CreateRoleReq 28 | Id int64 `json:"id" v:"id@required|min:1 #待编辑角色id不能为空|待编辑角色id长度非法"` // 角色id 29 | } 30 | 31 | // RoleQueryReq 角色列表查询参数 32 | type RoleQueryReq struct { 33 | common.PageReq 34 | } 35 | 36 | // RoleInfoReq 角色详情返回参数 37 | type RoleInfoReq struct { 38 | Id int64 `json:"id"` // 39 | ParentId string `json:"parentId"` // 父角色id 40 | RoleName string `json:"roleName"` // 角色名称 41 | Alias string `json:"alias"` // 角色别名 42 | CreatedAt *gtime.Time `json:"createdAt"` // 创建时间 43 | UpdatedAt *gtime.Time `json:"updatedAt"` // 更新时间 44 | } 45 | 46 | // RolePageListRes 角色列表返回参数 47 | type RolePageListRes struct { 48 | RoleInfoReq 49 | } 50 | -------------------------------------------------------------------------------- /router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | v1 "gf-react-admin-server/app/api/v1" 5 | "gf-react-admin-server/app/middleware" 6 | "github.com/gogf/gf/frame/g" 7 | "github.com/gogf/gf/net/ghttp" 8 | ) 9 | 10 | var ( 11 | // RouteGroupPrefix 路由统一前缀 12 | RouteGroupPrefix = "/v1" 13 | ) 14 | 15 | func init() { 16 | s := g.Server() 17 | // 跨域中间件 18 | s.Use(middleware.CORS) 19 | // 异常记录中间件 20 | s.Use(middleware.ErrorLog) 21 | s.Group(RouteGroupPrefix, func(group *ghttp.RouterGroup) { 22 | group.Middleware( 23 | middleware.GetPath) 24 | group.POST("/user/login", middleware.JwtMiddleware.LoginHandler) 25 | group.GET("/user/logout", middleware.JwtMiddleware.LogoutHandler) 26 | }) 27 | 28 | // 角色服务 29 | s.Group(RouteGroupPrefix, func(group *ghttp.RouterGroup) { 30 | group.Middleware(middleware.JwtAuth) 31 | group.POST("/role", v1.Role.CreateRole) 32 | group.PUT("/role", v1.Role.EditRole) 33 | group.GET("/role", v1.Role.RolePageList) 34 | group.GET("/role/{id}", v1.Role.RoleById) 35 | }) 36 | 37 | // 用户关系服务 38 | s.Group(RouteGroupPrefix, func(group *ghttp.RouterGroup) { 39 | group.Middleware(middleware.JwtAuth) 40 | group.PUT("/relation", v1.Relation.SaveRelation) 41 | }) 42 | 43 | // 资源服务 44 | s.Group(RouteGroupPrefix, func(group *ghttp.RouterGroup) { 45 | group.Middleware(middleware.JwtAuth) 46 | group.POST("/resource", v1.Resource.CreateResource) 47 | group.PUT("/resource", v1.Resource.EditResource) 48 | group.GET("/resource/tree", v1.Resource.GetResourceTree) 49 | }) 50 | 51 | // 用户服务 52 | s.Group(RouteGroupPrefix, func(group *ghttp.RouterGroup) { 53 | group.Middleware(middleware.JwtAuth) 54 | group.GET("/user/{id}", v1.User.GetUserInfos) 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /app/model/user.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. Fill this file as you wish. 3 | // ========================================================================== 4 | 5 | package model 6 | 7 | import ( 8 | "gf-react-admin-server/app/model/internal" 9 | ) 10 | 11 | // User is the golang structure for table admin_user. 12 | type User internal.User 13 | 14 | // Fill with you ideas below. 15 | 16 | // UserLoginReq is login param 17 | type UserLoginReq struct { 18 | Account string `v:"required#请输入账户"` // 账号 19 | Password string `v:"required#请输入密码"` // 密码 20 | } 21 | 22 | // UserLoginRes is login response param 23 | type UserLoginRes struct { 24 | JWT_USER_ID int `json:"JWT_USER_ID"` // 25 | FullName string `json:"fullName"` // 姓名 26 | Account string `json:"account"` // 账号 27 | Email string `json:"email"` // 邮箱 28 | Mobile string `json:"mobile"` // 手机号码 29 | Wechat string `json:"wechat"` // 微信号 30 | Avatar string `json:"avatar"` // 头像 31 | Sex int `json:"sex"` // 性别:0:未知,1:男,2:女 32 | Password string `json:"-"` 33 | } 34 | 35 | // UserInfo 用户信息 36 | type UserInfo struct { 37 | FullName string `json:"fullName"` // 姓名 38 | Account string `json:"account"` // 账号 39 | Email string `json:"email"` // 邮箱 40 | Mobile string `json:"mobile"` // 手机号码 41 | Wechat string `json:"wechat"` // 微信号 42 | Avatar string `json:"avatar"` // 头像 43 | Sex int `json:"sex"` // 性别:0:未知,1:男,2:女 44 | } 45 | 46 | // UserInfos 用户的全部信息 47 | type UserInfos struct { 48 | User UserInfo `json:"user"` 49 | Menus []ResourceInfo `json:"menus"` 50 | } 51 | -------------------------------------------------------------------------------- /app/service/user.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "gf-react-admin-server/app/dao" 5 | "gf-react-admin-server/app/model" 6 | "gf-react-admin-server/library/response" 7 | "github.com/gogf/gf/errors/gerror" 8 | "golang.org/x/crypto/bcrypt" 9 | ) 10 | 11 | type userService struct { 12 | } 13 | 14 | var ( 15 | User = &userService{} 16 | ) 17 | 18 | func (u *userService) Login(loginReq *model.UserLoginReq) (user *model.UserLoginRes, err error) { 19 | var queryParam = map[string]string{ 20 | "account": loginReq.Account, 21 | } 22 | err = dao.User.Where(queryParam).Scan(&user) 23 | if err != nil { 24 | return nil, err 25 | } 26 | if user == nil { 27 | return nil, gerror.NewCode(response.AccountExist, "账户不存在") 28 | } 29 | 30 | err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(loginReq.Password)) 31 | if err != nil { 32 | return nil, gerror.NewCode(response.AccountValidErr, "账户或密码错误") 33 | } 34 | return user, nil 35 | } 36 | 37 | // GetUserInfos 获取用户信息 38 | func (u *userService) GetUserInfos(userId int) (*model.UserInfos, error) { 39 | if userId <= 0 { 40 | return nil, nil 41 | } 42 | 43 | // 用户信息 44 | var userInfo *model.UserInfo 45 | err := dao.User.WherePri(userId).Scan(&userInfo) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | // 菜单资源 51 | menuResources, err := Resource.GetMenuByUserId(userId) 52 | if err != nil { 53 | return nil, err 54 | } 55 | menus := make([]model.ResourceInfo, 0, len(menuResources)) 56 | for _, v := range menuResources { 57 | menus = append(menus, model.ResourceInfo{ 58 | Id: v.Id, 59 | ParentId: v.ParentId, 60 | Name: v.Name, 61 | Alias: v.Alias, 62 | Url: v.Url, 63 | Icon: v.Icon, 64 | Type: v.Type, 65 | Sn: v.Sn, 66 | }) 67 | } 68 | 69 | userInfos := &model.UserInfos{ 70 | User: *userInfo, 71 | Menus: menus, 72 | } 73 | return userInfos, nil 74 | } 75 | -------------------------------------------------------------------------------- /library/common/tree.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | // ITreeNode 要使用树形结构,对应结构体需要实现以下方法 4 | type ITreeNode interface { 5 | GetPrimKey() int // 主键 6 | GetParentPrimKey() int // 父主键 7 | GetName() string // 节点名称 8 | GetData() interface{} // 数据 9 | Root() bool // 是否根节点 10 | } 11 | 12 | // TreeNode 树形结构的节点数据 13 | type TreeNode struct { 14 | PrimKey int `json:"primKey"` 15 | ParentPrimKey int `json:"parentPrimKey"` 16 | Name string `json:"name"` 17 | Data interface{} `json:"data"` 18 | Children []TreeNode `json:"children"` 19 | } 20 | 21 | // GenerateTree 生成树形结构 22 | func GenerateTree(nodes []ITreeNode) (trees []TreeNode) { 23 | trees = make([]TreeNode, 0) 24 | if len(nodes) <= 0 { 25 | return 26 | } 27 | var roots, childs []ITreeNode 28 | 29 | // 分类根节点和子节点 30 | for _, v := range nodes { 31 | if v.Root() { 32 | roots = append(roots, v) 33 | } else { 34 | childs = append(childs, v) 35 | } 36 | } 37 | 38 | for _, root := range roots { 39 | treeNode := &TreeNode{ 40 | Name: root.GetName(), 41 | PrimKey: root.GetPrimKey(), 42 | ParentPrimKey: root.GetParentPrimKey(), 43 | Data: root.GetData(), 44 | } 45 | 46 | // 递归寻找子节点 47 | recursiveTree(treeNode, childs) 48 | 49 | trees = append(trees, *treeNode) 50 | } 51 | return 52 | } 53 | 54 | func recursiveTree(node *TreeNode, childs []ITreeNode) { 55 | iNode := node.Data.(ITreeNode) 56 | 57 | for _, v := range childs { 58 | if v.GetParentPrimKey() == iNode.GetPrimKey() { 59 | childTreeNode := &TreeNode{ 60 | Name: v.GetName(), 61 | PrimKey: v.GetPrimKey(), 62 | ParentPrimKey: v.GetParentPrimKey(), 63 | Data: v.GetData(), 64 | } 65 | 66 | // 递归寻找子节点 67 | recursiveTree(childTreeNode, childs) 68 | 69 | node.Children = append(node.Children, *childTreeNode) 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packed/swagger.go: -------------------------------------------------------------------------------- 1 | package packed 2 | 3 | import "github.com/gogf/gf/os/gres" 4 | 5 | func init() { 6 | if err := gres.Add("H4sIAAAAAAAC/3yUfTTTix/Hv8Miv/Wb9EV0NUWJJrJYcku5HvL8TCWKyOZpyj00Wx5OjSJhbtTmqWHjNK15vtyQSR6aZhJF0TzVTLFCNbN73Hs7de7p3Pcfn8/5nM/n8z7vv17uTvIKIKAEKAFn7SiewHcCgfVAbHxQWFjoeeN/+p7wWFy0jzcUgECSUk+LKG5eI3Zg23uicuYL3Q6HrJOWB0PoubfIbytzOdsPPqZX+x6vIt/WRPBVhbWQTaqYE5h1DIcuZ/phqrvpzWxjjuPSVRavH0EIiQh1qod1PlDs5K/icWOSOcJsw6h2rp4DmWu5q1jR0M1RrJG/p3di1Z/5RAXvKZZcwIE0VJnJcmg/wR/WpHWFS6m6GNvAmtyFuRJEa6j9JI9Ux79Fu9NOKDfmXtTALibocHj3BFxqM1Y14PqvzXu3FubfJqZZFOqz5viHWmXP8P51aPXPxjdCaii+t5PfFEQ0TmQliVuLU/XJUHmYjQdkM+9CKM0OSwxRcyYF65pUHtYzlmFY75QV0AyeB2SUXYJ6PH1gsaPoGpYWJ7J9nUcyqBCXdVRAtRMoPUgwmzdrJD3EMJlwXEUy2mHP2M0nUH46hpj8u6UjJmqHzaANNNdwYnp73puRLWcES4ILlt072RVyv7idj8K9OnQsrn53n9i6+rM1zDItoq7UfhV8hNi9dL8wBfWTuoXwY2J5sLla8j6lhEcjXXrTb0qwrDmx8EElTVPdQohJdIDs3axXwGU08ihnQIUFM3ip/LkobHH+0IqBiGu/wollfBlONDfWN1Pr70sh1fuGw1fnFsAp+HQ5KSE0Kz/xjk8gnEhF2zS1i6Y2zLz84DEm8rK5hEOWxF4anplzwHRdt5e2aRb4rBjkBYrFp+TTUMjzT9kfr9vbbDm6pLlU6mF1TMxvIrhauCA52+21e8cx+3RMqG60k8XNGYMCRvZ8hCVLVPwuLMuIivpZfK9PB167ybvdC+KbG/Py9/wntSnDkcp0VGq3acr0PvIjmudo9kPr1qJBXde+9z6rQWaE7BcD1fpnn+qONezksQIwrmbzeGZRRtsQovLV+Ov/EVsCZ8zn8WNaQ6rbyvyN9QXpWzcKtOL0BtBHgqJmY9ioZFMYfbNTWZBeNFkhD27oUo7u8z3pjhWeMU1fJIJNtGQ9Xn9tSTQvEuc1IZ5ckNhK3uZ8EIxPzr9Wk/mjL9LX9wPr424c3cZUunuZUhV8h4l4TrWKH9ie6SOX6mXA/uMmOwJmcyTMb7AjfX+5jBgQ3BAYMqvv2eH8ToWAJSF+Q93YCnPcaVXRJvWaepJ40GKlFGgy89iNm384mMtZxGbspbkNwxFP/erd/j9kxkyy8kgihhjfF9HPabUe93aqxEUlpSG4y0zOzU8GBZa2rb595kVQUh2aiGfPkMLqsAcQMwQ+R0qKM/IBFzbwT4EOztaSqIHn1TE5I4IqMj6a073cuSAJl3bHLWfmGBadmnw2X5IxSunBcaj+HKiwJpMu38M0ENjxL1PSB4vqI61t+cNBXShCrzSgU0drF3zoqIAkQdct9gQStzH9QHGMtix7FPqgcCHDqGXEHnARXVqS2fQOb9iT4jdYuxFyh1wZBG2qQnikC4TXTM+6X9FA7qguBdnloMacSwnWnDgj9I7nkgmN5V9usQk5NBUnDQ3UjhzC2H3BlDQ6w3WTABZCiVdyica31IxHvpo9Ttpfk/U5KUOmCAAymbuTolKLnKtmjgIApCMB4CvbACDsX2xT/Ma2v3Aml5R6eu37+xt3J4gcKP+Njd87r7Hxq2Qpa/U/SfnN6sdR/pYKIDsyqgD8IBh03dpeDpADrgIAoAVdm/4MAAD//3+YgIK5BQAA"); err != nil { 7 | panic("add binary content to resource manager failed: " + err.Error()) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/api/v1/resource.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "gf-react-admin-server/app/model" 5 | "gf-react-admin-server/app/service" 6 | "gf-react-admin-server/library/response" 7 | "github.com/gogf/gf/errors/gerror" 8 | "github.com/gogf/gf/net/ghttp" 9 | "github.com/gogf/gf/util/gvalid" 10 | ) 11 | 12 | type resourceApi struct{} 13 | 14 | var ( 15 | Resource = &resourceApi{} 16 | ) 17 | 18 | // @summary 新建资源信息 19 | // @tags 资源管理 20 | // @produce json 21 | // @param entity body model.CreateResourceReq true "新建资源参数" 22 | // @router /v1/resource [POST] 23 | func (r *resourceApi) CreateResource(req *ghttp.Request) { 24 | createResource := &model.CreateResourceReq{} 25 | 26 | if err := req.Parse(createResource); err != nil { 27 | if _, ok := err.(*gvalid.Error); ok { 28 | // 参数校验失败 29 | response.FailCodeAndMsgExit(req, response.ParamValidErr, err.Error()) 30 | } 31 | response.FailMsgExit(req, err.Error()) 32 | } 33 | if err := service.Resource.CreateResource(createResource); err != nil { 34 | response.FailCodeAndMsgExit(req, gerror.Code(err), err.Error()) 35 | } 36 | response.SuccessMsgExit(req, "新建成功") 37 | } 38 | 39 | // @summary 编辑资源信息 40 | // @tags 资源管理 41 | // @produce json 42 | // @param entity body model.EditResourceReq true "编辑资源参数" 43 | // @router /v1/resource [PUT] 44 | func (r *resourceApi) EditResource(req *ghttp.Request) { 45 | editResourceReq := &model.EditResourceReq{} 46 | 47 | if err := req.Parse(editResourceReq); err != nil { 48 | if _, ok := err.(*gvalid.Error); ok { 49 | // 参数校验失败 50 | response.FailCodeAndMsgExit(req, response.ParamValidErr, err.Error()) 51 | } 52 | response.FailMsgExit(req, err.Error()) 53 | } 54 | if err := service.Resource.EditResource(editResourceReq); err != nil { 55 | response.FailCodeAndMsgExit(req, gerror.Code(err), err.Error()) 56 | } 57 | response.SuccessMsgExit(req, "编辑成功") 58 | } 59 | 60 | // @summary 获取资源树形结构 61 | // @tags 资源管理 62 | // @produce json 63 | // @router /v1/resource/tree [GET] 64 | func (r *resourceApi) GetResourceTree(req *ghttp.Request) { 65 | trees, err := service.Resource.GetResourceTree() 66 | if err != nil { 67 | response.FailMsgExit(req, err.Error()) 68 | } 69 | response.SuccessData(req, trees) 70 | } 71 | -------------------------------------------------------------------------------- /app/service/role.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "gf-react-admin-server/app/dao" 5 | "gf-react-admin-server/app/model" 6 | "gf-react-admin-server/library/common" 7 | "gf-react-admin-server/library/response" 8 | "github.com/gogf/gf/errors/gerror" 9 | "github.com/gogf/gf/util/gconv" 10 | ) 11 | 12 | type roleService struct{} 13 | 14 | var ( 15 | // Role 用于外部调用 16 | Role = &roleService{} 17 | ) 18 | 19 | // CreateRole 创建角色 20 | func (r *roleService) CreateRole(req *model.CreateRoleReq) error { 21 | // 判断是否已经存在该角色 22 | role, err := dao.Role.FindByNameOrAlias(req.RoleName, req.Alias) 23 | if err != nil { 24 | return err 25 | } 26 | if role != nil { 27 | return gerror.NewCode(response.DataExist, "该角色名或别名已存在,请勿重复创建。") 28 | } 29 | 30 | role = &model.Role{} 31 | err = gconv.Struct(req, role) 32 | if err != nil { 33 | return err 34 | } 35 | 36 | // 生成id 37 | id, err := common.Id.GenerateUUID() 38 | if err != nil { 39 | return err 40 | } 41 | role.Id = int64(id) 42 | // 创建角色 43 | _, err = dao.Role.Insert(role) 44 | if err != nil { 45 | return err 46 | } 47 | 48 | return nil 49 | } 50 | 51 | // EditRole 编辑角色信息 52 | func (r *roleService) EditRole(req *model.EditRoleReq) error { 53 | // 判断是否已经存在该角色 54 | role, err := dao.Role.FindByNameOrAlias(req.RoleName, req.Alias) 55 | if err != nil { 56 | return err 57 | } 58 | if role != nil && role.Id != req.Id { 59 | return gerror.NewCode(response.DataExist, "该角色名或别名已存在,请修改角色名或别名。") 60 | } 61 | 62 | err = gconv.Struct(req, role) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | // 更新角色 68 | _, err = dao.Role.Update(role, dao.Role.Columns.Id, role.Id) 69 | return err 70 | } 71 | 72 | // RolePageList 获取角色分页列表 73 | func (r *roleService) RolePageList(req *model.RoleQueryReq) (interface{}, error) { 74 | pageNo, pageSize := req.PageNo, req.PageSize 75 | total, err := dao.Role.Count() 76 | if err != nil { 77 | return nil, err 78 | } 79 | roles := make([]model.RolePageListRes, 0) 80 | err = dao.Role.Page(pageNo, pageSize).Structs(&roles) 81 | if err != nil { 82 | return nil, err 83 | } 84 | 85 | return &common.PageResult{ 86 | PageNo: pageNo, 87 | PageSize: pageSize, 88 | Total: total, 89 | Records: roles, 90 | }, nil 91 | } 92 | 93 | // RoleById 根据id获取角色信息 94 | func (r *roleService) RoleById(id int64) (role *model.RoleInfoReq, err error) { 95 | err = dao.Role.WherePri(id).Struct(&role) 96 | return 97 | } 98 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # gf-react-admin-server 2 | 3 | ## 简介 4 | 该项目为`gf-react-admin`项目对应后端项目,前端项目见[gf-react-admin](https://github.com/Riunshow/gf-react-admin),采用`Golang` + [GoFrame](https://github.com/gogf/gf) 进行开发,支持JWT鉴权、casbin权限控制。 5 | 6 | ## 主要技术 7 | - Golang 8 | - [GoFrame](https://github.com/gogf/gf) 9 | - JWT([gf-jwt](https://github.com/gogf/gf-jwt)) 10 | - [Casbin](https://github.com/casbin/casbin) 11 | - MySQL 12 | - Redis 13 | 14 | ## 项目细节 15 | ### 统一返回体 16 | 详情见项目`library`包 17 | 1. `resposne.go`文件,该文件中定义了统一的返回结构体如下: 18 | ```go 19 | type ResultRes struct { 20 | Code int `json:"code"` // response code, default: success-200 error-500 响应码 21 | Message string `json:"msg"` // response message 响应信息,若返回的是错误码,则此处对应相关错误信息 22 | Data interface{} `json:"data"` // response result data 返回数据 23 | } 24 | ``` 25 | 主要包含响应码、响应信息和相关数据,当响应码为200则表示服务正常,其余响应码对应相关错误,并会有对应的响应信息进行返回。 26 | 还定义了一些功能方法方便业务方进行调用返回,例如`Success(r *ghttp.Request)`、`SuccessExit(r *ghttp.Request)`,其中带有exit后缀的方法均表示会在返回response后退出当前HTTP执行函数 27 | 28 | 2. `page.go`定义了公共的分页返回参数结构体,并提供相关创建函数,结构体如下 29 | ```go 30 | // 分页统一返回体 31 | type PageResult struct { 32 | PageNum int `json:"pageNum"` // 分页页数 33 | PageSize int `json:"pageSize"` // 分页大小 34 | Total int `json:"total"` // 总记录数 35 | Records interface{} `json:"records"` // 对应数据 36 | } 37 | ``` 38 | ### JWT 39 | 本项目采用 [gf-jwt](https://github.com/gogf/gf-jwt) ,jwt的一些基础配置例如过期时间、签名key等都放在`config/config.toml`文件的中。jwt相关业务方发详情见`app/middleware/jwt.go`文件,该文件中的`init()`方法中初始化了 40 | gf-jwt的相关配置,通过自定义的结构体对外进行调用。`Authenticator`、`Authorization`、 41 | `Unauthorized`、`LoginResponse`分别对应了登录方法、鉴权方法、token校验失败方法、登录返回 42 | 方法,用来替换gf-jwt的对应默认方法。其他配置详情见gf-jwt的相关文档和案例。 43 | ```go 44 | // init to gf-jwt config. 进行jwt初始化 45 | func init() { 46 | // 初始化配置 47 | JwtCfg = new(JwtConfig) 48 | if err := g.Cfg().GetStruct("jwt", JwtCfg); err != nil { 49 | g.Log().Errorf("load jwt config fail, err: %v", err) 50 | } 51 | jwtMiddleware, err := jwt.New(&jwt.GfJWTMiddleware{ 52 | Realm: JwtCfg.Realm, 53 | Key: []byte(JwtCfg.SignKey), 54 | Timeout: time.Duration(JwtCfg.ExpireTime) * time.Minute, // 过期时间 55 | MaxRefresh: time.Duration(JwtCfg.RefreshTime) * time.Minute, // 刷新时间 56 | IdentityKey: JwtCfg.IdentityKey, 57 | TokenLookup: JwtCfg.TokenLookup, 58 | TokenHeadName: JwtCfg.TokenHeadName, 59 | TimeFunc: time.Now, 60 | CacheAdapter: adapter.NewRedis(g.Redis("cache")), // 采用redis替换默认的内存缓存 61 | Authenticator: Authenticator, 62 | Authorizator: Authorization, 63 | Unauthorized: Unauthorized, 64 | LoginResponse: LoginResponse, 65 | }) 66 | if err != nil { 67 | g.Log().Errorf("init jwt middleware fail, error: %v", err) 68 | } 69 | JwtMiddleware = jwtMiddleware 70 | } 71 | ``` 72 | -------------------------------------------------------------------------------- /app/api/v1/role.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "gf-react-admin-server/app/model" 5 | "gf-react-admin-server/app/service" 6 | "gf-react-admin-server/library/response" 7 | "github.com/gogf/gf/errors/gerror" 8 | "github.com/gogf/gf/net/ghttp" 9 | "github.com/gogf/gf/util/gconv" 10 | "github.com/gogf/gf/util/gvalid" 11 | ) 12 | 13 | type roleApi struct{} 14 | 15 | var ( 16 | // Role 外部调用 17 | Role = &roleApi{} 18 | ) 19 | 20 | // @summary 创建角色接口 21 | // @tags 角色服务 22 | // @produce json 23 | // @param entity body model.CreateRoleReq true "创建角色参数" 24 | // @router /v1/role [POST] 25 | func (ra *roleApi) CreateRole(r *ghttp.Request) { 26 | var createRoleReq = &model.CreateRoleReq{} 27 | if err := r.Parse(createRoleReq); err != nil { 28 | if _, ok := err.(*gvalid.Error); ok { 29 | // 参数校验失败 30 | response.FailCodeAndMsgExit(r, response.ParamValidErr, err.Error()) 31 | } 32 | response.FailMsgExit(r, err.Error()) 33 | } 34 | if err := service.Role.CreateRole(createRoleReq); err != nil { 35 | response.FailCodeAndMsgExit(r, gerror.Code(err), err.Error()) 36 | } 37 | response.SuccessMsgExit(r, "创建角色成功") 38 | } 39 | 40 | // @summary 编辑角色接口 41 | // @tags 角色服务 42 | // @produce json 43 | // @param entity body model.EditRoleReq true "编辑角色参数" 44 | // @router /v1/role [PUT] 45 | func (ra *roleApi) EditRole(r *ghttp.Request) { 46 | var editRoleReq = &model.EditRoleReq{} 47 | if err := r.ParseForm(editRoleReq); err != nil { 48 | if _, ok := err.(*gvalid.Error); ok { 49 | // 参数校验失败 50 | response.FailCodeAndMsgExit(r, response.ParamValidErr, err.Error()) 51 | } 52 | response.FailMsgExit(r, err.Error()) 53 | } 54 | if err := service.Role.EditRole(editRoleReq); err != nil { 55 | response.FailCodeAndMsgExit(r, gerror.Code(err), err.Error()) 56 | } 57 | response.SuccessMsgExit(r, "编辑角色信息成功") 58 | } 59 | 60 | // @summary 角色分页列表 61 | // @tags 角色服务 62 | // @produce json 63 | // @param entity body model.RoleQueryReq true "角色列表搜索参数" 64 | // @router /v1/role [GET] 65 | func (ra *roleApi) RolePageList(r *ghttp.Request) { 66 | var roleQueryReq = &model.RoleQueryReq{} 67 | if err := r.Parse(roleQueryReq); err != nil { 68 | if _, ok := err.(*gvalid.Error); ok { 69 | // 参数校验失败 70 | response.FailCodeAndMsgExit(r, response.ParamValidErr, err.Error()) 71 | } 72 | response.FailMsgExit(r, err.Error()) 73 | } 74 | 75 | roles, err := service.Role.RolePageList(roleQueryReq) 76 | if err != nil { 77 | response.FailCodeAndMsgExit(r, gerror.Code(err), err.Error()) 78 | } 79 | response.SuccessDataExit(r, roles) 80 | } 81 | 82 | // @summary 角色详情 83 | // @tags 角色服务 84 | // @produce json 85 | // @param id path int true "角色id" 86 | // @router /v1/role/{id} [GET] 87 | func (ra *roleApi) RoleById(r *ghttp.Request) { 88 | id := r.Get("id") 89 | if err := gvalid.Check(id, "required|integer|min:1", "角色id为空|参数类型非法|角色id长度非法"); err != nil { 90 | response.FailMsgExit(r, err.Error()) 91 | } 92 | role, err := service.Role.RoleById(gconv.Int64(id)) 93 | if err != nil { 94 | response.FailMsgExit(r, err.Error()) 95 | } 96 | response.SuccessData(r, role) 97 | } 98 | -------------------------------------------------------------------------------- /library/response/response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | import ( 4 | "github.com/gogf/gf/frame/g" 5 | "github.com/gogf/gf/net/ghttp" 6 | "net/http" 7 | ) 8 | 9 | var ( 10 | OK = http.StatusOK 11 | OkMessage = "正常" 12 | ERROR = http.StatusInternalServerError 13 | ErrorMessage = "服务器发生了一些错误" 14 | DataExist = 1001 // 数据已存在 15 | ParamValidErr = 1002 // 参数校验失败 16 | AccountExist = 1003 // 帐号不存在 17 | AccountValidErr = 1004 // 帐号或密码错误 18 | ) 19 | 20 | type ResultRes struct { 21 | Code int `json:"code"` // response code, default: success-200 error-500 响应码 22 | Message string `json:"msg"` // response message 响应信息,若返回的是错误码,则此处对应相关错误信息 23 | Data interface{} `json:"data"` // response result data 返回数据 24 | } 25 | 26 | // RestResult to write response, but not exit. 返回统一格式对象,但不退出。 27 | func RestResult(r *ghttp.Request, code int, msg string, data interface{}) { 28 | if err := r.Response.WriteJson(ResultRes{ 29 | Code: code, 30 | Message: msg, 31 | Data: data, 32 | }); err != nil { 33 | // response write error, print log. 返回错误,记录日志 34 | g.Log().Error(err) 35 | } 36 | } 37 | 38 | // RestResultExit to write response and exit. 返回统一格式对象,并退出。 39 | func RestResultExit(r *ghttp.Request, code int, msg string, data interface{}) { 40 | RestResult(r, code, msg, data) 41 | r.Exit() 42 | } 43 | 44 | // Success result default success message, but not exit. 返回默认成功信息,但不退出。 45 | func Success(r *ghttp.Request) { 46 | RestResult(r, OK, OkMessage, nil) 47 | } 48 | 49 | // SuccessExit result default success message and exit. 返回默认成功信息,并退出。 50 | func SuccessExit(r *ghttp.Request) { 51 | RestResultExit(r, OK, OkMessage, nil) 52 | } 53 | 54 | // SuccessMsg result success and custom message but not exit. 返回成功和自定义信息,但不退出。 55 | func SuccessMsg(r *ghttp.Request, msg string) { 56 | RestResult(r, OK, msg, nil) 57 | } 58 | 59 | // SuccessMsgExit result success and custom message and exit. 返回成功和自定义信息,并退出。 60 | func SuccessMsgExit(r *ghttp.Request, msg string) { 61 | RestResultExit(r, OK, msg, nil) 62 | } 63 | 64 | // SuccessData result success and custom data but not exit. 返回成功和数据,但不退出。 65 | func SuccessData(r *ghttp.Request, data interface{}) { 66 | RestResult(r, OK, OkMessage, data) 67 | } 68 | 69 | // SuccessDataExit result success and custom data and exit. 返回成功和数据,并退出。 70 | func SuccessDataExit(r *ghttp.Request, data interface{}) { 71 | RestResultExit(r, OK, OkMessage, data) 72 | } 73 | 74 | // Fail result default fail message, but not exit. 返回默认失败信息,但不退出。 75 | func Fail(r *ghttp.Request) { 76 | RestResult(r, ERROR, ErrorMessage, nil) 77 | } 78 | 79 | // FailExit result default fail message and exit. 返回默认失败信息,并退出。 80 | func FailExit(r *ghttp.Request) { 81 | RestResultExit(r, ERROR, ErrorMessage, nil) 82 | } 83 | 84 | // FailMsg result error and custom message but not exit. 返回失败和信息,但不退出 85 | func FailMsg(r *ghttp.Request, msg string) { 86 | RestResult(r, ERROR, msg, nil) 87 | } 88 | 89 | // FailMsgExit result error and custom message and exit. 返回失败和信息,并退出 90 | func FailMsgExit(r *ghttp.Request, msg string) { 91 | RestResultExit(r, ERROR, msg, nil) 92 | } 93 | 94 | // FailCodeAndMsg result error code and custom message but not exit. 返回失败,自定义状态码和信息,不退出 95 | func FailCodeAndMsg(r *ghttp.Request, code int, msg string) { 96 | RestResult(r, code, msg, nil) 97 | } 98 | 99 | // FailCodeAndMsgExit result error code and custom message and exit. 返回失败,自定义状态码和信息,并退出 100 | func FailCodeAndMsgExit(r *ghttp.Request, code int, msg string) { 101 | RestResultExit(r, code, msg, nil) 102 | } 103 | -------------------------------------------------------------------------------- /app/service/resource.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "gf-react-admin-server/app/dao" 5 | "gf-react-admin-server/app/model" 6 | "gf-react-admin-server/library/common" 7 | "gf-react-admin-server/library/response" 8 | "github.com/gogf/gf/errors/gerror" 9 | "github.com/gogf/gf/util/gconv" 10 | ) 11 | 12 | type resourceService struct{} 13 | 14 | var ( 15 | Resource = &resourceService{} 16 | ) 17 | 18 | // CreateResource create resource service method 19 | func (r *resourceService) CreateResource(req *model.CreateResourceReq) error { 20 | // 判断是否存在相同资源 21 | result, err := dao.Resource.FindByNameAndType(req.Name, req.Type) 22 | if err != nil { 23 | return err 24 | } 25 | if result != nil { 26 | return gerror.NewCode(response.DataExist, "该资源已存在,请勿重复创建。") 27 | } 28 | 29 | resource := &model.Resource{} 30 | err = gconv.Struct(req, resource) 31 | if err != nil { 32 | return err 33 | } 34 | 35 | // 生成id 36 | id, err := common.Id.GenerateUUID() 37 | if err != nil { 38 | return err 39 | } 40 | resource.Id = id 41 | 42 | // 创建资源 43 | _, err = dao.Resource.Insert(resource) 44 | if err != nil { 45 | return err 46 | } 47 | 48 | return nil 49 | } 50 | 51 | // EditResource 编辑资源信息 52 | func (r *resourceService) EditResource(req *model.EditResourceReq) error { 53 | // 判断是否存在相同资源 54 | result, err := dao.Resource.FindByNameAndType(req.Name, req.Type) 55 | if err != nil { 56 | return err 57 | } 58 | if result != nil && result.Id != req.Id { 59 | return gerror.NewCode(response.DataExist, "资源名已存在,请修改资源名。") 60 | } 61 | 62 | // 更新 63 | _, err = dao.Resource.Update(req, dao.Resource.Columns.Id, req.Id) 64 | if err != nil { 65 | return err 66 | } 67 | return nil 68 | } 69 | 70 | // GetResourceTree 获取资源树形结构 71 | func (r *resourceService) GetResourceTree() (trees []common.TreeNode, err error) { 72 | resources := make([]*model.Resource, 0) 73 | err = dao.Resource.Order("sn ASC").Structs(&resources) 74 | if err != nil { 75 | return nil, err 76 | } 77 | 78 | trees = common.GenerateTree(model.GetResourceSlice(resources)) 79 | return 80 | } 81 | 82 | // GetMenuByUserId 获取用户具有的资源列表 83 | func (r *resourceService) GetMenuByUserId(userId int) ([]*model.Resource, error) { 84 | if userId <= 0 { 85 | err := gerror.New("userId不能为空") 86 | return nil, err 87 | } 88 | 89 | userRelations := ([]model.Relation)(nil) 90 | err := dao.Relation.Where(dao.Relation.Columns.UserId, userId).Structs(&userRelations) 91 | if len(userRelations) <= 0 { 92 | return nil, err 93 | } 94 | 95 | roleIds := make([]int64, 0, len(userRelations)) 96 | for _, v := range userRelations { 97 | roleIds = append(roleIds, v.RoleId) 98 | } 99 | 100 | roleResources := ([]model.RoleResource)(nil) 101 | err = dao.RoleResource.Where(dao.RoleResource.Columns.RoleId+" IN (?)", roleIds).Structs(&roleResources) 102 | if len(roleResources) <= 0 { 103 | return nil, err 104 | } 105 | 106 | resourceIds := make([]int64, 0, len(roleResources)) 107 | for _, v := range roleResources { 108 | resourceIds = append(resourceIds, v.ResourceId) 109 | } 110 | 111 | resources := make([]*model.Resource, 0) 112 | err = dao.Resource.Where("type = ?", "menu").WherePri(resourceIds).Order("sn ASC").Structs(&resources) 113 | if err != nil { 114 | return nil, err 115 | } 116 | 117 | return resources, nil 118 | } 119 | 120 | // GetMenuTreeByUserId 根据用户id获取改用户拥有的菜单资源 121 | func (r *resourceService) GetMenuTreeByUserId(userId int) (trees []common.TreeNode, err error) { 122 | resources, err := r.GetMenuByUserId(userId) 123 | if err != nil { 124 | return nil, err 125 | } 126 | 127 | trees = common.GenerateTree(model.GetResourceSlice(resources)) 128 | return 129 | } 130 | -------------------------------------------------------------------------------- /app/model/resource.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. Fill this file as you wish. 3 | // ========================================================================== 4 | 5 | package model 6 | 7 | import ( 8 | "gf-react-admin-server/app/model/internal" 9 | "gf-react-admin-server/library/common" 10 | ) 11 | 12 | // Resource is the golang structure for table admin_resource. 13 | type Resource internal.Resource 14 | 15 | // Fill with you ideas below. 16 | func (r *Resource) GetPrimKey() int { 17 | return int(r.Id) 18 | } 19 | 20 | func (r *Resource) GetParentPrimKey() int { 21 | return int(r.ParentId) 22 | } 23 | 24 | func (r *Resource) GetName() string { 25 | return r.Name 26 | } 27 | 28 | func (r *Resource) GetData() interface{} { 29 | return r 30 | } 31 | 32 | func (r *Resource) Root() bool { 33 | return r.ParentId == 0 34 | } 35 | 36 | // GetResourceSlice 将菜单资源slice转换为树形结构通用slice 37 | func GetResourceSlice(data []*Resource) (iTrees []common.ITreeNode) { 38 | for _, v := range data { 39 | iTrees = append(iTrees, v) 40 | } 41 | return 42 | } 43 | 44 | // CreateResourceReq 新增资源参数 45 | type CreateResourceReq struct { 46 | ParentId int64 `json:"parentId"` // 父资源id 47 | Name string `json:"name" v:"name@required#资源名称不能为空"` // 资源名称 48 | Alias string `json:"alias"` // 资源别称 49 | Url string `json:"url"` // 资源路径 50 | Enable bool `json:"enable"` // 0:不显示,1显示 51 | Icon string `json:"icon"` // 资源图标 52 | Type string `json:"type" v:"type@required|in:menu,button,link#资源类型不能为空|请选择正确的资源类型"` // 资源类型:menu-菜单;button-按钮;link-链接 53 | Sn int `json:"sn"` // 排序 54 | } 55 | 56 | // EditResourceReq 编辑资源参数 57 | type EditResourceReq struct { 58 | Id int64 `json:"id" v:"id@required|min:1#待编辑资源id不能为空|待编辑资源id不能为空"` // 主键id 59 | ParentId int64 `json:"parentId"` // 父资源id 60 | Name string `json:"name" v:"name@required#资源名称不能为空"` // 资源名称 61 | Alias string `json:"alias"` // 资源别称 62 | Url string `json:"url"` // 资源路径 63 | Enable bool `json:"enable"` // 0:不显示,1显示 64 | Icon string `json:"icon"` // 资源图标 65 | Type string `json:"type" v:"name@required|in:menu,button,link#资源类型不能为空|请选择正确的资源类型"` // 资源类型:menu-菜单;button-按钮;link-链接 66 | Sn int `json:"sn"` // 排序 67 | } 68 | 69 | // ResourceTree 资源树形结构 70 | type ResourceTree struct { 71 | Resource 72 | Child []ResourceTree `json:"child"` // 子资源 73 | } 74 | 75 | // ResourceRoleTree 角色对应的资源树形结构 76 | type ResourceRoleTree struct { 77 | Resource 78 | Checked bool `json:"checked"` // 是否选中 79 | Child []ResourceRoleTree `json:"child"` // 子资源 80 | } 81 | 82 | // ResourceReq 资源信息 83 | type ResourceInfo struct { 84 | Id int64 `json:"id"` // 主键id 85 | ParentId int64 `json:"parentId"` // 父资源id 86 | Name string `json:"name"` // 资源名称 87 | Alias string `json:"alias"` // 资源别称 88 | Url string `json:"url"` // 资源路径 89 | Enable bool `json:"enable"` // 0:不显示,1显示 90 | Icon string `json:"icon"` // 资源图标 91 | Type string `json:"type"` // 资源类型:menu-菜单;button-按钮;link-链接 92 | Sn int `json:"sn"` // 排序 93 | } 94 | -------------------------------------------------------------------------------- /app/middleware/jwt.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "gf-react-admin-server/app/model" 5 | "gf-react-admin-server/app/service" 6 | "gf-react-admin-server/library/response" 7 | "github.com/gogf/gcache-adapter/adapter" 8 | jwt "github.com/gogf/gf-jwt" 9 | "github.com/gogf/gf/frame/g" 10 | "github.com/gogf/gf/net/ghttp" 11 | "github.com/gogf/gf/util/gconv" 12 | "time" 13 | ) 14 | 15 | type JwtConfig struct { 16 | ExpireTime int // 过期时间 17 | RefreshTime int // 刷新时间 18 | SignKey string // 签名 19 | Realm string // 域 20 | IdentityKey string // 鉴权中用户唯一标识 21 | TokenLookup string // token在请求中位置 22 | TokenHeadName string // token前缀 23 | } 24 | 25 | var ( 26 | // gf-jwt middleware. gf-jwt自带的中间件 27 | JwtMiddleware *jwt.GfJWTMiddleware 28 | // jwt config. jwt配置 29 | JwtCfg *JwtConfig 30 | errorMsg = "无访问权限" 31 | ) 32 | 33 | type loginRes struct { 34 | Token string `json:"token"` 35 | Expire time.Time `json:"expire"` 36 | } 37 | 38 | // init to gf-jwt config. 进行jwt初始化 39 | func init() { 40 | // 初始化配置 41 | JwtCfg = new(JwtConfig) 42 | if err := g.Cfg().GetStruct("jwt", JwtCfg); err != nil { 43 | g.Log().Errorf("load jwt config fail, err: %v", err) 44 | } 45 | jwtMiddleware, err := jwt.New(&jwt.GfJWTMiddleware{ 46 | Realm: JwtCfg.Realm, 47 | Key: []byte(JwtCfg.SignKey), 48 | Timeout: time.Duration(JwtCfg.ExpireTime) * time.Minute, // 过期时间 49 | MaxRefresh: time.Duration(JwtCfg.RefreshTime) * time.Minute, // 刷新时间 50 | IdentityKey: JwtCfg.IdentityKey, 51 | TokenLookup: JwtCfg.TokenLookup, 52 | TokenHeadName: JwtCfg.TokenHeadName, 53 | TimeFunc: time.Now, 54 | CacheAdapter: adapter.NewRedis(g.Redis("cache")), // 采用redis替换默认的内存缓存 55 | Authenticator: Authenticator, 56 | PayloadFunc: PayloadFunc, 57 | Authorizator: Authorization, 58 | Unauthorized: Unauthorized, 59 | LoginResponse: LoginResponse, 60 | }) 61 | if err != nil { 62 | g.Log().Errorf("init jwt middleware fail, error: %v", err) 63 | } 64 | JwtMiddleware = jwtMiddleware 65 | } 66 | 67 | //TODO Authenticator user login valid, and return userInfo. 进行登录校验,返回用户信息、错误 68 | // @summary 登录 69 | // @tags 用户服务 70 | // @produce json 71 | // @param entity body model.UserLoginReq true "登录参数" 72 | // @router /v1/user/login [POST] 73 | func Authenticator(r *ghttp.Request) (interface{}, error) { 74 | var ( 75 | loginReg *model.UserLoginReq 76 | ) 77 | if err := r.Parse(&loginReg); err != nil { 78 | g.Log().Errorf("登录失败,err:[%v]", err) 79 | response.FailMsgExit(r, err.Error()) 80 | } 81 | loginRes, err := service.User.Login(loginReg) 82 | return gconv.Map(&loginRes), err 83 | } 84 | 85 | // PayloadFunc customer info to jwt. 放入自定义信息到jwt的claims中 86 | func PayloadFunc(data interface{}) jwt.MapClaims { 87 | claims := jwt.MapClaims{} 88 | params := data.(map[string]interface{}) 89 | if len(params) > 0 { 90 | for k, v := range params { 91 | claims[k] = v 92 | } 93 | } 94 | return claims 95 | } 96 | 97 | //TODO Authorization check user auth role by IdentityHandler func. 根据IdentityHandler方法返回的信息检查用户权限,返回false则检查失败 98 | func Authorization(data interface{}, r *ghttp.Request) bool { 99 | return true 100 | } 101 | 102 | // Unauthorized custom unauthorized result. 自定义无权限返回方法 103 | func Unauthorized(r *ghttp.Request, code int, message string) { 104 | g.Log().Warningf("访问失败,错误码:[%v], 错误信息:[%v], 请求路径:[%v],请求方法:[%v], router-method:[%v], router-uri:[%v], router-regNames [%v], router-regRule:[%v]", 105 | code, message, 106 | r.RequestURI, r.Method, r.Router.Method, r.Router.Uri, r.Router.RegNames, r.Router.RegRule) 107 | if message == "" { 108 | message = errorMsg 109 | } 110 | response.FailCodeAndMsgExit(r, code, message) 111 | } 112 | 113 | // LoginResponse custom callback login response. 自定义登录返回方法 114 | func LoginResponse(r *ghttp.Request, code int, token string, expire time.Time) { 115 | response.RestResultExit(r, code, "", &loginRes{ 116 | Token: token, 117 | Expire: expire, 118 | }) 119 | } 120 | 121 | // JwtAuth request head token valid. 检查请求中的token合法性 122 | func JwtAuth(r *ghttp.Request) { 123 | JwtMiddleware.MiddlewareFunc()(r) 124 | r.Middleware.Next() 125 | } 126 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /swagger/swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "contact": {} 5 | }, 6 | "paths": { 7 | "/v1/relation": { 8 | "put": { 9 | "produces": [ 10 | "application/json" 11 | ], 12 | "tags": [ 13 | "用户关系服务" 14 | ], 15 | "summary": "保存用户关系", 16 | "parameters": [ 17 | { 18 | "description": "保存用户关系参数", 19 | "name": "entity", 20 | "in": "body", 21 | "required": true, 22 | "schema": { 23 | "$ref": "#/definitions/model.SaveRelationReq" 24 | } 25 | } 26 | ] 27 | } 28 | }, 29 | "/v1/resource": { 30 | "put": { 31 | "produces": [ 32 | "application/json" 33 | ], 34 | "tags": [ 35 | "资源管理" 36 | ], 37 | "summary": "编辑资源信息", 38 | "parameters": [ 39 | { 40 | "description": "编辑资源参数", 41 | "name": "entity", 42 | "in": "body", 43 | "required": true, 44 | "schema": { 45 | "$ref": "#/definitions/model.EditResourceReq" 46 | } 47 | } 48 | ] 49 | }, 50 | "post": { 51 | "produces": [ 52 | "application/json" 53 | ], 54 | "tags": [ 55 | "资源管理" 56 | ], 57 | "summary": "新建资源信息", 58 | "parameters": [ 59 | { 60 | "description": "新建资源参数", 61 | "name": "entity", 62 | "in": "body", 63 | "required": true, 64 | "schema": { 65 | "$ref": "#/definitions/model.CreateResourceReq" 66 | } 67 | } 68 | ] 69 | } 70 | }, 71 | "/v1/resource/tree": { 72 | "get": { 73 | "produces": [ 74 | "application/json" 75 | ], 76 | "tags": [ 77 | "资源管理" 78 | ], 79 | "summary": "获取资源树形结构" 80 | } 81 | }, 82 | "/v1/role": { 83 | "get": { 84 | "produces": [ 85 | "application/json" 86 | ], 87 | "tags": [ 88 | "角色服务" 89 | ], 90 | "summary": "角色分页列表", 91 | "parameters": [ 92 | { 93 | "description": "角色列表搜索参数", 94 | "name": "entity", 95 | "in": "body", 96 | "required": true, 97 | "schema": { 98 | "$ref": "#/definitions/model.RoleQueryReq" 99 | } 100 | } 101 | ] 102 | }, 103 | "put": { 104 | "produces": [ 105 | "application/json" 106 | ], 107 | "tags": [ 108 | "角色服务" 109 | ], 110 | "summary": "编辑角色接口", 111 | "parameters": [ 112 | { 113 | "description": "编辑角色参数", 114 | "name": "entity", 115 | "in": "body", 116 | "required": true, 117 | "schema": { 118 | "$ref": "#/definitions/model.EditRoleReq" 119 | } 120 | } 121 | ] 122 | }, 123 | "post": { 124 | "produces": [ 125 | "application/json" 126 | ], 127 | "tags": [ 128 | "角色服务" 129 | ], 130 | "summary": "创建角色接口", 131 | "parameters": [ 132 | { 133 | "description": "创建角色参数", 134 | "name": "entity", 135 | "in": "body", 136 | "required": true, 137 | "schema": { 138 | "$ref": "#/definitions/model.CreateRoleReq" 139 | } 140 | } 141 | ] 142 | } 143 | }, 144 | "/v1/role/{id}": { 145 | "get": { 146 | "produces": [ 147 | "application/json" 148 | ], 149 | "tags": [ 150 | "角色服务" 151 | ], 152 | "summary": "角色详情", 153 | "parameters": [ 154 | { 155 | "type": "integer", 156 | "description": "角色id", 157 | "name": "id", 158 | "in": "path", 159 | "required": true 160 | } 161 | ] 162 | } 163 | }, 164 | "/v1/user/login": { 165 | "post": { 166 | "produces": [ 167 | "application/json" 168 | ], 169 | "tags": [ 170 | "用户服务" 171 | ], 172 | "summary": "登录", 173 | "parameters": [ 174 | { 175 | "description": "登录参数", 176 | "name": "entity", 177 | "in": "body", 178 | "required": true, 179 | "schema": { 180 | "$ref": "#/definitions/model.UserLoginReq" 181 | } 182 | } 183 | ] 184 | } 185 | }, 186 | "/v1/user/{id}": { 187 | "get": { 188 | "produces": [ 189 | "application/json" 190 | ], 191 | "tags": [ 192 | "用户服务" 193 | ], 194 | "summary": "用户详情", 195 | "parameters": [ 196 | { 197 | "type": "integer", 198 | "description": "用户id", 199 | "name": "id", 200 | "in": "path", 201 | "required": true 202 | } 203 | ] 204 | } 205 | } 206 | }, 207 | "definitions": { 208 | "model.CreateResourceReq": { 209 | "type": "object", 210 | "properties": { 211 | "alias": { 212 | "description": "资源别称", 213 | "type": "string" 214 | }, 215 | "enable": { 216 | "description": "0:不显示,1显示", 217 | "type": "boolean" 218 | }, 219 | "icon": { 220 | "description": "资源图标", 221 | "type": "string" 222 | }, 223 | "name": { 224 | "description": "资源名称", 225 | "type": "string" 226 | }, 227 | "parentId": { 228 | "description": "父资源id", 229 | "type": "integer" 230 | }, 231 | "sn": { 232 | "description": "排序", 233 | "type": "integer" 234 | }, 235 | "type": { 236 | "description": "资源类型:menu-菜单;button-按钮;link-链接", 237 | "type": "string" 238 | }, 239 | "url": { 240 | "description": "资源路径", 241 | "type": "string" 242 | } 243 | } 244 | }, 245 | "model.CreateRoleReq": { 246 | "type": "object", 247 | "properties": { 248 | "alias": { 249 | "description": "角色别名", 250 | "type": "string" 251 | }, 252 | "parentId": { 253 | "description": "父角色id", 254 | "type": "string" 255 | }, 256 | "roleName": { 257 | "description": "角色名称", 258 | "type": "string" 259 | } 260 | } 261 | }, 262 | "model.EditResourceReq": { 263 | "type": "object", 264 | "properties": { 265 | "alias": { 266 | "description": "资源别称", 267 | "type": "string" 268 | }, 269 | "enable": { 270 | "description": "0:不显示,1显示", 271 | "type": "boolean" 272 | }, 273 | "icon": { 274 | "description": "资源图标", 275 | "type": "string" 276 | }, 277 | "id": { 278 | "description": "主键id", 279 | "type": "integer" 280 | }, 281 | "name": { 282 | "description": "资源名称", 283 | "type": "string" 284 | }, 285 | "parentId": { 286 | "description": "父资源id", 287 | "type": "integer" 288 | }, 289 | "sn": { 290 | "description": "排序", 291 | "type": "integer" 292 | }, 293 | "type": { 294 | "description": "资源类型:menu-菜单;button-按钮;link-链接", 295 | "type": "string" 296 | }, 297 | "url": { 298 | "description": "资源路径", 299 | "type": "string" 300 | } 301 | } 302 | }, 303 | "model.EditRoleReq": { 304 | "type": "object", 305 | "properties": { 306 | "alias": { 307 | "description": "角色别名", 308 | "type": "string" 309 | }, 310 | "id": { 311 | "description": "角色id", 312 | "type": "integer" 313 | }, 314 | "parentId": { 315 | "description": "父角色id", 316 | "type": "string" 317 | }, 318 | "roleName": { 319 | "description": "角色名称", 320 | "type": "string" 321 | } 322 | } 323 | }, 324 | "model.RoleQueryReq": { 325 | "type": "object", 326 | "properties": { 327 | "pageNo": { 328 | "description": "分页页数", 329 | "type": "integer" 330 | }, 331 | "pageSize": { 332 | "description": "分页大小", 333 | "type": "integer" 334 | } 335 | } 336 | }, 337 | "model.SaveRelationReq": { 338 | "type": "object", 339 | "properties": { 340 | "roleIds": { 341 | "description": "角色id slice", 342 | "type": "array", 343 | "items": { 344 | "type": "integer" 345 | } 346 | }, 347 | "userId": { 348 | "description": "用户id", 349 | "type": "integer" 350 | } 351 | } 352 | }, 353 | "model.UserLoginReq": { 354 | "type": "object", 355 | "properties": { 356 | "account": { 357 | "description": "账号", 358 | "type": "string" 359 | }, 360 | "password": { 361 | "description": "密码", 362 | "type": "string" 363 | } 364 | } 365 | } 366 | } 367 | } -------------------------------------------------------------------------------- /app/dao/internal/role.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "context" 9 | "database/sql" 10 | "github.com/gogf/gf/database/gdb" 11 | "github.com/gogf/gf/frame/g" 12 | "github.com/gogf/gf/frame/gmvc" 13 | "time" 14 | 15 | "gf-react-admin-server/app/model" 16 | ) 17 | 18 | // RoleDao is the manager for logic model data accessing 19 | // and custom defined data operations functions management. 20 | type RoleDao struct { 21 | gmvc.M 22 | DB gdb.DB 23 | Table string 24 | Columns roleColumns 25 | } 26 | 27 | // RoleColumns defines and stores column names for table admin_role. 28 | type roleColumns struct { 29 | Id string // 30 | ParentId string // 父角色id 31 | RoleName string // 角色名称 32 | Alias string // 角色别名 33 | CreatedAt string // 创建时间 34 | UpdatedAt string // 更新时间 35 | DeletedAt string // 删除时间时间 36 | } 37 | 38 | var ( 39 | // Role is globally public accessible object for table admin_role operations. 40 | Role = &RoleDao{ 41 | M: g.DB("default").Model("admin_role").Safe(), 42 | DB: g.DB("default"), 43 | Table: "admin_role", 44 | Columns: roleColumns{ 45 | Id: "id", 46 | ParentId: "parent_id", 47 | RoleName: "role_name", 48 | Alias: "alias", 49 | CreatedAt: "created_at", 50 | UpdatedAt: "updated_at", 51 | DeletedAt: "deleted_at", 52 | }, 53 | } 54 | ) 55 | 56 | // Ctx is a chaining function, which creates and returns a new DB that is a shallow copy 57 | // of current DB object and with given context in it. 58 | // Note that this returned DB object can be used only once, so do not assign it to 59 | // a global or package variable for long using. 60 | func (d *RoleDao) Ctx(ctx context.Context) *RoleDao { 61 | return &RoleDao{M: d.M.Ctx(ctx)} 62 | } 63 | 64 | // As sets an alias name for current table. 65 | func (d *RoleDao) As(as string) *RoleDao { 66 | return &RoleDao{M: d.M.As(as)} 67 | } 68 | 69 | // TX sets the transaction for current operation. 70 | func (d *RoleDao) TX(tx *gdb.TX) *RoleDao { 71 | return &RoleDao{M: d.M.TX(tx)} 72 | } 73 | 74 | // Master marks the following operation on master node. 75 | func (d *RoleDao) Master() *RoleDao { 76 | return &RoleDao{M: d.M.Master()} 77 | } 78 | 79 | // Slave marks the following operation on slave node. 80 | // Note that it makes sense only if there's any slave node configured. 81 | func (d *RoleDao) Slave() *RoleDao { 82 | return &RoleDao{M: d.M.Slave()} 83 | } 84 | 85 | // Args sets custom arguments for model operation. 86 | func (d *RoleDao) Args(args ...interface{}) *RoleDao { 87 | return &RoleDao{M: d.M.Args(args...)} 88 | } 89 | 90 | // LeftJoin does "LEFT JOIN ... ON ..." statement on the model. 91 | // The parameter can be joined table and its joined condition, 92 | // and also with its alias name, like: 93 | // Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid") 94 | // Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid") 95 | func (d *RoleDao) LeftJoin(table ...string) *RoleDao { 96 | return &RoleDao{M: d.M.LeftJoin(table...)} 97 | } 98 | 99 | // RightJoin does "RIGHT JOIN ... ON ..." statement on the model. 100 | // The parameter
can be joined table and its joined condition, 101 | // and also with its alias name, like: 102 | // Table("user").RightJoin("user_detail", "user_detail.uid=user.uid") 103 | // Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid") 104 | func (d *RoleDao) RightJoin(table ...string) *RoleDao { 105 | return &RoleDao{M: d.M.RightJoin(table...)} 106 | } 107 | 108 | // InnerJoin does "INNER JOIN ... ON ..." statement on the model. 109 | // The parameter
can be joined table and its joined condition, 110 | // and also with its alias name, like: 111 | // Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid") 112 | // Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid") 113 | func (d *RoleDao) InnerJoin(table ...string) *RoleDao { 114 | return &RoleDao{M: d.M.InnerJoin(table...)} 115 | } 116 | 117 | // Fields sets the operation fields of the model, multiple fields joined using char ','. 118 | // The parameter can be type of string/map/*map/struct/*struct. 119 | func (d *RoleDao) Fields(fieldNamesOrMapStruct ...interface{}) *RoleDao { 120 | return &RoleDao{M: d.M.Fields(fieldNamesOrMapStruct...)} 121 | } 122 | 123 | // FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','. 124 | // The parameter can be type of string/map/*map/struct/*struct. 125 | func (d *RoleDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *RoleDao { 126 | return &RoleDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)} 127 | } 128 | 129 | // Option sets the extra operation option for the model. 130 | func (d *RoleDao) Option(option int) *RoleDao { 131 | return &RoleDao{M: d.M.Option(option)} 132 | } 133 | 134 | // OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers 135 | // the data and where attributes for empty values. 136 | func (d *RoleDao) OmitEmpty() *RoleDao { 137 | return &RoleDao{M: d.M.OmitEmpty()} 138 | } 139 | 140 | // Filter marks filtering the fields which does not exist in the fields of the operated table. 141 | func (d *RoleDao) Filter() *RoleDao { 142 | return &RoleDao{M: d.M.Filter()} 143 | } 144 | 145 | // Where sets the condition statement for the model. The parameter can be type of 146 | // string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times, 147 | // multiple conditions will be joined into where statement using "AND". 148 | // Eg: 149 | // Where("uid=10000") 150 | // Where("uid", 10000) 151 | // Where("money>? AND name like ?", 99999, "vip_%") 152 | // Where("uid", 1).Where("name", "john") 153 | // Where("status IN (?)", g.Slice{1,2,3}) 154 | // Where("age IN(?,?)", 18, 50) 155 | // Where(User{ Id : 1, UserName : "john"}) 156 | func (d *RoleDao) Where(where interface{}, args ...interface{}) *RoleDao { 157 | return &RoleDao{M: d.M.Where(where, args...)} 158 | } 159 | 160 | // WherePri does the same logic as M.Where except that if the parameter 161 | // is a single condition like int/string/float/slice, it treats the condition as the primary 162 | // key value. That is, if primary key is "id" and given parameter as "123", the 163 | // WherePri function treats the condition as "id=123", but M.Where treats the condition 164 | // as string "123". 165 | func (d *RoleDao) WherePri(where interface{}, args ...interface{}) *RoleDao { 166 | return &RoleDao{M: d.M.WherePri(where, args...)} 167 | } 168 | 169 | // And adds "AND" condition to the where statement. 170 | func (d *RoleDao) And(where interface{}, args ...interface{}) *RoleDao { 171 | return &RoleDao{M: d.M.And(where, args...)} 172 | } 173 | 174 | // Or adds "OR" condition to the where statement. 175 | func (d *RoleDao) Or(where interface{}, args ...interface{}) *RoleDao { 176 | return &RoleDao{M: d.M.Or(where, args...)} 177 | } 178 | 179 | // Group sets the "GROUP BY" statement for the model. 180 | func (d *RoleDao) Group(groupBy string) *RoleDao { 181 | return &RoleDao{M: d.M.Group(groupBy)} 182 | } 183 | 184 | // Order sets the "ORDER BY" statement for the model. 185 | func (d *RoleDao) Order(orderBy ...string) *RoleDao { 186 | return &RoleDao{M: d.M.Order(orderBy...)} 187 | } 188 | 189 | // Limit sets the "LIMIT" statement for the model. 190 | // The parameter can be either one or two number, if passed two number is passed, 191 | // it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]" 192 | // statement. 193 | func (d *RoleDao) Limit(limit ...int) *RoleDao { 194 | return &RoleDao{M: d.M.Limit(limit...)} 195 | } 196 | 197 | // Offset sets the "OFFSET" statement for the model. 198 | // It only makes sense for some databases like SQLServer, PostgreSQL, etc. 199 | func (d *RoleDao) Offset(offset int) *RoleDao { 200 | return &RoleDao{M: d.M.Offset(offset)} 201 | } 202 | 203 | // Page sets the paging number for the model. 204 | // The parameter is started from 1 for paging. 205 | // Note that, it differs that the Limit function start from 0 for "LIMIT" statement. 206 | func (d *RoleDao) Page(page, limit int) *RoleDao { 207 | return &RoleDao{M: d.M.Page(page, limit)} 208 | } 209 | 210 | // Batch sets the batch operation number for the model. 211 | func (d *RoleDao) Batch(batch int) *RoleDao { 212 | return &RoleDao{M: d.M.Batch(batch)} 213 | } 214 | 215 | // Cache sets the cache feature for the model. It caches the result of the sql, which means 216 | // if there's another same sql request, it just reads and returns the result from cache, it 217 | // but not committed and executed into the database. 218 | // 219 | // If the parameter < 0, which means it clear the cache with given . 220 | // If the parameter = 0, which means it never expires. 221 | // If the parameter > 0, which means it expires after . 222 | // 223 | // The optional parameter is used to bind a name to the cache, which means you can later 224 | // control the cache like changing the or clearing the cache with specified . 225 | // 226 | // Note that, the cache feature is disabled if the model is operating on a transaction. 227 | func (d *RoleDao) Cache(duration time.Duration, name ...string) *RoleDao { 228 | return &RoleDao{M: d.M.Cache(duration, name...)} 229 | } 230 | 231 | // Data sets the operation data for the model. 232 | // The parameter can be type of string/map/gmap/slice/struct/*struct, etc. 233 | // Eg: 234 | // Data("uid=10000") 235 | // Data("uid", 10000) 236 | // Data(g.Map{"uid": 10000, "name":"john"}) 237 | // Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"}) 238 | func (d *RoleDao) Data(data ...interface{}) *RoleDao { 239 | return &RoleDao{M: d.M.Data(data...)} 240 | } 241 | 242 | // All does "SELECT FROM ..." statement for the model. 243 | // It retrieves the records from table and returns the result as []*model.Role. 244 | // It returns nil if there's no record retrieved with the given conditions from table. 245 | // 246 | // The optional parameter is the same as the parameter of M.Where function, 247 | // see M.Where. 248 | func (d *RoleDao) All(where ...interface{}) ([]*model.Role, error) { 249 | all, err := d.M.All(where...) 250 | if err != nil { 251 | return nil, err 252 | } 253 | var entities []*model.Role 254 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 255 | return nil, err 256 | } 257 | return entities, nil 258 | } 259 | 260 | // One retrieves one record from table and returns the result as *model.Role. 261 | // It returns nil if there's no record retrieved with the given conditions from table. 262 | // 263 | // The optional parameter is the same as the parameter of M.Where function, 264 | // see M.Where. 265 | func (d *RoleDao) One(where ...interface{}) (*model.Role, error) { 266 | one, err := d.M.One(where...) 267 | if err != nil { 268 | return nil, err 269 | } 270 | var entity *model.Role 271 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 272 | return nil, err 273 | } 274 | return entity, nil 275 | } 276 | 277 | // FindOne retrieves and returns a single Record by M.WherePri and M.One. 278 | // Also see M.WherePri and M.One. 279 | func (d *RoleDao) FindOne(where ...interface{}) (*model.Role, error) { 280 | one, err := d.M.FindOne(where...) 281 | if err != nil { 282 | return nil, err 283 | } 284 | var entity *model.Role 285 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 286 | return nil, err 287 | } 288 | return entity, nil 289 | } 290 | 291 | // FindAll retrieves and returns Result by by M.WherePri and M.All. 292 | // Also see M.WherePri and M.All. 293 | func (d *RoleDao) FindAll(where ...interface{}) ([]*model.Role, error) { 294 | all, err := d.M.FindAll(where...) 295 | if err != nil { 296 | return nil, err 297 | } 298 | var entities []*model.Role 299 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 300 | return nil, err 301 | } 302 | return entities, nil 303 | } 304 | 305 | // Struct retrieves one record from table and converts it into given struct. 306 | // The parameter should be type of *struct/**struct. If type **struct is given, 307 | // it can create the struct internally during converting. 308 | // 309 | // The optional parameter is the same as the parameter of Model.Where function, 310 | // see Model.Where. 311 | // 312 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 313 | // from table and is not nil. 314 | // 315 | // Eg: 316 | // user := new(User) 317 | // err := dao.User.Where("id", 1).Struct(user) 318 | // 319 | // user := (*User)(nil) 320 | // err := dao.User.Where("id", 1).Struct(&user) 321 | func (d *RoleDao) Struct(pointer interface{}, where ...interface{}) error { 322 | return d.M.Struct(pointer, where...) 323 | } 324 | 325 | // Structs retrieves records from table and converts them into given struct slice. 326 | // The parameter should be type of *[]struct/*[]*struct. It can create and fill the struct 327 | // slice internally during converting. 328 | // 329 | // The optional parameter is the same as the parameter of Model.Where function, 330 | // see Model.Where. 331 | // 332 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 333 | // from table and is not empty. 334 | // 335 | // Eg: 336 | // users := ([]User)(nil) 337 | // err := dao.User.Structs(&users) 338 | // 339 | // users := ([]*User)(nil) 340 | // err := dao.User.Structs(&users) 341 | func (d *RoleDao) Structs(pointer interface{}, where ...interface{}) error { 342 | return d.M.Structs(pointer, where...) 343 | } 344 | 345 | // Scan automatically calls Struct or Structs function according to the type of parameter . 346 | // It calls function Struct if is type of *struct/**struct. 347 | // It calls function Structs if is type of *[]struct/*[]*struct. 348 | // 349 | // The optional parameter is the same as the parameter of Model.Where function, 350 | // see Model.Where. 351 | // 352 | // Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil. 353 | // 354 | // Eg: 355 | // user := new(User) 356 | // err := dao.User.Where("id", 1).Scan(user) 357 | // 358 | // user := (*User)(nil) 359 | // err := dao.User.Where("id", 1).Scan(&user) 360 | // 361 | // users := ([]User)(nil) 362 | // err := dao.User.Scan(&users) 363 | // 364 | // users := ([]*User)(nil) 365 | // err := dao.User.Scan(&users) 366 | func (d *RoleDao) Scan(pointer interface{}, where ...interface{}) error { 367 | return d.M.Scan(pointer, where...) 368 | } 369 | 370 | // Chunk iterates the table with given size and callback function. 371 | func (d *RoleDao) Chunk(limit int, callback func(entities []*model.Role, err error) bool) { 372 | d.M.Chunk(limit, func(result gdb.Result, err error) bool { 373 | var entities []*model.Role 374 | err = result.Structs(&entities) 375 | if err == sql.ErrNoRows { 376 | return false 377 | } 378 | return callback(entities, err) 379 | }) 380 | } 381 | 382 | // LockUpdate sets the lock for update for current operation. 383 | func (d *RoleDao) LockUpdate() *RoleDao { 384 | return &RoleDao{M: d.M.LockUpdate()} 385 | } 386 | 387 | // LockShared sets the lock in share mode for current operation. 388 | func (d *RoleDao) LockShared() *RoleDao { 389 | return &RoleDao{M: d.M.LockShared()} 390 | } 391 | 392 | // Unscoped enables/disables the soft deleting feature. 393 | func (d *RoleDao) Unscoped() *RoleDao { 394 | return &RoleDao{M: d.M.Unscoped()} 395 | } 396 | -------------------------------------------------------------------------------- /app/dao/internal/user.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "context" 9 | "database/sql" 10 | "github.com/gogf/gf/database/gdb" 11 | "github.com/gogf/gf/frame/g" 12 | "github.com/gogf/gf/frame/gmvc" 13 | "time" 14 | 15 | "gf-react-admin-server/app/model" 16 | ) 17 | 18 | // UserDao is the manager for logic model data accessing 19 | // and custom defined data operations functions management. 20 | type UserDao struct { 21 | gmvc.M 22 | DB gdb.DB 23 | Table string 24 | Columns userColumns 25 | } 26 | 27 | // UserColumns defines and stores column names for table admin_user. 28 | type userColumns struct { 29 | Id string // 30 | FullName string // 姓名 31 | Account string // 账号 32 | Password string // 密码 33 | Email string // 邮箱 34 | Mobile string // 手机号码 35 | Wechat string // 微信号 36 | Avatar string // 头像 37 | Sex string // 性别:0:未知,1:男,2:女 38 | Status string // 0:禁用,1正常 39 | CreatedAt string // 创建时间 40 | UpdatedAt string // 更新时间 41 | DeletedAt string // 删除时间时间 42 | } 43 | 44 | var ( 45 | // User is globally public accessible object for table admin_user operations. 46 | User = &UserDao{ 47 | M: g.DB("default").Model("admin_user").Safe(), 48 | DB: g.DB("default"), 49 | Table: "admin_user", 50 | Columns: userColumns{ 51 | Id: "id", 52 | FullName: "full_name", 53 | Account: "account", 54 | Password: "password", 55 | Email: "email", 56 | Mobile: "mobile", 57 | Wechat: "wechat", 58 | Avatar: "avatar", 59 | Sex: "sex", 60 | Status: "status", 61 | CreatedAt: "created_at", 62 | UpdatedAt: "updated_at", 63 | DeletedAt: "deleted_at", 64 | }, 65 | } 66 | ) 67 | 68 | // Ctx is a chaining function, which creates and returns a new DB that is a shallow copy 69 | // of current DB object and with given context in it. 70 | // Note that this returned DB object can be used only once, so do not assign it to 71 | // a global or package variable for long using. 72 | func (d *UserDao) Ctx(ctx context.Context) *UserDao { 73 | return &UserDao{M: d.M.Ctx(ctx)} 74 | } 75 | 76 | // As sets an alias name for current table. 77 | func (d *UserDao) As(as string) *UserDao { 78 | return &UserDao{M: d.M.As(as)} 79 | } 80 | 81 | // TX sets the transaction for current operation. 82 | func (d *UserDao) TX(tx *gdb.TX) *UserDao { 83 | return &UserDao{M: d.M.TX(tx)} 84 | } 85 | 86 | // Master marks the following operation on master node. 87 | func (d *UserDao) Master() *UserDao { 88 | return &UserDao{M: d.M.Master()} 89 | } 90 | 91 | // Slave marks the following operation on slave node. 92 | // Note that it makes sense only if there's any slave node configured. 93 | func (d *UserDao) Slave() *UserDao { 94 | return &UserDao{M: d.M.Slave()} 95 | } 96 | 97 | // Args sets custom arguments for model operation. 98 | func (d *UserDao) Args(args ...interface{}) *UserDao { 99 | return &UserDao{M: d.M.Args(args...)} 100 | } 101 | 102 | // LeftJoin does "LEFT JOIN ... ON ..." statement on the model. 103 | // The parameter
can be joined table and its joined condition, 104 | // and also with its alias name, like: 105 | // Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid") 106 | // Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid") 107 | func (d *UserDao) LeftJoin(table ...string) *UserDao { 108 | return &UserDao{M: d.M.LeftJoin(table...)} 109 | } 110 | 111 | // RightJoin does "RIGHT JOIN ... ON ..." statement on the model. 112 | // The parameter
can be joined table and its joined condition, 113 | // and also with its alias name, like: 114 | // Table("user").RightJoin("user_detail", "user_detail.uid=user.uid") 115 | // Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid") 116 | func (d *UserDao) RightJoin(table ...string) *UserDao { 117 | return &UserDao{M: d.M.RightJoin(table...)} 118 | } 119 | 120 | // InnerJoin does "INNER JOIN ... ON ..." statement on the model. 121 | // The parameter
can be joined table and its joined condition, 122 | // and also with its alias name, like: 123 | // Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid") 124 | // Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid") 125 | func (d *UserDao) InnerJoin(table ...string) *UserDao { 126 | return &UserDao{M: d.M.InnerJoin(table...)} 127 | } 128 | 129 | // Fields sets the operation fields of the model, multiple fields joined using char ','. 130 | // The parameter can be type of string/map/*map/struct/*struct. 131 | func (d *UserDao) Fields(fieldNamesOrMapStruct ...interface{}) *UserDao { 132 | return &UserDao{M: d.M.Fields(fieldNamesOrMapStruct...)} 133 | } 134 | 135 | // FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','. 136 | // The parameter can be type of string/map/*map/struct/*struct. 137 | func (d *UserDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *UserDao { 138 | return &UserDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)} 139 | } 140 | 141 | // Option sets the extra operation option for the model. 142 | func (d *UserDao) Option(option int) *UserDao { 143 | return &UserDao{M: d.M.Option(option)} 144 | } 145 | 146 | // OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers 147 | // the data and where attributes for empty values. 148 | func (d *UserDao) OmitEmpty() *UserDao { 149 | return &UserDao{M: d.M.OmitEmpty()} 150 | } 151 | 152 | // Filter marks filtering the fields which does not exist in the fields of the operated table. 153 | func (d *UserDao) Filter() *UserDao { 154 | return &UserDao{M: d.M.Filter()} 155 | } 156 | 157 | // Where sets the condition statement for the model. The parameter can be type of 158 | // string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times, 159 | // multiple conditions will be joined into where statement using "AND". 160 | // Eg: 161 | // Where("uid=10000") 162 | // Where("uid", 10000) 163 | // Where("money>? AND name like ?", 99999, "vip_%") 164 | // Where("uid", 1).Where("name", "john") 165 | // Where("status IN (?)", g.Slice{1,2,3}) 166 | // Where("age IN(?,?)", 18, 50) 167 | // Where(User{ Id : 1, UserName : "john"}) 168 | func (d *UserDao) Where(where interface{}, args ...interface{}) *UserDao { 169 | return &UserDao{M: d.M.Where(where, args...)} 170 | } 171 | 172 | // WherePri does the same logic as M.Where except that if the parameter 173 | // is a single condition like int/string/float/slice, it treats the condition as the primary 174 | // key value. That is, if primary key is "id" and given parameter as "123", the 175 | // WherePri function treats the condition as "id=123", but M.Where treats the condition 176 | // as string "123". 177 | func (d *UserDao) WherePri(where interface{}, args ...interface{}) *UserDao { 178 | return &UserDao{M: d.M.WherePri(where, args...)} 179 | } 180 | 181 | // And adds "AND" condition to the where statement. 182 | func (d *UserDao) And(where interface{}, args ...interface{}) *UserDao { 183 | return &UserDao{M: d.M.And(where, args...)} 184 | } 185 | 186 | // Or adds "OR" condition to the where statement. 187 | func (d *UserDao) Or(where interface{}, args ...interface{}) *UserDao { 188 | return &UserDao{M: d.M.Or(where, args...)} 189 | } 190 | 191 | // Group sets the "GROUP BY" statement for the model. 192 | func (d *UserDao) Group(groupBy string) *UserDao { 193 | return &UserDao{M: d.M.Group(groupBy)} 194 | } 195 | 196 | // Order sets the "ORDER BY" statement for the model. 197 | func (d *UserDao) Order(orderBy ...string) *UserDao { 198 | return &UserDao{M: d.M.Order(orderBy...)} 199 | } 200 | 201 | // Limit sets the "LIMIT" statement for the model. 202 | // The parameter can be either one or two number, if passed two number is passed, 203 | // it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]" 204 | // statement. 205 | func (d *UserDao) Limit(limit ...int) *UserDao { 206 | return &UserDao{M: d.M.Limit(limit...)} 207 | } 208 | 209 | // Offset sets the "OFFSET" statement for the model. 210 | // It only makes sense for some databases like SQLServer, PostgreSQL, etc. 211 | func (d *UserDao) Offset(offset int) *UserDao { 212 | return &UserDao{M: d.M.Offset(offset)} 213 | } 214 | 215 | // Page sets the paging number for the model. 216 | // The parameter is started from 1 for paging. 217 | // Note that, it differs that the Limit function start from 0 for "LIMIT" statement. 218 | func (d *UserDao) Page(page, limit int) *UserDao { 219 | return &UserDao{M: d.M.Page(page, limit)} 220 | } 221 | 222 | // Batch sets the batch operation number for the model. 223 | func (d *UserDao) Batch(batch int) *UserDao { 224 | return &UserDao{M: d.M.Batch(batch)} 225 | } 226 | 227 | // Cache sets the cache feature for the model. It caches the result of the sql, which means 228 | // if there's another same sql request, it just reads and returns the result from cache, it 229 | // but not committed and executed into the database. 230 | // 231 | // If the parameter < 0, which means it clear the cache with given . 232 | // If the parameter = 0, which means it never expires. 233 | // If the parameter > 0, which means it expires after . 234 | // 235 | // The optional parameter is used to bind a name to the cache, which means you can later 236 | // control the cache like changing the or clearing the cache with specified . 237 | // 238 | // Note that, the cache feature is disabled if the model is operating on a transaction. 239 | func (d *UserDao) Cache(duration time.Duration, name ...string) *UserDao { 240 | return &UserDao{M: d.M.Cache(duration, name...)} 241 | } 242 | 243 | // Data sets the operation data for the model. 244 | // The parameter can be type of string/map/gmap/slice/struct/*struct, etc. 245 | // Eg: 246 | // Data("uid=10000") 247 | // Data("uid", 10000) 248 | // Data(g.Map{"uid": 10000, "name":"john"}) 249 | // Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"}) 250 | func (d *UserDao) Data(data ...interface{}) *UserDao { 251 | return &UserDao{M: d.M.Data(data...)} 252 | } 253 | 254 | // All does "SELECT FROM ..." statement for the model. 255 | // It retrieves the records from table and returns the result as []*model.User. 256 | // It returns nil if there's no record retrieved with the given conditions from table. 257 | // 258 | // The optional parameter is the same as the parameter of M.Where function, 259 | // see M.Where. 260 | func (d *UserDao) All(where ...interface{}) ([]*model.User, error) { 261 | all, err := d.M.All(where...) 262 | if err != nil { 263 | return nil, err 264 | } 265 | var entities []*model.User 266 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 267 | return nil, err 268 | } 269 | return entities, nil 270 | } 271 | 272 | // One retrieves one record from table and returns the result as *model.User. 273 | // It returns nil if there's no record retrieved with the given conditions from table. 274 | // 275 | // The optional parameter is the same as the parameter of M.Where function, 276 | // see M.Where. 277 | func (d *UserDao) One(where ...interface{}) (*model.User, error) { 278 | one, err := d.M.One(where...) 279 | if err != nil { 280 | return nil, err 281 | } 282 | var entity *model.User 283 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 284 | return nil, err 285 | } 286 | return entity, nil 287 | } 288 | 289 | // FindOne retrieves and returns a single Record by M.WherePri and M.One. 290 | // Also see M.WherePri and M.One. 291 | func (d *UserDao) FindOne(where ...interface{}) (*model.User, error) { 292 | one, err := d.M.FindOne(where...) 293 | if err != nil { 294 | return nil, err 295 | } 296 | var entity *model.User 297 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 298 | return nil, err 299 | } 300 | return entity, nil 301 | } 302 | 303 | // FindAll retrieves and returns Result by by M.WherePri and M.All. 304 | // Also see M.WherePri and M.All. 305 | func (d *UserDao) FindAll(where ...interface{}) ([]*model.User, error) { 306 | all, err := d.M.FindAll(where...) 307 | if err != nil { 308 | return nil, err 309 | } 310 | var entities []*model.User 311 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 312 | return nil, err 313 | } 314 | return entities, nil 315 | } 316 | 317 | // Struct retrieves one record from table and converts it into given struct. 318 | // The parameter should be type of *struct/**struct. If type **struct is given, 319 | // it can create the struct internally during converting. 320 | // 321 | // The optional parameter is the same as the parameter of Model.Where function, 322 | // see Model.Where. 323 | // 324 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 325 | // from table and is not nil. 326 | // 327 | // Eg: 328 | // user := new(User) 329 | // err := dao.User.Where("id", 1).Struct(user) 330 | // 331 | // user := (*User)(nil) 332 | // err := dao.User.Where("id", 1).Struct(&user) 333 | func (d *UserDao) Struct(pointer interface{}, where ...interface{}) error { 334 | return d.M.Struct(pointer, where...) 335 | } 336 | 337 | // Structs retrieves records from table and converts them into given struct slice. 338 | // The parameter should be type of *[]struct/*[]*struct. It can create and fill the struct 339 | // slice internally during converting. 340 | // 341 | // The optional parameter is the same as the parameter of Model.Where function, 342 | // see Model.Where. 343 | // 344 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 345 | // from table and is not empty. 346 | // 347 | // Eg: 348 | // users := ([]User)(nil) 349 | // err := dao.User.Structs(&users) 350 | // 351 | // users := ([]*User)(nil) 352 | // err := dao.User.Structs(&users) 353 | func (d *UserDao) Structs(pointer interface{}, where ...interface{}) error { 354 | return d.M.Structs(pointer, where...) 355 | } 356 | 357 | // Scan automatically calls Struct or Structs function according to the type of parameter . 358 | // It calls function Struct if is type of *struct/**struct. 359 | // It calls function Structs if is type of *[]struct/*[]*struct. 360 | // 361 | // The optional parameter is the same as the parameter of Model.Where function, 362 | // see Model.Where. 363 | // 364 | // Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil. 365 | // 366 | // Eg: 367 | // user := new(User) 368 | // err := dao.User.Where("id", 1).Scan(user) 369 | // 370 | // user := (*User)(nil) 371 | // err := dao.User.Where("id", 1).Scan(&user) 372 | // 373 | // users := ([]User)(nil) 374 | // err := dao.User.Scan(&users) 375 | // 376 | // users := ([]*User)(nil) 377 | // err := dao.User.Scan(&users) 378 | func (d *UserDao) Scan(pointer interface{}, where ...interface{}) error { 379 | return d.M.Scan(pointer, where...) 380 | } 381 | 382 | // Chunk iterates the table with given size and callback function. 383 | func (d *UserDao) Chunk(limit int, callback func(entities []*model.User, err error) bool) { 384 | d.M.Chunk(limit, func(result gdb.Result, err error) bool { 385 | var entities []*model.User 386 | err = result.Structs(&entities) 387 | if err == sql.ErrNoRows { 388 | return false 389 | } 390 | return callback(entities, err) 391 | }) 392 | } 393 | 394 | // LockUpdate sets the lock for update for current operation. 395 | func (d *UserDao) LockUpdate() *UserDao { 396 | return &UserDao{M: d.M.LockUpdate()} 397 | } 398 | 399 | // LockShared sets the lock in share mode for current operation. 400 | func (d *UserDao) LockShared() *UserDao { 401 | return &UserDao{M: d.M.LockShared()} 402 | } 403 | 404 | // Unscoped enables/disables the soft deleting feature. 405 | func (d *UserDao) Unscoped() *UserDao { 406 | return &UserDao{M: d.M.Unscoped()} 407 | } 408 | -------------------------------------------------------------------------------- /app/dao/internal/relation.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "context" 9 | "database/sql" 10 | "github.com/gogf/gf/database/gdb" 11 | "github.com/gogf/gf/frame/g" 12 | "github.com/gogf/gf/frame/gmvc" 13 | "time" 14 | 15 | "gf-react-admin-server/app/model" 16 | ) 17 | 18 | // RelationDao is the manager for logic model data accessing 19 | // and custom defined data operations functions management. 20 | type RelationDao struct { 21 | gmvc.M 22 | DB gdb.DB 23 | Table string 24 | Columns relationColumns 25 | } 26 | 27 | // RelationColumns defines and stores column names for table admin_relation. 28 | type relationColumns struct { 29 | Id string // 30 | UserId string // 用户id 31 | RoleId string // 角色id 32 | CreatedAt string // 创建时间 33 | UpdatedAt string // 更新时间 34 | DeletedAt string // 删除时间 35 | } 36 | 37 | var ( 38 | // Relation is globally public accessible object for table admin_relation operations. 39 | Relation = &RelationDao{ 40 | M: g.DB("default").Model("admin_relation").Safe(), 41 | DB: g.DB("default"), 42 | Table: "admin_relation", 43 | Columns: relationColumns{ 44 | Id: "id", 45 | UserId: "user_id", 46 | RoleId: "role_id", 47 | CreatedAt: "created_at", 48 | UpdatedAt: "updated_at", 49 | DeletedAt: "deleted_at", 50 | }, 51 | } 52 | ) 53 | 54 | // Ctx is a chaining function, which creates and returns a new DB that is a shallow copy 55 | // of current DB object and with given context in it. 56 | // Note that this returned DB object can be used only once, so do not assign it to 57 | // a global or package variable for long using. 58 | func (d *RelationDao) Ctx(ctx context.Context) *RelationDao { 59 | return &RelationDao{M: d.M.Ctx(ctx)} 60 | } 61 | 62 | // As sets an alias name for current table. 63 | func (d *RelationDao) As(as string) *RelationDao { 64 | return &RelationDao{M: d.M.As(as)} 65 | } 66 | 67 | // TX sets the transaction for current operation. 68 | func (d *RelationDao) TX(tx *gdb.TX) *RelationDao { 69 | return &RelationDao{M: d.M.TX(tx)} 70 | } 71 | 72 | // Master marks the following operation on master node. 73 | func (d *RelationDao) Master() *RelationDao { 74 | return &RelationDao{M: d.M.Master()} 75 | } 76 | 77 | // Slave marks the following operation on slave node. 78 | // Note that it makes sense only if there's any slave node configured. 79 | func (d *RelationDao) Slave() *RelationDao { 80 | return &RelationDao{M: d.M.Slave()} 81 | } 82 | 83 | // Args sets custom arguments for model operation. 84 | func (d *RelationDao) Args(args ...interface{}) *RelationDao { 85 | return &RelationDao{M: d.M.Args(args...)} 86 | } 87 | 88 | // LeftJoin does "LEFT JOIN ... ON ..." statement on the model. 89 | // The parameter
can be joined table and its joined condition, 90 | // and also with its alias name, like: 91 | // Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid") 92 | // Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid") 93 | func (d *RelationDao) LeftJoin(table ...string) *RelationDao { 94 | return &RelationDao{M: d.M.LeftJoin(table...)} 95 | } 96 | 97 | // RightJoin does "RIGHT JOIN ... ON ..." statement on the model. 98 | // The parameter
can be joined table and its joined condition, 99 | // and also with its alias name, like: 100 | // Table("user").RightJoin("user_detail", "user_detail.uid=user.uid") 101 | // Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid") 102 | func (d *RelationDao) RightJoin(table ...string) *RelationDao { 103 | return &RelationDao{M: d.M.RightJoin(table...)} 104 | } 105 | 106 | // InnerJoin does "INNER JOIN ... ON ..." statement on the model. 107 | // The parameter
can be joined table and its joined condition, 108 | // and also with its alias name, like: 109 | // Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid") 110 | // Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid") 111 | func (d *RelationDao) InnerJoin(table ...string) *RelationDao { 112 | return &RelationDao{M: d.M.InnerJoin(table...)} 113 | } 114 | 115 | // Fields sets the operation fields of the model, multiple fields joined using char ','. 116 | // The parameter can be type of string/map/*map/struct/*struct. 117 | func (d *RelationDao) Fields(fieldNamesOrMapStruct ...interface{}) *RelationDao { 118 | return &RelationDao{M: d.M.Fields(fieldNamesOrMapStruct...)} 119 | } 120 | 121 | // FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','. 122 | // The parameter can be type of string/map/*map/struct/*struct. 123 | func (d *RelationDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *RelationDao { 124 | return &RelationDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)} 125 | } 126 | 127 | // Option sets the extra operation option for the model. 128 | func (d *RelationDao) Option(option int) *RelationDao { 129 | return &RelationDao{M: d.M.Option(option)} 130 | } 131 | 132 | // OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers 133 | // the data and where attributes for empty values. 134 | func (d *RelationDao) OmitEmpty() *RelationDao { 135 | return &RelationDao{M: d.M.OmitEmpty()} 136 | } 137 | 138 | // Filter marks filtering the fields which does not exist in the fields of the operated table. 139 | func (d *RelationDao) Filter() *RelationDao { 140 | return &RelationDao{M: d.M.Filter()} 141 | } 142 | 143 | // Where sets the condition statement for the model. The parameter can be type of 144 | // string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times, 145 | // multiple conditions will be joined into where statement using "AND". 146 | // Eg: 147 | // Where("uid=10000") 148 | // Where("uid", 10000) 149 | // Where("money>? AND name like ?", 99999, "vip_%") 150 | // Where("uid", 1).Where("name", "john") 151 | // Where("status IN (?)", g.Slice{1,2,3}) 152 | // Where("age IN(?,?)", 18, 50) 153 | // Where(User{ Id : 1, UserName : "john"}) 154 | func (d *RelationDao) Where(where interface{}, args ...interface{}) *RelationDao { 155 | return &RelationDao{M: d.M.Where(where, args...)} 156 | } 157 | 158 | // WherePri does the same logic as M.Where except that if the parameter 159 | // is a single condition like int/string/float/slice, it treats the condition as the primary 160 | // key value. That is, if primary key is "id" and given parameter as "123", the 161 | // WherePri function treats the condition as "id=123", but M.Where treats the condition 162 | // as string "123". 163 | func (d *RelationDao) WherePri(where interface{}, args ...interface{}) *RelationDao { 164 | return &RelationDao{M: d.M.WherePri(where, args...)} 165 | } 166 | 167 | // And adds "AND" condition to the where statement. 168 | func (d *RelationDao) And(where interface{}, args ...interface{}) *RelationDao { 169 | return &RelationDao{M: d.M.And(where, args...)} 170 | } 171 | 172 | // Or adds "OR" condition to the where statement. 173 | func (d *RelationDao) Or(where interface{}, args ...interface{}) *RelationDao { 174 | return &RelationDao{M: d.M.Or(where, args...)} 175 | } 176 | 177 | // Group sets the "GROUP BY" statement for the model. 178 | func (d *RelationDao) Group(groupBy string) *RelationDao { 179 | return &RelationDao{M: d.M.Group(groupBy)} 180 | } 181 | 182 | // Order sets the "ORDER BY" statement for the model. 183 | func (d *RelationDao) Order(orderBy ...string) *RelationDao { 184 | return &RelationDao{M: d.M.Order(orderBy...)} 185 | } 186 | 187 | // Limit sets the "LIMIT" statement for the model. 188 | // The parameter can be either one or two number, if passed two number is passed, 189 | // it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]" 190 | // statement. 191 | func (d *RelationDao) Limit(limit ...int) *RelationDao { 192 | return &RelationDao{M: d.M.Limit(limit...)} 193 | } 194 | 195 | // Offset sets the "OFFSET" statement for the model. 196 | // It only makes sense for some databases like SQLServer, PostgreSQL, etc. 197 | func (d *RelationDao) Offset(offset int) *RelationDao { 198 | return &RelationDao{M: d.M.Offset(offset)} 199 | } 200 | 201 | // Page sets the paging number for the model. 202 | // The parameter is started from 1 for paging. 203 | // Note that, it differs that the Limit function start from 0 for "LIMIT" statement. 204 | func (d *RelationDao) Page(page, limit int) *RelationDao { 205 | return &RelationDao{M: d.M.Page(page, limit)} 206 | } 207 | 208 | // Batch sets the batch operation number for the model. 209 | func (d *RelationDao) Batch(batch int) *RelationDao { 210 | return &RelationDao{M: d.M.Batch(batch)} 211 | } 212 | 213 | // Cache sets the cache feature for the model. It caches the result of the sql, which means 214 | // if there's another same sql request, it just reads and returns the result from cache, it 215 | // but not committed and executed into the database. 216 | // 217 | // If the parameter < 0, which means it clear the cache with given . 218 | // If the parameter = 0, which means it never expires. 219 | // If the parameter > 0, which means it expires after . 220 | // 221 | // The optional parameter is used to bind a name to the cache, which means you can later 222 | // control the cache like changing the or clearing the cache with specified . 223 | // 224 | // Note that, the cache feature is disabled if the model is operating on a transaction. 225 | func (d *RelationDao) Cache(duration time.Duration, name ...string) *RelationDao { 226 | return &RelationDao{M: d.M.Cache(duration, name...)} 227 | } 228 | 229 | // Data sets the operation data for the model. 230 | // The parameter can be type of string/map/gmap/slice/struct/*struct, etc. 231 | // Eg: 232 | // Data("uid=10000") 233 | // Data("uid", 10000) 234 | // Data(g.Map{"uid": 10000, "name":"john"}) 235 | // Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"}) 236 | func (d *RelationDao) Data(data ...interface{}) *RelationDao { 237 | return &RelationDao{M: d.M.Data(data...)} 238 | } 239 | 240 | // All does "SELECT FROM ..." statement for the model. 241 | // It retrieves the records from table and returns the result as []*model.Relation. 242 | // It returns nil if there's no record retrieved with the given conditions from table. 243 | // 244 | // The optional parameter is the same as the parameter of M.Where function, 245 | // see M.Where. 246 | func (d *RelationDao) All(where ...interface{}) ([]*model.Relation, error) { 247 | all, err := d.M.All(where...) 248 | if err != nil { 249 | return nil, err 250 | } 251 | var entities []*model.Relation 252 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 253 | return nil, err 254 | } 255 | return entities, nil 256 | } 257 | 258 | // One retrieves one record from table and returns the result as *model.Relation. 259 | // It returns nil if there's no record retrieved with the given conditions from table. 260 | // 261 | // The optional parameter is the same as the parameter of M.Where function, 262 | // see M.Where. 263 | func (d *RelationDao) One(where ...interface{}) (*model.Relation, error) { 264 | one, err := d.M.One(where...) 265 | if err != nil { 266 | return nil, err 267 | } 268 | var entity *model.Relation 269 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 270 | return nil, err 271 | } 272 | return entity, nil 273 | } 274 | 275 | // FindOne retrieves and returns a single Record by M.WherePri and M.One. 276 | // Also see M.WherePri and M.One. 277 | func (d *RelationDao) FindOne(where ...interface{}) (*model.Relation, error) { 278 | one, err := d.M.FindOne(where...) 279 | if err != nil { 280 | return nil, err 281 | } 282 | var entity *model.Relation 283 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 284 | return nil, err 285 | } 286 | return entity, nil 287 | } 288 | 289 | // FindAll retrieves and returns Result by by M.WherePri and M.All. 290 | // Also see M.WherePri and M.All. 291 | func (d *RelationDao) FindAll(where ...interface{}) ([]*model.Relation, error) { 292 | all, err := d.M.FindAll(where...) 293 | if err != nil { 294 | return nil, err 295 | } 296 | var entities []*model.Relation 297 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 298 | return nil, err 299 | } 300 | return entities, nil 301 | } 302 | 303 | // Struct retrieves one record from table and converts it into given struct. 304 | // The parameter should be type of *struct/**struct. If type **struct is given, 305 | // it can create the struct internally during converting. 306 | // 307 | // The optional parameter is the same as the parameter of Model.Where function, 308 | // see Model.Where. 309 | // 310 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 311 | // from table and is not nil. 312 | // 313 | // Eg: 314 | // user := new(User) 315 | // err := dao.User.Where("id", 1).Struct(user) 316 | // 317 | // user := (*User)(nil) 318 | // err := dao.User.Where("id", 1).Struct(&user) 319 | func (d *RelationDao) Struct(pointer interface{}, where ...interface{}) error { 320 | return d.M.Struct(pointer, where...) 321 | } 322 | 323 | // Structs retrieves records from table and converts them into given struct slice. 324 | // The parameter should be type of *[]struct/*[]*struct. It can create and fill the struct 325 | // slice internally during converting. 326 | // 327 | // The optional parameter is the same as the parameter of Model.Where function, 328 | // see Model.Where. 329 | // 330 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 331 | // from table and is not empty. 332 | // 333 | // Eg: 334 | // users := ([]User)(nil) 335 | // err := dao.User.Structs(&users) 336 | // 337 | // users := ([]*User)(nil) 338 | // err := dao.User.Structs(&users) 339 | func (d *RelationDao) Structs(pointer interface{}, where ...interface{}) error { 340 | return d.M.Structs(pointer, where...) 341 | } 342 | 343 | // Scan automatically calls Struct or Structs function according to the type of parameter . 344 | // It calls function Struct if is type of *struct/**struct. 345 | // It calls function Structs if is type of *[]struct/*[]*struct. 346 | // 347 | // The optional parameter is the same as the parameter of Model.Where function, 348 | // see Model.Where. 349 | // 350 | // Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil. 351 | // 352 | // Eg: 353 | // user := new(User) 354 | // err := dao.User.Where("id", 1).Scan(user) 355 | // 356 | // user := (*User)(nil) 357 | // err := dao.User.Where("id", 1).Scan(&user) 358 | // 359 | // users := ([]User)(nil) 360 | // err := dao.User.Scan(&users) 361 | // 362 | // users := ([]*User)(nil) 363 | // err := dao.User.Scan(&users) 364 | func (d *RelationDao) Scan(pointer interface{}, where ...interface{}) error { 365 | return d.M.Scan(pointer, where...) 366 | } 367 | 368 | // Chunk iterates the table with given size and callback function. 369 | func (d *RelationDao) Chunk(limit int, callback func(entities []*model.Relation, err error) bool) { 370 | d.M.Chunk(limit, func(result gdb.Result, err error) bool { 371 | var entities []*model.Relation 372 | err = result.Structs(&entities) 373 | if err == sql.ErrNoRows { 374 | return false 375 | } 376 | return callback(entities, err) 377 | }) 378 | } 379 | 380 | // LockUpdate sets the lock for update for current operation. 381 | func (d *RelationDao) LockUpdate() *RelationDao { 382 | return &RelationDao{M: d.M.LockUpdate()} 383 | } 384 | 385 | // LockShared sets the lock in share mode for current operation. 386 | func (d *RelationDao) LockShared() *RelationDao { 387 | return &RelationDao{M: d.M.LockShared()} 388 | } 389 | 390 | // Unscoped enables/disables the soft deleting feature. 391 | func (d *RelationDao) Unscoped() *RelationDao { 392 | return &RelationDao{M: d.M.Unscoped()} 393 | } 394 | -------------------------------------------------------------------------------- /app/dao/internal/resource.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "context" 9 | "database/sql" 10 | "github.com/gogf/gf/database/gdb" 11 | "github.com/gogf/gf/frame/g" 12 | "github.com/gogf/gf/frame/gmvc" 13 | "time" 14 | 15 | "gf-react-admin-server/app/model" 16 | ) 17 | 18 | // ResourceDao is the manager for logic model data accessing 19 | // and custom defined data operations functions management. 20 | type ResourceDao struct { 21 | gmvc.M 22 | DB gdb.DB 23 | Table string 24 | Columns resourceColumns 25 | } 26 | 27 | // ResourceColumns defines and stores column names for table admin_resource. 28 | type resourceColumns struct { 29 | Id string // 30 | ParentId string // 父资源id 31 | Name string // 资源名称 32 | Alias string // 资源别称 33 | Url string // 资源路径 34 | Enable string // 0:不显示,1显示 35 | Icon string // 资源图标 36 | Type string // 资源类型:menu-菜单;button-按钮;link-链接 37 | Sn string // 排序 38 | CreateBy string // 创建人 39 | CreatedAt string // 创建时间 40 | UpdatedBy string // 更新人 41 | UpdatedAt string // 更新时间 42 | DeleteBy string // 删除人 43 | DeletedAt string // 删除时间时间 44 | } 45 | 46 | var ( 47 | // Resource is globally public accessible object for table admin_resource operations. 48 | Resource = &ResourceDao{ 49 | M: g.DB("default").Model("admin_resource").Safe(), 50 | DB: g.DB("default"), 51 | Table: "admin_resource", 52 | Columns: resourceColumns{ 53 | Id: "id", 54 | ParentId: "parent_id", 55 | Name: "name", 56 | Alias: "alias", 57 | Url: "url", 58 | Enable: "enable", 59 | Icon: "icon", 60 | Type: "type", 61 | Sn: "sn", 62 | CreateBy: "create_by", 63 | CreatedAt: "created_at", 64 | UpdatedBy: "updated_by", 65 | UpdatedAt: "updated_at", 66 | DeleteBy: "delete_by", 67 | DeletedAt: "deleted_at", 68 | }, 69 | } 70 | ) 71 | 72 | // Ctx is a chaining function, which creates and returns a new DB that is a shallow copy 73 | // of current DB object and with given context in it. 74 | // Note that this returned DB object can be used only once, so do not assign it to 75 | // a global or package variable for long using. 76 | func (d *ResourceDao) Ctx(ctx context.Context) *ResourceDao { 77 | return &ResourceDao{M: d.M.Ctx(ctx)} 78 | } 79 | 80 | // As sets an alias name for current table. 81 | func (d *ResourceDao) As(as string) *ResourceDao { 82 | return &ResourceDao{M: d.M.As(as)} 83 | } 84 | 85 | // TX sets the transaction for current operation. 86 | func (d *ResourceDao) TX(tx *gdb.TX) *ResourceDao { 87 | return &ResourceDao{M: d.M.TX(tx)} 88 | } 89 | 90 | // Master marks the following operation on master node. 91 | func (d *ResourceDao) Master() *ResourceDao { 92 | return &ResourceDao{M: d.M.Master()} 93 | } 94 | 95 | // Slave marks the following operation on slave node. 96 | // Note that it makes sense only if there's any slave node configured. 97 | func (d *ResourceDao) Slave() *ResourceDao { 98 | return &ResourceDao{M: d.M.Slave()} 99 | } 100 | 101 | // Args sets custom arguments for model operation. 102 | func (d *ResourceDao) Args(args ...interface{}) *ResourceDao { 103 | return &ResourceDao{M: d.M.Args(args...)} 104 | } 105 | 106 | // LeftJoin does "LEFT JOIN ... ON ..." statement on the model. 107 | // The parameter
can be joined table and its joined condition, 108 | // and also with its alias name, like: 109 | // Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid") 110 | // Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid") 111 | func (d *ResourceDao) LeftJoin(table ...string) *ResourceDao { 112 | return &ResourceDao{M: d.M.LeftJoin(table...)} 113 | } 114 | 115 | // RightJoin does "RIGHT JOIN ... ON ..." statement on the model. 116 | // The parameter
can be joined table and its joined condition, 117 | // and also with its alias name, like: 118 | // Table("user").RightJoin("user_detail", "user_detail.uid=user.uid") 119 | // Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid") 120 | func (d *ResourceDao) RightJoin(table ...string) *ResourceDao { 121 | return &ResourceDao{M: d.M.RightJoin(table...)} 122 | } 123 | 124 | // InnerJoin does "INNER JOIN ... ON ..." statement on the model. 125 | // The parameter
can be joined table and its joined condition, 126 | // and also with its alias name, like: 127 | // Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid") 128 | // Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid") 129 | func (d *ResourceDao) InnerJoin(table ...string) *ResourceDao { 130 | return &ResourceDao{M: d.M.InnerJoin(table...)} 131 | } 132 | 133 | // Fields sets the operation fields of the model, multiple fields joined using char ','. 134 | // The parameter can be type of string/map/*map/struct/*struct. 135 | func (d *ResourceDao) Fields(fieldNamesOrMapStruct ...interface{}) *ResourceDao { 136 | return &ResourceDao{M: d.M.Fields(fieldNamesOrMapStruct...)} 137 | } 138 | 139 | // FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','. 140 | // The parameter can be type of string/map/*map/struct/*struct. 141 | func (d *ResourceDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *ResourceDao { 142 | return &ResourceDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)} 143 | } 144 | 145 | // Option sets the extra operation option for the model. 146 | func (d *ResourceDao) Option(option int) *ResourceDao { 147 | return &ResourceDao{M: d.M.Option(option)} 148 | } 149 | 150 | // OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers 151 | // the data and where attributes for empty values. 152 | func (d *ResourceDao) OmitEmpty() *ResourceDao { 153 | return &ResourceDao{M: d.M.OmitEmpty()} 154 | } 155 | 156 | // Filter marks filtering the fields which does not exist in the fields of the operated table. 157 | func (d *ResourceDao) Filter() *ResourceDao { 158 | return &ResourceDao{M: d.M.Filter()} 159 | } 160 | 161 | // Where sets the condition statement for the model. The parameter can be type of 162 | // string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times, 163 | // multiple conditions will be joined into where statement using "AND". 164 | // Eg: 165 | // Where("uid=10000") 166 | // Where("uid", 10000) 167 | // Where("money>? AND name like ?", 99999, "vip_%") 168 | // Where("uid", 1).Where("name", "john") 169 | // Where("status IN (?)", g.Slice{1,2,3}) 170 | // Where("age IN(?,?)", 18, 50) 171 | // Where(User{ Id : 1, UserName : "john"}) 172 | func (d *ResourceDao) Where(where interface{}, args ...interface{}) *ResourceDao { 173 | return &ResourceDao{M: d.M.Where(where, args...)} 174 | } 175 | 176 | // WherePri does the same logic as M.Where except that if the parameter 177 | // is a single condition like int/string/float/slice, it treats the condition as the primary 178 | // key value. That is, if primary key is "id" and given parameter as "123", the 179 | // WherePri function treats the condition as "id=123", but M.Where treats the condition 180 | // as string "123". 181 | func (d *ResourceDao) WherePri(where interface{}, args ...interface{}) *ResourceDao { 182 | return &ResourceDao{M: d.M.WherePri(where, args...)} 183 | } 184 | 185 | // And adds "AND" condition to the where statement. 186 | func (d *ResourceDao) And(where interface{}, args ...interface{}) *ResourceDao { 187 | return &ResourceDao{M: d.M.And(where, args...)} 188 | } 189 | 190 | // Or adds "OR" condition to the where statement. 191 | func (d *ResourceDao) Or(where interface{}, args ...interface{}) *ResourceDao { 192 | return &ResourceDao{M: d.M.Or(where, args...)} 193 | } 194 | 195 | // Group sets the "GROUP BY" statement for the model. 196 | func (d *ResourceDao) Group(groupBy string) *ResourceDao { 197 | return &ResourceDao{M: d.M.Group(groupBy)} 198 | } 199 | 200 | // Order sets the "ORDER BY" statement for the model. 201 | func (d *ResourceDao) Order(orderBy ...string) *ResourceDao { 202 | return &ResourceDao{M: d.M.Order(orderBy...)} 203 | } 204 | 205 | // Limit sets the "LIMIT" statement for the model. 206 | // The parameter can be either one or two number, if passed two number is passed, 207 | // it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]" 208 | // statement. 209 | func (d *ResourceDao) Limit(limit ...int) *ResourceDao { 210 | return &ResourceDao{M: d.M.Limit(limit...)} 211 | } 212 | 213 | // Offset sets the "OFFSET" statement for the model. 214 | // It only makes sense for some databases like SQLServer, PostgreSQL, etc. 215 | func (d *ResourceDao) Offset(offset int) *ResourceDao { 216 | return &ResourceDao{M: d.M.Offset(offset)} 217 | } 218 | 219 | // Page sets the paging number for the model. 220 | // The parameter is started from 1 for paging. 221 | // Note that, it differs that the Limit function start from 0 for "LIMIT" statement. 222 | func (d *ResourceDao) Page(page, limit int) *ResourceDao { 223 | return &ResourceDao{M: d.M.Page(page, limit)} 224 | } 225 | 226 | // Batch sets the batch operation number for the model. 227 | func (d *ResourceDao) Batch(batch int) *ResourceDao { 228 | return &ResourceDao{M: d.M.Batch(batch)} 229 | } 230 | 231 | // Cache sets the cache feature for the model. It caches the result of the sql, which means 232 | // if there's another same sql request, it just reads and returns the result from cache, it 233 | // but not committed and executed into the database. 234 | // 235 | // If the parameter < 0, which means it clear the cache with given . 236 | // If the parameter = 0, which means it never expires. 237 | // If the parameter > 0, which means it expires after . 238 | // 239 | // The optional parameter is used to bind a name to the cache, which means you can later 240 | // control the cache like changing the or clearing the cache with specified . 241 | // 242 | // Note that, the cache feature is disabled if the model is operating on a transaction. 243 | func (d *ResourceDao) Cache(duration time.Duration, name ...string) *ResourceDao { 244 | return &ResourceDao{M: d.M.Cache(duration, name...)} 245 | } 246 | 247 | // Data sets the operation data for the model. 248 | // The parameter can be type of string/map/gmap/slice/struct/*struct, etc. 249 | // Eg: 250 | // Data("uid=10000") 251 | // Data("uid", 10000) 252 | // Data(g.Map{"uid": 10000, "name":"john"}) 253 | // Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"}) 254 | func (d *ResourceDao) Data(data ...interface{}) *ResourceDao { 255 | return &ResourceDao{M: d.M.Data(data...)} 256 | } 257 | 258 | // All does "SELECT FROM ..." statement for the model. 259 | // It retrieves the records from table and returns the result as []*model.Resource. 260 | // It returns nil if there's no record retrieved with the given conditions from table. 261 | // 262 | // The optional parameter is the same as the parameter of M.Where function, 263 | // see M.Where. 264 | func (d *ResourceDao) All(where ...interface{}) ([]*model.Resource, error) { 265 | all, err := d.M.All(where...) 266 | if err != nil { 267 | return nil, err 268 | } 269 | var entities []*model.Resource 270 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 271 | return nil, err 272 | } 273 | return entities, nil 274 | } 275 | 276 | // One retrieves one record from table and returns the result as *model.Resource. 277 | // It returns nil if there's no record retrieved with the given conditions from table. 278 | // 279 | // The optional parameter is the same as the parameter of M.Where function, 280 | // see M.Where. 281 | func (d *ResourceDao) One(where ...interface{}) (*model.Resource, error) { 282 | one, err := d.M.One(where...) 283 | if err != nil { 284 | return nil, err 285 | } 286 | var entity *model.Resource 287 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 288 | return nil, err 289 | } 290 | return entity, nil 291 | } 292 | 293 | // FindOne retrieves and returns a single Record by M.WherePri and M.One. 294 | // Also see M.WherePri and M.One. 295 | func (d *ResourceDao) FindOne(where ...interface{}) (*model.Resource, error) { 296 | one, err := d.M.FindOne(where...) 297 | if err != nil { 298 | return nil, err 299 | } 300 | var entity *model.Resource 301 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 302 | return nil, err 303 | } 304 | return entity, nil 305 | } 306 | 307 | // FindAll retrieves and returns Result by by M.WherePri and M.All. 308 | // Also see M.WherePri and M.All. 309 | func (d *ResourceDao) FindAll(where ...interface{}) ([]*model.Resource, error) { 310 | all, err := d.M.FindAll(where...) 311 | if err != nil { 312 | return nil, err 313 | } 314 | var entities []*model.Resource 315 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 316 | return nil, err 317 | } 318 | return entities, nil 319 | } 320 | 321 | // Struct retrieves one record from table and converts it into given struct. 322 | // The parameter should be type of *struct/**struct. If type **struct is given, 323 | // it can create the struct internally during converting. 324 | // 325 | // The optional parameter is the same as the parameter of Model.Where function, 326 | // see Model.Where. 327 | // 328 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 329 | // from table and is not nil. 330 | // 331 | // Eg: 332 | // user := new(User) 333 | // err := dao.User.Where("id", 1).Struct(user) 334 | // 335 | // user := (*User)(nil) 336 | // err := dao.User.Where("id", 1).Struct(&user) 337 | func (d *ResourceDao) Struct(pointer interface{}, where ...interface{}) error { 338 | return d.M.Struct(pointer, where...) 339 | } 340 | 341 | // Structs retrieves records from table and converts them into given struct slice. 342 | // The parameter should be type of *[]struct/*[]*struct. It can create and fill the struct 343 | // slice internally during converting. 344 | // 345 | // The optional parameter is the same as the parameter of Model.Where function, 346 | // see Model.Where. 347 | // 348 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 349 | // from table and is not empty. 350 | // 351 | // Eg: 352 | // users := ([]User)(nil) 353 | // err := dao.User.Structs(&users) 354 | // 355 | // users := ([]*User)(nil) 356 | // err := dao.User.Structs(&users) 357 | func (d *ResourceDao) Structs(pointer interface{}, where ...interface{}) error { 358 | return d.M.Structs(pointer, where...) 359 | } 360 | 361 | // Scan automatically calls Struct or Structs function according to the type of parameter . 362 | // It calls function Struct if is type of *struct/**struct. 363 | // It calls function Structs if is type of *[]struct/*[]*struct. 364 | // 365 | // The optional parameter is the same as the parameter of Model.Where function, 366 | // see Model.Where. 367 | // 368 | // Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil. 369 | // 370 | // Eg: 371 | // user := new(User) 372 | // err := dao.User.Where("id", 1).Scan(user) 373 | // 374 | // user := (*User)(nil) 375 | // err := dao.User.Where("id", 1).Scan(&user) 376 | // 377 | // users := ([]User)(nil) 378 | // err := dao.User.Scan(&users) 379 | // 380 | // users := ([]*User)(nil) 381 | // err := dao.User.Scan(&users) 382 | func (d *ResourceDao) Scan(pointer interface{}, where ...interface{}) error { 383 | return d.M.Scan(pointer, where...) 384 | } 385 | 386 | // Chunk iterates the table with given size and callback function. 387 | func (d *ResourceDao) Chunk(limit int, callback func(entities []*model.Resource, err error) bool) { 388 | d.M.Chunk(limit, func(result gdb.Result, err error) bool { 389 | var entities []*model.Resource 390 | err = result.Structs(&entities) 391 | if err == sql.ErrNoRows { 392 | return false 393 | } 394 | return callback(entities, err) 395 | }) 396 | } 397 | 398 | // LockUpdate sets the lock for update for current operation. 399 | func (d *ResourceDao) LockUpdate() *ResourceDao { 400 | return &ResourceDao{M: d.M.LockUpdate()} 401 | } 402 | 403 | // LockShared sets the lock in share mode for current operation. 404 | func (d *ResourceDao) LockShared() *ResourceDao { 405 | return &ResourceDao{M: d.M.LockShared()} 406 | } 407 | 408 | // Unscoped enables/disables the soft deleting feature. 409 | func (d *ResourceDao) Unscoped() *ResourceDao { 410 | return &ResourceDao{M: d.M.Unscoped()} 411 | } 412 | -------------------------------------------------------------------------------- /app/dao/internal/role_resource.go: -------------------------------------------------------------------------------- 1 | // ========================================================================== 2 | // This is auto-generated by gf cli tool. DO NOT EDIT THIS FILE MANUALLY. 3 | // ========================================================================== 4 | 5 | package internal 6 | 7 | import ( 8 | "context" 9 | "database/sql" 10 | "github.com/gogf/gf/database/gdb" 11 | "github.com/gogf/gf/frame/g" 12 | "github.com/gogf/gf/frame/gmvc" 13 | "time" 14 | 15 | "gf-react-admin-server/app/model" 16 | ) 17 | 18 | // RoleResourceDao is the manager for logic model data accessing 19 | // and custom defined data operations functions management. 20 | type RoleResourceDao struct { 21 | gmvc.M 22 | DB gdb.DB 23 | Table string 24 | Columns roleResourceColumns 25 | } 26 | 27 | // RoleResourceColumns defines and stores column names for table admin_role_resource. 28 | type roleResourceColumns struct { 29 | Id string // 30 | RoleId string // 角色id 31 | ResourceId string // 资源id 32 | CreateBy string // 创建人 33 | CreatedAt string // 创建时间 34 | UpdatedBy string // 更新人 35 | UpdatedAt string // 更新时间 36 | DeleteBy string // 删除人 37 | DeletedAt string // 删除时间时间 38 | } 39 | 40 | var ( 41 | // RoleResource is globally public accessible object for table admin_role_resource operations. 42 | RoleResource = &RoleResourceDao{ 43 | M: g.DB("default").Model("admin_role_resource").Safe(), 44 | DB: g.DB("default"), 45 | Table: "admin_role_resource", 46 | Columns: roleResourceColumns{ 47 | Id: "id", 48 | RoleId: "role_id", 49 | ResourceId: "resource_id", 50 | CreateBy: "create_by", 51 | CreatedAt: "created_at", 52 | UpdatedBy: "updated_by", 53 | UpdatedAt: "updated_at", 54 | DeleteBy: "delete_by", 55 | DeletedAt: "deleted_at", 56 | }, 57 | } 58 | ) 59 | 60 | // Ctx is a chaining function, which creates and returns a new DB that is a shallow copy 61 | // of current DB object and with given context in it. 62 | // Note that this returned DB object can be used only once, so do not assign it to 63 | // a global or package variable for long using. 64 | func (d *RoleResourceDao) Ctx(ctx context.Context) *RoleResourceDao { 65 | return &RoleResourceDao{M: d.M.Ctx(ctx)} 66 | } 67 | 68 | // As sets an alias name for current table. 69 | func (d *RoleResourceDao) As(as string) *RoleResourceDao { 70 | return &RoleResourceDao{M: d.M.As(as)} 71 | } 72 | 73 | // TX sets the transaction for current operation. 74 | func (d *RoleResourceDao) TX(tx *gdb.TX) *RoleResourceDao { 75 | return &RoleResourceDao{M: d.M.TX(tx)} 76 | } 77 | 78 | // Master marks the following operation on master node. 79 | func (d *RoleResourceDao) Master() *RoleResourceDao { 80 | return &RoleResourceDao{M: d.M.Master()} 81 | } 82 | 83 | // Slave marks the following operation on slave node. 84 | // Note that it makes sense only if there's any slave node configured. 85 | func (d *RoleResourceDao) Slave() *RoleResourceDao { 86 | return &RoleResourceDao{M: d.M.Slave()} 87 | } 88 | 89 | // Args sets custom arguments for model operation. 90 | func (d *RoleResourceDao) Args(args ...interface{}) *RoleResourceDao { 91 | return &RoleResourceDao{M: d.M.Args(args...)} 92 | } 93 | 94 | // LeftJoin does "LEFT JOIN ... ON ..." statement on the model. 95 | // The parameter
can be joined table and its joined condition, 96 | // and also with its alias name, like: 97 | // Table("user").LeftJoin("user_detail", "user_detail.uid=user.uid") 98 | // Table("user", "u").LeftJoin("user_detail", "ud", "ud.uid=u.uid") 99 | func (d *RoleResourceDao) LeftJoin(table ...string) *RoleResourceDao { 100 | return &RoleResourceDao{M: d.M.LeftJoin(table...)} 101 | } 102 | 103 | // RightJoin does "RIGHT JOIN ... ON ..." statement on the model. 104 | // The parameter
can be joined table and its joined condition, 105 | // and also with its alias name, like: 106 | // Table("user").RightJoin("user_detail", "user_detail.uid=user.uid") 107 | // Table("user", "u").RightJoin("user_detail", "ud", "ud.uid=u.uid") 108 | func (d *RoleResourceDao) RightJoin(table ...string) *RoleResourceDao { 109 | return &RoleResourceDao{M: d.M.RightJoin(table...)} 110 | } 111 | 112 | // InnerJoin does "INNER JOIN ... ON ..." statement on the model. 113 | // The parameter
can be joined table and its joined condition, 114 | // and also with its alias name, like: 115 | // Table("user").InnerJoin("user_detail", "user_detail.uid=user.uid") 116 | // Table("user", "u").InnerJoin("user_detail", "ud", "ud.uid=u.uid") 117 | func (d *RoleResourceDao) InnerJoin(table ...string) *RoleResourceDao { 118 | return &RoleResourceDao{M: d.M.InnerJoin(table...)} 119 | } 120 | 121 | // Fields sets the operation fields of the model, multiple fields joined using char ','. 122 | // The parameter can be type of string/map/*map/struct/*struct. 123 | func (d *RoleResourceDao) Fields(fieldNamesOrMapStruct ...interface{}) *RoleResourceDao { 124 | return &RoleResourceDao{M: d.M.Fields(fieldNamesOrMapStruct...)} 125 | } 126 | 127 | // FieldsEx sets the excluded operation fields of the model, multiple fields joined using char ','. 128 | // The parameter can be type of string/map/*map/struct/*struct. 129 | func (d *RoleResourceDao) FieldsEx(fieldNamesOrMapStruct ...interface{}) *RoleResourceDao { 130 | return &RoleResourceDao{M: d.M.FieldsEx(fieldNamesOrMapStruct...)} 131 | } 132 | 133 | // Option sets the extra operation option for the model. 134 | func (d *RoleResourceDao) Option(option int) *RoleResourceDao { 135 | return &RoleResourceDao{M: d.M.Option(option)} 136 | } 137 | 138 | // OmitEmpty sets OPTION_OMITEMPTY option for the model, which automatically filers 139 | // the data and where attributes for empty values. 140 | func (d *RoleResourceDao) OmitEmpty() *RoleResourceDao { 141 | return &RoleResourceDao{M: d.M.OmitEmpty()} 142 | } 143 | 144 | // Filter marks filtering the fields which does not exist in the fields of the operated table. 145 | func (d *RoleResourceDao) Filter() *RoleResourceDao { 146 | return &RoleResourceDao{M: d.M.Filter()} 147 | } 148 | 149 | // Where sets the condition statement for the model. The parameter can be type of 150 | // string/map/gmap/slice/struct/*struct, etc. Note that, if it's called more than one times, 151 | // multiple conditions will be joined into where statement using "AND". 152 | // Eg: 153 | // Where("uid=10000") 154 | // Where("uid", 10000) 155 | // Where("money>? AND name like ?", 99999, "vip_%") 156 | // Where("uid", 1).Where("name", "john") 157 | // Where("status IN (?)", g.Slice{1,2,3}) 158 | // Where("age IN(?,?)", 18, 50) 159 | // Where(User{ Id : 1, UserName : "john"}) 160 | func (d *RoleResourceDao) Where(where interface{}, args ...interface{}) *RoleResourceDao { 161 | return &RoleResourceDao{M: d.M.Where(where, args...)} 162 | } 163 | 164 | // WherePri does the same logic as M.Where except that if the parameter 165 | // is a single condition like int/string/float/slice, it treats the condition as the primary 166 | // key value. That is, if primary key is "id" and given parameter as "123", the 167 | // WherePri function treats the condition as "id=123", but M.Where treats the condition 168 | // as string "123". 169 | func (d *RoleResourceDao) WherePri(where interface{}, args ...interface{}) *RoleResourceDao { 170 | return &RoleResourceDao{M: d.M.WherePri(where, args...)} 171 | } 172 | 173 | // And adds "AND" condition to the where statement. 174 | func (d *RoleResourceDao) And(where interface{}, args ...interface{}) *RoleResourceDao { 175 | return &RoleResourceDao{M: d.M.And(where, args...)} 176 | } 177 | 178 | // Or adds "OR" condition to the where statement. 179 | func (d *RoleResourceDao) Or(where interface{}, args ...interface{}) *RoleResourceDao { 180 | return &RoleResourceDao{M: d.M.Or(where, args...)} 181 | } 182 | 183 | // Group sets the "GROUP BY" statement for the model. 184 | func (d *RoleResourceDao) Group(groupBy string) *RoleResourceDao { 185 | return &RoleResourceDao{M: d.M.Group(groupBy)} 186 | } 187 | 188 | // Order sets the "ORDER BY" statement for the model. 189 | func (d *RoleResourceDao) Order(orderBy ...string) *RoleResourceDao { 190 | return &RoleResourceDao{M: d.M.Order(orderBy...)} 191 | } 192 | 193 | // Limit sets the "LIMIT" statement for the model. 194 | // The parameter can be either one or two number, if passed two number is passed, 195 | // it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]" 196 | // statement. 197 | func (d *RoleResourceDao) Limit(limit ...int) *RoleResourceDao { 198 | return &RoleResourceDao{M: d.M.Limit(limit...)} 199 | } 200 | 201 | // Offset sets the "OFFSET" statement for the model. 202 | // It only makes sense for some databases like SQLServer, PostgreSQL, etc. 203 | func (d *RoleResourceDao) Offset(offset int) *RoleResourceDao { 204 | return &RoleResourceDao{M: d.M.Offset(offset)} 205 | } 206 | 207 | // Page sets the paging number for the model. 208 | // The parameter is started from 1 for paging. 209 | // Note that, it differs that the Limit function start from 0 for "LIMIT" statement. 210 | func (d *RoleResourceDao) Page(page, limit int) *RoleResourceDao { 211 | return &RoleResourceDao{M: d.M.Page(page, limit)} 212 | } 213 | 214 | // Batch sets the batch operation number for the model. 215 | func (d *RoleResourceDao) Batch(batch int) *RoleResourceDao { 216 | return &RoleResourceDao{M: d.M.Batch(batch)} 217 | } 218 | 219 | // Cache sets the cache feature for the model. It caches the result of the sql, which means 220 | // if there's another same sql request, it just reads and returns the result from cache, it 221 | // but not committed and executed into the database. 222 | // 223 | // If the parameter < 0, which means it clear the cache with given . 224 | // If the parameter = 0, which means it never expires. 225 | // If the parameter > 0, which means it expires after . 226 | // 227 | // The optional parameter is used to bind a name to the cache, which means you can later 228 | // control the cache like changing the or clearing the cache with specified . 229 | // 230 | // Note that, the cache feature is disabled if the model is operating on a transaction. 231 | func (d *RoleResourceDao) Cache(duration time.Duration, name ...string) *RoleResourceDao { 232 | return &RoleResourceDao{M: d.M.Cache(duration, name...)} 233 | } 234 | 235 | // Data sets the operation data for the model. 236 | // The parameter can be type of string/map/gmap/slice/struct/*struct, etc. 237 | // Eg: 238 | // Data("uid=10000") 239 | // Data("uid", 10000) 240 | // Data(g.Map{"uid": 10000, "name":"john"}) 241 | // Data(g.Slice{g.Map{"uid": 10000, "name":"john"}, g.Map{"uid": 20000, "name":"smith"}) 242 | func (d *RoleResourceDao) Data(data ...interface{}) *RoleResourceDao { 243 | return &RoleResourceDao{M: d.M.Data(data...)} 244 | } 245 | 246 | // All does "SELECT FROM ..." statement for the model. 247 | // It retrieves the records from table and returns the result as []*model.RoleResource. 248 | // It returns nil if there's no record retrieved with the given conditions from table. 249 | // 250 | // The optional parameter is the same as the parameter of M.Where function, 251 | // see M.Where. 252 | func (d *RoleResourceDao) All(where ...interface{}) ([]*model.RoleResource, error) { 253 | all, err := d.M.All(where...) 254 | if err != nil { 255 | return nil, err 256 | } 257 | var entities []*model.RoleResource 258 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 259 | return nil, err 260 | } 261 | return entities, nil 262 | } 263 | 264 | // One retrieves one record from table and returns the result as *model.RoleResource. 265 | // It returns nil if there's no record retrieved with the given conditions from table. 266 | // 267 | // The optional parameter is the same as the parameter of M.Where function, 268 | // see M.Where. 269 | func (d *RoleResourceDao) One(where ...interface{}) (*model.RoleResource, error) { 270 | one, err := d.M.One(where...) 271 | if err != nil { 272 | return nil, err 273 | } 274 | var entity *model.RoleResource 275 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 276 | return nil, err 277 | } 278 | return entity, nil 279 | } 280 | 281 | // FindOne retrieves and returns a single Record by M.WherePri and M.One. 282 | // Also see M.WherePri and M.One. 283 | func (d *RoleResourceDao) FindOne(where ...interface{}) (*model.RoleResource, error) { 284 | one, err := d.M.FindOne(where...) 285 | if err != nil { 286 | return nil, err 287 | } 288 | var entity *model.RoleResource 289 | if err = one.Struct(&entity); err != nil && err != sql.ErrNoRows { 290 | return nil, err 291 | } 292 | return entity, nil 293 | } 294 | 295 | // FindAll retrieves and returns Result by by M.WherePri and M.All. 296 | // Also see M.WherePri and M.All. 297 | func (d *RoleResourceDao) FindAll(where ...interface{}) ([]*model.RoleResource, error) { 298 | all, err := d.M.FindAll(where...) 299 | if err != nil { 300 | return nil, err 301 | } 302 | var entities []*model.RoleResource 303 | if err = all.Structs(&entities); err != nil && err != sql.ErrNoRows { 304 | return nil, err 305 | } 306 | return entities, nil 307 | } 308 | 309 | // Struct retrieves one record from table and converts it into given struct. 310 | // The parameter should be type of *struct/**struct. If type **struct is given, 311 | // it can create the struct internally during converting. 312 | // 313 | // The optional parameter is the same as the parameter of Model.Where function, 314 | // see Model.Where. 315 | // 316 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 317 | // from table and is not nil. 318 | // 319 | // Eg: 320 | // user := new(User) 321 | // err := dao.User.Where("id", 1).Struct(user) 322 | // 323 | // user := (*User)(nil) 324 | // err := dao.User.Where("id", 1).Struct(&user) 325 | func (d *RoleResourceDao) Struct(pointer interface{}, where ...interface{}) error { 326 | return d.M.Struct(pointer, where...) 327 | } 328 | 329 | // Structs retrieves records from table and converts them into given struct slice. 330 | // The parameter should be type of *[]struct/*[]*struct. It can create and fill the struct 331 | // slice internally during converting. 332 | // 333 | // The optional parameter is the same as the parameter of Model.Where function, 334 | // see Model.Where. 335 | // 336 | // Note that it returns sql.ErrNoRows if there's no record retrieved with the given conditions 337 | // from table and is not empty. 338 | // 339 | // Eg: 340 | // users := ([]User)(nil) 341 | // err := dao.User.Structs(&users) 342 | // 343 | // users := ([]*User)(nil) 344 | // err := dao.User.Structs(&users) 345 | func (d *RoleResourceDao) Structs(pointer interface{}, where ...interface{}) error { 346 | return d.M.Structs(pointer, where...) 347 | } 348 | 349 | // Scan automatically calls Struct or Structs function according to the type of parameter . 350 | // It calls function Struct if is type of *struct/**struct. 351 | // It calls function Structs if is type of *[]struct/*[]*struct. 352 | // 353 | // The optional parameter is the same as the parameter of Model.Where function, 354 | // see Model.Where. 355 | // 356 | // Note that it returns sql.ErrNoRows if there's no record retrieved and given pointer is not empty or nil. 357 | // 358 | // Eg: 359 | // user := new(User) 360 | // err := dao.User.Where("id", 1).Scan(user) 361 | // 362 | // user := (*User)(nil) 363 | // err := dao.User.Where("id", 1).Scan(&user) 364 | // 365 | // users := ([]User)(nil) 366 | // err := dao.User.Scan(&users) 367 | // 368 | // users := ([]*User)(nil) 369 | // err := dao.User.Scan(&users) 370 | func (d *RoleResourceDao) Scan(pointer interface{}, where ...interface{}) error { 371 | return d.M.Scan(pointer, where...) 372 | } 373 | 374 | // Chunk iterates the table with given size and callback function. 375 | func (d *RoleResourceDao) Chunk(limit int, callback func(entities []*model.RoleResource, err error) bool) { 376 | d.M.Chunk(limit, func(result gdb.Result, err error) bool { 377 | var entities []*model.RoleResource 378 | err = result.Structs(&entities) 379 | if err == sql.ErrNoRows { 380 | return false 381 | } 382 | return callback(entities, err) 383 | }) 384 | } 385 | 386 | // LockUpdate sets the lock for update for current operation. 387 | func (d *RoleResourceDao) LockUpdate() *RoleResourceDao { 388 | return &RoleResourceDao{M: d.M.LockUpdate()} 389 | } 390 | 391 | // LockShared sets the lock in share mode for current operation. 392 | func (d *RoleResourceDao) LockShared() *RoleResourceDao { 393 | return &RoleResourceDao{M: d.M.LockShared()} 394 | } 395 | 396 | // Unscoped enables/disables the soft deleting feature. 397 | func (d *RoleResourceDao) Unscoped() *RoleResourceDao { 398 | return &RoleResourceDao{M: d.M.Unscoped()} 399 | } 400 | --------------------------------------------------------------------------------