Initial commit

This commit is contained in:
zze 2023-09-22 16:55:57 +08:00 committed by GitHub
commit dd96cce40e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
134 changed files with 3613 additions and 0 deletions

1
.gitattributes vendored Normal file
View File

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

20
.gitignore vendored Normal file
View File

@ -0,0 +1,20 @@
.buildpath
.hgignore.swp
.project
.orig
.swp
.idea/
.settings/
.vscode/
bin/
**/.DS_Store
gf
main
main.exe
output/
manifest/output/
temp/
temp.yaml
bin
**/config/config-prod.yaml
dist

6
Makefile Normal file
View File

@ -0,0 +1,6 @@
ROOT_DIR = $(shell pwd)
NAMESPACE = "default"
DEPLOY_NAME = "zze-admin-go"
DOCKER_NAME = "zze-admin-go"
include ./hack/hack.mk

42
README.MD Normal file
View File

@ -0,0 +1,42 @@
# zze Admin go
## 功能
本项目主要用来作为新项目启动时的模板如果你想要使用 Golang 来新开发一个后台管理系统那么选我就对了
- 已实现后台管理系统最基础的用户管理角色管理权限管理基于它来开发可以让你可以更聚焦业务的实现
- 选用了相对成熟稳定功能齐全的的框架后端基于 **[GoFrame](https://goframe.org/pages/viewpage.action?pageId=1114119)**
前端基于 **[PureAdmin](https://yiming_chang.gitee.io/pure-admin-doc/pages/introduction/)**
- 支持一套权限管理逻辑控制前后端路由按钮级别权限
## 预览地址
[点我预览](http://admin.zze.xyz)
- 管理员`admin`密码`devops.zze`
- 测试账号`test`密码`devops.zze`
效果图
![用户管理](https://raw.githubusercontent.com/zze326/zze-admin-go/main/resource/imgs/user-manage.png)
![角色管理](https://raw.githubusercontent.com/zze326/zze-admin-go/main/resource/imgs/role-manage.png)
![权限管理](https://raw.githubusercontent.com/zze326/zze-admin-go/main/resource/imgs/permission-manage.png)
![部门管理](https://raw.githubusercontent.com/zze326/zze-admin-go/main/resource/imgs/dept-manage.png)
## 技术栈
- 语言GolangTypescript
- 后端GoFrameCasbin
- 前端Vue3ViteElement-PlusTypeScriptPinia
## 项目运行
1 MySQL 中执行 `manifest/db/zze_admin_go.sql` 创建好数据库以及初始化数据
2然后修改 `manifest/config/config.yaml` 中的数据库连接地址`database.default.link`格式如下
```sql
mysql:<用户名>:<密码>@tcp(<数据库地址>)/<库名>?loc=Local&parseTime=true
-- mysql:zze:zze.admin@tcp(127.0.0.1:3306)/zze_admin_go?loc=Local&parseTime=true
```
3直接运行项目根目录的 `main.go` 就可以跑起来啦~
## 前端项目
本仓库是后端项目对应前端项目地址为<https://github.com/zze326/zze-admin-fe>。

29
api/common.go Normal file
View File

@ -0,0 +1,29 @@
package api
import (
"github.com/gogf/gf/v2/encoding/gjson"
)
type PageLstReq struct {
Page int `p:"page" v:"page @integer|min:1#页码必填" dc:"页码"` // 页码
PageSize int `p:"pageSize" v:"pageSize @integer|min:1#每页数量必填" dc:"每页数量"` // 每页数量
Search string `p:"search" dc:"模糊搜索内容"` // 搜索内容
Wheres *gjson.Json `p:"wheres" dc:"搜索条件"`
}
func (r *PageLstReq) Offset() int {
return (r.Page - 1) * r.PageSize
}
func (r *PageLstReq) Limit() int {
return r.PageSize
}
func (r *PageLstReq) SearchStr() string {
return "%" + r.Search + "%"
}
type PageLstRes[T any] struct {
Total int `json:"total" dc:"总数"` // 总数
List []T `json:"list" dc:"列表"` // 列表
}

18
api/dept/dept.go Normal file
View File

@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package dept
import (
"context"
"devops-super/api/dept/v1"
)
type IDeptV1 interface {
Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error)
GetLst(ctx context.Context, req *v1.GetLstReq) (res *v1.GetLstRes, err error)
Upt(ctx context.Context, req *v1.UptReq) (res *v1.UptRes, err error)
Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error)
}

38
api/dept/v1/dept.go Normal file
View File

@ -0,0 +1,38 @@
package v1
import (
"devops-super/internal/model/entity"
"devops-super/internal/model/mid"
"github.com/gogf/gf/v2/frame/g"
)
type AddReq struct {
g.Meta `path:"/dept" method:"post" tags:"部门" summary:"新增部门"`
*mid.Dept
}
type AddRes struct{}
type GetLstReq struct {
g.Meta `path:"/dept/list" method:"get" tags:"部门" summary:"获取部门列表"`
Search string `p:"search"`
}
type GetLstRes struct {
List []*entity.Dept `json:"list"`
}
type UptReq struct {
g.Meta `path:"/dept/{id}" method:"put" tags:"部门" summary:"更新部门"`
Id int ` v:"min:1#id必须" path:"id"`
*mid.Dept
}
type UptRes struct{}
type DelReq struct {
g.Meta `path:"/dept/{id}" method:"delete" tags:"部门" summary:"删除部门"`
Id int `v:"min:1#id必须" path:"id" `
}
type DelRes struct{}

View File

@ -0,0 +1,22 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package permission
import (
"context"
"devops-super/api/permission/v1"
)
type IPermissionV1 interface {
Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error)
GetLst(ctx context.Context, req *v1.GetLstReq) (res *v1.GetLstRes, err error)
Upt(ctx context.Context, req *v1.UptReq) (res *v1.UptRes, err error)
UptShowLink(ctx context.Context, req *v1.UptShowLinkReq) (res *v1.UptShowLinkRes, err error)
Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error)
GetRouteLst(ctx context.Context, req *v1.GetRouteLstReq) (res *v1.GetRouteLstRes, err error)
}

View File

@ -0,0 +1,54 @@
package v1
import (
"devops-super/internal/model/entity"
"devops-super/internal/model/mid"
"github.com/gogf/gf/v2/frame/g"
)
type AddReq struct {
g.Meta `path:"/permission" method:"post" tags:"权限" summary:"创建权限"`
*mid.Permission
}
type AddRes struct{}
type GetLstReq struct {
g.Meta `path:"/permission/list" method:"get" tags:"权限" summary:"获取权限列表"`
Search string `p:"search"`
}
type GetLstRes struct {
List []*entity.Permission `json:"list"`
}
type UptReq struct {
g.Meta `path:"/permission/{id}" method:"put" tags:"权限" summary:"更新权限"`
Id int ` v:"min:1#id必须" path:"id"`
*mid.Permission
}
type UptRes struct{}
type UptShowLinkReq struct {
g.Meta `path:"/permission/{id}/show-link" method:"patch" tags:"权限" summary:"更新是否显示在菜单"`
Id int `v:"min:1#id必须" path:"id" `
Enabled bool `v:"required" json:"enabled"`
}
type UptShowLinkRes struct{}
type DelReq struct {
g.Meta `path:"/permission/{id}" method:"delete" tags:"权限" summary:"删除权限"`
Id int `v:"min:1#id必须" path:"id" `
}
type DelRes struct{}
type GetRouteLstReq struct {
g.Meta `path:"/permission/route-list" method:"get" tags:"权限" summary:"获取前端路由列表"`
}
type GetRouteLstRes struct {
List []*mid.Route `json:"list"`
}

18
api/public/public.go Normal file
View File

@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package public
import (
"context"
"devops-super/api/public/v1"
)
type IPublicV1 interface {
Login(ctx context.Context, req *v1.LoginReq) (res *v1.LoginRes, err error)
RefreshToken(ctx context.Context, req *v1.RefreshTokenReq) (res *v1.RefreshTokenRes, err error)
Logout(ctx context.Context, req *v1.LogoutReq) (res *v1.LogoutRes, err error)
Ping(ctx context.Context, req *v1.PingReq) (res *v1.PingRes, err error)
}

37
api/public/v1/login.go Normal file
View File

@ -0,0 +1,37 @@
package v1
import "github.com/gogf/gf/v2/frame/g"
type LoginReq struct {
g.Meta `path:"/login" tags:"用户" method:"post" summary:"登录"`
Username string `v:"required#请输入用户名" json:"username" dc:"用户名"`
Password string `v:"required#请输入密码" json:"password" dc:"密码"`
}
type LoginRes struct {
Username string `json:"username"`
RealName string `json:"realName"`
Token string `json:"token"`
Expires int64 `json:"expires"`
RefreshAfter int64 `json:"refreshAfter"`
Roles []string `json:"roles"`
}
type RefreshTokenReq struct {
g.Meta `path:"/refresh-token" method:"post" tags:"用户" summary:"刷新 Token"`
}
type RefreshTokenRes struct {
Username string `json:"username"`
RealName string `json:"realName"`
Token string `json:"token"`
Expire int64 `json:"expire"`
RefreshAfter int64 `json:"refreshAfter"`
Roles []string `json:"roles"`
}
type LogoutReq struct {
g.Meta `path:"/logout" method:"post" tags:"用户" summary:"用户登出"`
}
type LogoutRes struct{}

9
api/public/v1/public.go Normal file
View File

@ -0,0 +1,9 @@
package v1
import "github.com/gogf/gf/v2/frame/g"
type PingReq struct {
g.Meta `path:"/ping" method:"get" tags:"健康检查" summary:"ping"`
}
type PingRes struct{}

22
api/role/role.go Normal file
View File

@ -0,0 +1,22 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package role
import (
"context"
"devops-super/api/role/v1"
)
type IRoleV1 interface {
UptPermission(ctx context.Context, req *v1.UptPermissionReq) (res *v1.UptPermissionRes, err error)
GetPageLst(ctx context.Context, req *v1.GetPageLstReq) (res *v1.GetPageLstRes, err error)
Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error)
Upt(ctx context.Context, req *v1.UptReq) (res *v1.UptRes, err error)
Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error)
GetLst(ctx context.Context, req *v1.GetLstReq) (res *v1.GetLstRes, err error)
}

14
api/role/v1/permission.go Normal file
View File

@ -0,0 +1,14 @@
package v1
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
)
type UptPermissionReq struct {
g.Meta `method:"patch" path:"/role/{id}/permission" summary:"更新角色关联的权限" tags:"角色"`
Id int `v:"min:1#id必须" path:"id"`
PermissionIds *gjson.Json `json:"permissionIds"`
}
type UptPermissionRes struct{}

48
api/role/v1/role.go Normal file
View File

@ -0,0 +1,48 @@
package v1
import (
"devops-super/api"
"devops-super/internal/model/entity"
"devops-super/internal/model/mid"
"github.com/gogf/gf/v2/frame/g"
)
type GetPageLstReq struct {
g.Meta `method:"get" path:"/role/page-list" summary:"分页获取角色列表" tags:"角色"`
*api.PageLstReq
}
type GetPageLstRes struct {
*api.PageLstRes[*entity.Role]
}
type AddReq struct {
g.Meta `method:"post" path:"/role" summary:"添加角色" tags:"角色"`
*mid.Role
}
type AddRes struct{}
type UptReq struct {
g.Meta `method:"put" path:"/role/{id}" summary:"更新角色" tags:"角色"`
Id int ` v:"min:1#id必须" path:"id"`
*mid.Role
}
type UptRes struct{}
type DelReq struct {
g.Meta `method:"delete" path:"/role/{id}" summary:"删除角色" tags:"角色"`
Id int ` v:"min:1#id必须" path:"id"`
}
type DelRes struct{}
type GetLstReq struct {
g.Meta `method:"get" path:"/role/list" summary:"获取所有角色列表" tags:"角色"`
*api.PageLstReq
}
type GetLstRes struct {
List []*entity.Role `json:"list"`
}

22
api/user/user.go Normal file
View File

@ -0,0 +1,22 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package user
import (
"context"
"devops-super/api/user/v1"
)
type IUserV1 interface {
GetPageLst(ctx context.Context, req *v1.GetPageLstReq) (res *v1.GetPageLstRes, err error)
Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error)
Upt(ctx context.Context, req *v1.UptReq) (res *v1.UptRes, err error)
UptPassword(ctx context.Context, req *v1.UptPasswordReq) (res *v1.UptPasswordRes, err error)
UptEnabled(ctx context.Context, req *v1.UptEnabledReq) (res *v1.UptEnabledRes, err error)
Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error)
}

55
api/user/v1/user.go Normal file
View File

@ -0,0 +1,55 @@
package v1
import (
"devops-super/api"
"devops-super/internal/model/entity"
"devops-super/internal/model/mid"
"github.com/gogf/gf/v2/frame/g"
)
type GetPageLstReq struct {
g.Meta `method:"get" path:"/user/page-list" summary:"分页获取用户列表" tags:"用户"`
*api.PageLstReq
}
type GetPageLstRes struct {
*api.PageLstRes[*entity.User]
}
type AddReq struct {
g.Meta `method:"post" path:"/user" summary:"新增用户" tags:"用户"`
*mid.User
}
type AddRes struct{}
type UptReq struct {
g.Meta `method:"put" path:"/user/{id}" summary:"更新用户" tags:"用户"`
Id int ` v:"min:1#id必须" path:"id"`
*mid.User
}
type UptRes struct{}
type UptPasswordReq struct {
g.Meta `method:"patch" path:"/user/{id}/password" summary:"更新用户密码" tags:"用户"`
Id int ` v:"min:1#id必须" path:"id"`
Password string `v:"required|length:6,30#请输入密码|密码长度为:{min}到:{max}位"`
}
type UptPasswordRes struct{}
type UptEnabledReq struct {
g.Meta `method:"patch" path:"/user/{id}/enabled" summary:"更新用户密码" tags:"用户"`
Id int `v:"min:1#id必须" path:"id"`
Enabled bool `v:"required" json:"enabled"`
}
type UptEnabledRes struct{}
type DelReq struct {
g.Meta `method:"delete" path:"/user/{id}" summary:"删除用户" tags:"用户"`
Id int ` v:"min:1#id必须" path:"id"`
}
type DelRes struct{}

45
go.mod Normal file
View File

@ -0,0 +1,45 @@
module devops-super
go 1.18
require (
github.com/casbin/casbin/v2 v2.77.2
github.com/gogf/gf-jwt/v2 v2.1.0
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.4
github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.4
github.com/gogf/gf/v2 v2.5.4
golang.org/x/crypto v0.11.0
)
require (
github.com/BurntSushi/toml v1.2.0 // indirect
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grokify/html-strip-tags-go v0.0.1 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/redis/go-redis/v9 v9.0.5 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/tidwall/gjson v1.14.4 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

202
go.sum Normal file
View File

@ -0,0 +1,202 @@
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
github.com/casbin/casbin/v2 v2.77.2 h1:yQinn/w9x8AswiwqwtrXz93VU48R1aYTXdHEx4RI3jM=
github.com/casbin/casbin/v2 v2.77.2/go.mod h1:mzGx0hYW9/ksOSpw3wNjk3NRAroq5VMFYUQ6G43iGPk=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gogf/gf-jwt/v2 v2.1.0 h1:79/KH6vo3IAtHTvRubE8/NXKDF6/UisItLVpdsTTIjE=
github.com/gogf/gf-jwt/v2 v2.1.0/go.mod h1:AGEJOkG64G8ZYOi50ObYgJ+D7L3W4GcTW65m6VVGbmI=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.4 h1:xAmYQZEDBDoce/q5s7UTibYHHW0DSTApfmXVC/i0/zI=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.5.4/go.mod h1:lEgzJw5PLBOEJ4gZHgs1GwsbjyBLBttN2sN63rYRNhk=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.4 h1:t4Ls/E022VMk5hc3a4IgWO3xGNEQRXicCTOrFymZdDg=
github.com/gogf/gf/contrib/nosql/redis/v2 v2.5.4/go.mod h1:1P7id3OWFb3lkp1zBKdGqRoVXgYAjATzky++tGh2vxc=
github.com/gogf/gf/v2 v2.0.0-rc3/go.mod h1:apktt6TleWtCIwpz63vBqUnw8MX8gWKoZyxgDpXFtgM=
github.com/gogf/gf/v2 v2.5.4 h1:UBCSw8mInkHmEqL0E1LYc6QhSpaNFY/wHcFrTI/rzTk=
github.com/gogf/gf/v2 v2.5.4/go.mod h1:7yf5qp0BznfsYx7Sw49m3mQvBsHpwAjJk3Q9ZnKoUEc=
github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog=
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0=
github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o=
github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

19
hack/config.yaml Normal file
View File

@ -0,0 +1,19 @@
# CLI tool, only in development environment.
# https://goframe.org/pages/viewpage.action?pageId=3673173
gfcli:
docker:
build: "-a amd64 -s linux -p temp -ew"
tagPrefixes:
- zze326/
gen:
dao:
- link: "mysql:zze:devops.zze@tcp(192.168.2.231:3306)/zze_admin_go?loc=Local&parseTime=true"
group: default
tables: "user, permission, role, dept"
withTime: false
gJsonSupport: true
overwriteDao: true
descriptionTag: true
# jsonCase: Snake
clear: true

19
hack/hack-cli.mk Normal file
View File

@ -0,0 +1,19 @@
# Install/Update to the latest CLI tool.
.PHONY: cli
cli:
@set -e; \
wget -O gf https://github.com/gogf/gf/releases/latest/download/gf_$(shell go env GOOS)_$(shell go env GOARCH) && \
chmod +x gf && \
./gf install -y && \
rm ./gf
# Check and install CLI tool.
.PHONY: cli.install
cli.install:
@set -e; \
gf -v > /dev/null 2>&1 || if [[ "$?" -ne "0" ]]; then \
echo "GoFame CLI is not installed, start proceeding auto installation..."; \
make cli; \
fi;

77
hack/hack.mk Normal file
View File

@ -0,0 +1,77 @@
include ./hack/hack-cli.mk
DATE := $(shell date '+%Y%m%d%H%M')
# Update GoFrame and its CLI to latest stable version.
.PHONY: up
up: cli.install
@gf up -a
# Build binary using configuration from hack/config.yaml.
.PHONY: build
build: cli.install
@gf build -ew
# Parse api and generate controller/sdk.
.PHONY: ctrl
ctrl: cli.install
@gf gen ctrl
# Generate Go files for DAO/DO/Entity.
.PHONY: dao
dao: cli.install
@gf gen dao
# Parse current project go files and generate enums go file.
.PHONY: enums
enums: cli.install
@gf gen enums
# Generate Go files for Service.
.PHONY: service
service: cli.install
@gf gen service
# Build docker image.
.PHONY: image
image: cli.install
# $(eval _TAG = $(shell git describe --dirty --always --tags --abbrev=8 --match 'v*' | sed 's/-/./2' | sed 's/-/./2'))
$(eval _TAG = $(DATE))
#ifneq (, $(shell git status --porcelain 2>/dev/null))
# $(eval _TAG = $(_TAG).dirty)
#endif
$(eval _TAG = $(if ${TAG}, ${TAG}, $(_TAG)))
$(eval _PUSH = $(if ${PUSH}, ${PUSH}, ))
@gf docker ${_PUSH} -tn $(DOCKER_NAME):${_TAG};
# Build docker image and automatically push to docker repo.
.PHONY: image.push
image.push:
@make image PUSH=-p;
# Deploy image and yaml to current kubectl environment.
.PHONY: deploy
deploy:
$(eval _TAG = $(if ${TAG}, ${TAG}, develop))
@set -e; \
mkdir -p $(ROOT_DIR)/temp/kustomize;\
cd $(ROOT_DIR)/manifest/deploy/kustomize/overlays/${_ENV};\
kustomize build > $(ROOT_DIR)/temp/kustomize.yaml;\
kubectl apply -f $(ROOT_DIR)/temp/kustomize.yaml; \
if [ $(DEPLOY_NAME) != "" ]; then \
kubectl patch -n $(NAMESPACE) deployment/$(DEPLOY_NAME) -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"$(shell date +%s)\"}}}}}"; \
fi;
# Parsing protobuf files and generating go files.
.PHONY: pb
pb: cli.install
@gf gen pb
# Generate protobuf files for database tables.
.PHONY: pbentity
pbentity: cli.install
@gf gen pbentity

51
internal/cmd/cmd.go Normal file
View File

@ -0,0 +1,51 @@
package cmd
import (
"context"
"devops-super/internal/controller/dept"
"devops-super/internal/controller/permission"
"devops-super/internal/controller/public"
"devops-super/internal/controller/role"
"devops-super/internal/controller/user"
"devops-super/internal/service"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd"
)
var (
Main = gcmd.Command{
Name: "main",
Usage: "main",
Brief: "start http server",
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareCORS)
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
public.NewV1(),
)
// 权限控制路由
group.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(service.Middleware().Auth)
group.Bind(
user.NewV1(),
permission.NewV1(),
role.NewV1(),
dept.NewV1(),
)
})
})
// 初始化
if err = service.Context().Init(ctx); err != nil {
g.Log().Fatal(ctx, err)
}
s.Run()
return nil
},
}
)

11
internal/consts/consts.go Normal file
View File

@ -0,0 +1,11 @@
package consts
// 权限类型
const (
PERMISSION_TYPE_DIR = 1 // 目录
PERMISSION_TYPE_MENU = 2 // 菜单
PERMISSION_TYPE_ABLE = 3 // 功能
)
// 系统必须权限名称
const PERMISSION_SYSTEM_REQUIRED_NAME = "system-required"

View File

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dept

View File

@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package dept
import (
"devops-super/api/dept"
)
type ControllerV1 struct{}
func NewV1() dept.IDeptV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,20 @@
package dept
import (
"context"
"devops-super/internal/model/entity"
"devops-super/internal/service"
"github.com/gogf/gf/v2/util/gconv"
"devops-super/api/dept/v1"
)
func (c *ControllerV1) Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error) {
in := new(entity.Dept)
if err = gconv.Struct(req, in); err != nil {
return
}
err = service.Dept().Add(ctx, in)
return
}

View File

@ -0,0 +1,14 @@
package dept
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"devops-super/api/dept/v1"
)
func (c *ControllerV1) Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error) {
err = service.Role().Del(ctx, &do.Role{Id: req.Id})
return
}

View File

@ -0,0 +1,14 @@
package dept
import (
"context"
"devops-super/internal/service"
"devops-super/api/dept/v1"
)
func (c *ControllerV1) GetLst(ctx context.Context, req *v1.GetLstReq) (res *v1.GetLstRes, err error) {
res = new(v1.GetLstRes)
res.List, err = service.Dept().GetLst(ctx, req.Search)
return
}

View File

@ -0,0 +1,19 @@
package dept
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"github.com/gogf/gf/v2/util/gconv"
"devops-super/api/dept/v1"
)
func (c *ControllerV1) Upt(ctx context.Context, req *v1.UptReq) (res *v1.UptRes, err error) {
in := new(do.Dept)
if err = gconv.Struct(req, in); err != nil {
return
}
err = service.Dept().Upt(ctx, in)
return
}

View File

@ -0,0 +1,6 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package permission

View File

@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package permission
import (
"devops-super/api/permission"
)
type ControllerV1 struct{}
func NewV1() permission.IPermissionV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,19 @@
package permission
import (
"context"
"devops-super/internal/model/entity"
"devops-super/internal/service"
"github.com/gogf/gf/v2/util/gconv"
"devops-super/api/permission/v1"
)
func (c *ControllerV1) Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error) {
ePermission := new(entity.Permission)
if err = gconv.Struct(req, ePermission); err != nil {
return
}
err = service.Permission().Add(ctx, ePermission)
return
}

View File

@ -0,0 +1,14 @@
package permission
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"devops-super/api/permission/v1"
)
func (c *ControllerV1) Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error) {
err = service.Permission().Del(ctx, &do.Permission{Id: req.Id})
return
}

View File

@ -0,0 +1,14 @@
package permission
import (
"context"
"devops-super/internal/service"
"devops-super/api/permission/v1"
)
func (c *ControllerV1) GetLst(ctx context.Context, req *v1.GetLstReq) (res *v1.GetLstRes, err error) {
res = new(v1.GetLstRes)
res.List, err = service.Permission().GetLst(ctx, req.Search)
return
}

View File

@ -0,0 +1,14 @@
package permission
import (
"context"
"devops-super/internal/service"
"devops-super/api/permission/v1"
)
func (c *ControllerV1) GetRouteLst(ctx context.Context, req *v1.GetRouteLstReq) (res *v1.GetRouteLstRes, err error) {
res = new(v1.GetRouteLstRes)
res.List, err = service.Permission().GetRouteLst(ctx)
return
}

View File

@ -0,0 +1,19 @@
package permission
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"github.com/gogf/gf/v2/util/gconv"
"devops-super/api/permission/v1"
)
func (c *ControllerV1) Upt(ctx context.Context, req *v1.UptReq) (res *v1.UptRes, err error) {
uptDo := new(do.Permission)
if err = gconv.Struct(req, uptDo); err != nil {
return
}
err = service.Permission().Upt(ctx, uptDo)
return
}

View File

@ -0,0 +1,14 @@
package permission
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"devops-super/api/permission/v1"
)
func (c *ControllerV1) UptShowLink(ctx context.Context, req *v1.UptShowLinkReq) (res *v1.UptShowLinkRes, err error) {
err = service.Permission().Upt(ctx, &do.Permission{Id: req.Id, ShowLink: req.Enabled})
return
}

View File

@ -0,0 +1,6 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package public

View File

@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package public
import (
"devops-super/api/public"
)
type ControllerV1 struct{}
func NewV1() public.IPublicV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,28 @@
package public
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"time"
"devops-super/api/public/v1"
)
func (c *ControllerV1) Login(ctx context.Context, req *v1.LoginReq) (res *v1.LoginRes, err error) {
token, expires := service.Auth().LoginHandler(ctx)
refreshAfter := time.Now().Add(expires.Sub(time.Now()) / 2).UnixMilli()
eUser, err := service.User().GetComb(ctx, &do.User{Username: req.Username})
if err != nil {
return nil, err
}
res = &v1.LoginRes{
Username: eUser.Username,
RealName: eUser.RealName,
Token: token,
Expires: expires.UnixMilli(),
RefreshAfter: refreshAfter,
Roles: eUser.RoleCodes(),
}
return
}

View File

@ -0,0 +1,13 @@
package public
import (
"context"
"devops-super/internal/service"
"devops-super/api/public/v1"
)
func (c *ControllerV1) Logout(ctx context.Context, _ *v1.LogoutReq) (res *v1.LogoutRes, err error) {
service.Auth().LogoutHandler(ctx)
return
}

View File

@ -0,0 +1,11 @@
package public
import (
"context"
"devops-super/api/public/v1"
)
func (c *ControllerV1) Ping(ctx context.Context, req *v1.PingReq) (res *v1.PingRes, err error) {
return
}

View File

@ -0,0 +1,28 @@
package public
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"time"
"devops-super/api/public/v1"
)
func (c *ControllerV1) RefreshToken(ctx context.Context, req *v1.RefreshTokenReq) (res *v1.RefreshTokenRes, err error) {
token, expire := service.Auth().RefreshHandler(ctx)
refreshAfter := time.Now().Add(expire.Sub(time.Now()) / 2).UnixMilli()
eUser, err := service.User().GetComb(ctx, &do.User{Id: service.Auth().GetIdentity(ctx)})
if err != nil {
return nil, err
}
res = &v1.RefreshTokenRes{
Username: eUser.Username,
RealName: eUser.RealName,
Token: token,
Expire: expire.UnixMilli(),
RefreshAfter: refreshAfter,
Roles: eUser.RoleCodes(),
}
return
}

View File

@ -0,0 +1,6 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package role

View File

@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package role
import (
"devops-super/api/role"
)
type ControllerV1 struct{}
func NewV1() role.IRoleV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,20 @@
package role
import (
"context"
"devops-super/internal/model/entity"
"devops-super/internal/service"
"github.com/gogf/gf/v2/util/gconv"
"devops-super/api/role/v1"
)
func (c *ControllerV1) Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error) {
in := new(entity.Role)
if err = gconv.Struct(req, in); err != nil {
return
}
err = service.Role().Add(ctx, in)
return
}

View File

@ -0,0 +1,14 @@
package role
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"devops-super/api/role/v1"
)
func (c *ControllerV1) Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error) {
err = service.Role().Del(ctx, &do.Role{Id: req.Id})
return
}

View File

@ -0,0 +1,14 @@
package role
import (
"context"
"devops-super/internal/service"
"devops-super/api/role/v1"
)
func (c *ControllerV1) GetLst(ctx context.Context, req *v1.GetLstReq) (res *v1.GetLstRes, err error) {
res = new(v1.GetLstRes)
res.List, err = service.Role().GetLst(ctx)
return
}

View File

@ -0,0 +1,14 @@
package role
import (
"context"
"devops-super/internal/service"
"devops-super/api/role/v1"
)
func (c *ControllerV1) GetPageLst(ctx context.Context, req *v1.GetPageLstReq) (res *v1.GetPageLstRes, err error) {
res = new(v1.GetPageLstRes)
res.PageLstRes, err = service.Role().GetPageLst(ctx, req.PageLstReq)
return
}

View File

@ -0,0 +1,19 @@
package role
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"github.com/gogf/gf/v2/util/gconv"
"devops-super/api/role/v1"
)
func (c *ControllerV1) Upt(ctx context.Context, req *v1.UptReq) (res *v1.UptRes, err error) {
in := new(do.Role)
if err = gconv.Struct(req, in); err != nil {
return
}
err = service.Role().Upt(ctx, in)
return
}

View File

@ -0,0 +1,14 @@
package role
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"devops-super/api/role/v1"
)
func (c *ControllerV1) UptPermission(ctx context.Context, req *v1.UptPermissionReq) (res *v1.UptPermissionRes, err error) {
err = service.Role().Upt(ctx, &do.Role{Id: req.Id, Permission: req.PermissionIds})
return
}

View File

@ -0,0 +1,6 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package user

View File

@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package user
import (
"devops-super/api/user"
)
type ControllerV1 struct{}
func NewV1() user.IUserV1 {
return &ControllerV1{}
}

View File

@ -0,0 +1,21 @@
package user
import (
"context"
"devops-super/internal/model/entity"
"devops-super/internal/service"
"github.com/gogf/gf/v2/util/gconv"
"devops-super/api/user/v1"
)
func (c *ControllerV1) Add(ctx context.Context, req *v1.AddReq) (res *v1.AddRes, err error) {
eUser := new(entity.User)
if err = gconv.Struct(req, eUser); err != nil {
return
}
eUser.Password = "devops.zze"
err = service.User().Add(ctx, eUser)
return
}

View File

@ -0,0 +1,13 @@
package user
import (
"context"
"devops-super/api/user/v1"
"devops-super/internal/model/do"
"devops-super/internal/service"
)
func (c *ControllerV1) Del(ctx context.Context, req *v1.DelReq) (res *v1.DelRes, err error) {
err = service.User().Del(ctx, &do.User{Id: req.Id})
return
}

View File

@ -0,0 +1,14 @@
package user
import (
"context"
"devops-super/internal/service"
"devops-super/api/user/v1"
)
func (c *ControllerV1) GetPageLst(ctx context.Context, req *v1.GetPageLstReq) (res *v1.GetPageLstRes, err error) {
res = new(v1.GetPageLstRes)
res.PageLstRes, err = service.User().GetPageLst(ctx, req.PageLstReq)
return
}

View File

@ -0,0 +1,19 @@
package user
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"github.com/gogf/gf/v2/util/gconv"
"devops-super/api/user/v1"
)
func (c *ControllerV1) Upt(ctx context.Context, req *v1.UptReq) (res *v1.UptRes, err error) {
uptDo := new(do.User)
if err = gconv.Struct(req, uptDo); err != nil {
return
}
err = service.User().Upt(ctx, uptDo)
return
}

View File

@ -0,0 +1,14 @@
package user
import (
"context"
"devops-super/internal/model/do"
"devops-super/internal/service"
"devops-super/api/user/v1"
)
func (c *ControllerV1) UptEnabled(ctx context.Context, req *v1.UptEnabledReq) (res *v1.UptEnabledRes, err error) {
err = service.User().Upt(ctx, &do.User{Id: req.Id, Enabled: req.Enabled})
return
}

View File

@ -0,0 +1,13 @@
package user
import (
"context"
"devops-super/api/user/v1"
"devops-super/internal/model/do"
"devops-super/internal/service"
)
func (c *ControllerV1) UptPassword(ctx context.Context, req *v1.UptPasswordReq) (res *v1.UptPasswordRes, err error) {
err = service.User().Upt(ctx, &do.User{Id: req.Id, Password: req.Password})
return
}

0
internal/dao/.gitkeep Normal file
View File

27
internal/dao/dept.go Normal file
View File

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"devops-super/internal/dao/internal"
)
// internalDeptDao is internal type for wrapping internal DAO implements.
type internalDeptDao = *internal.DeptDao
// deptDao is the data access object for table dept.
// You can define custom methods on it to extend its functionality as you wish.
type deptDao struct {
internalDeptDao
}
var (
// Dept is globally public accessible object for table dept operations.
Dept = deptDao{
internal.NewDeptDao(),
}
)
// Fill with you ideas below.

View File

@ -0,0 +1,81 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// DeptDao is the data access object for table dept.
type DeptDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns DeptColumns // columns contains all the column names of Table for convenient usage.
}
// DeptColumns defines and stores column names for table dept.
type DeptColumns struct {
Id string //
Name string // 部门名称
Rank string // 排序
ParentId string // 上级部门 id
UpdatedAt string // 更新时间
}
// deptColumns holds the columns for table dept.
var deptColumns = DeptColumns{
Id: "id",
Name: "name",
Rank: "rank",
ParentId: "parent_id",
UpdatedAt: "updated_at",
}
// NewDeptDao creates and returns a new DAO object for table data access.
func NewDeptDao() *DeptDao {
return &DeptDao{
group: "default",
table: "dept",
columns: deptColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *DeptDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *DeptDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *DeptDao) Columns() DeptColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *DeptDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *DeptDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *DeptDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,97 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// PermissionDao is the data access object for table permission.
type PermissionDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns PermissionColumns // columns contains all the column names of Table for convenient usage.
}
// PermissionColumns defines and stores column names for table permission.
type PermissionColumns struct {
Id string //
Title string // 标题
Name string // 路由名称
Type string // 类型:1-目录,2-菜单,3-功能
FRoute string // 前端路由路径
BRoutes string // 后端路由路径
Redirect string // 重定向路径
Icon string // 图标
Rank string // 排序
ShowLink string // 是否在菜单中展示
ShowParent string // 是否展示父级菜单
KeepAlive string // 页面缓存
ParentId string // 父级权限 id
}
// permissionColumns holds the columns for table permission.
var permissionColumns = PermissionColumns{
Id: "id",
Title: "title",
Name: "name",
Type: "type",
FRoute: "f_route",
BRoutes: "b_routes",
Redirect: "redirect",
Icon: "icon",
Rank: "rank",
ShowLink: "show_link",
ShowParent: "show_parent",
KeepAlive: "keep_alive",
ParentId: "parent_id",
}
// NewPermissionDao creates and returns a new DAO object for table data access.
func NewPermissionDao() *PermissionDao {
return &PermissionDao{
group: "default",
table: "permission",
columns: permissionColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *PermissionDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *PermissionDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *PermissionDao) Columns() PermissionColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *PermissionDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *PermissionDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *PermissionDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,81 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// RoleDao is the data access object for table role.
type RoleDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns RoleColumns // columns contains all the column names of Table for convenient usage.
}
// RoleColumns defines and stores column names for table role.
type RoleColumns struct {
Id string //
Name string // 角色名称
Code string // 角色代码
Permission string // 关联权限
UpdatedAt string // 更新时间
}
// roleColumns holds the columns for table role.
var roleColumns = RoleColumns{
Id: "id",
Name: "name",
Code: "code",
Permission: "permission",
UpdatedAt: "updated_at",
}
// NewRoleDao creates and returns a new DAO object for table data access.
func NewRoleDao() *RoleDao {
return &RoleDao{
group: "default",
table: "role",
columns: roleColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *RoleDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *RoleDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *RoleDao) Columns() RoleColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *RoleDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *RoleDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *RoleDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,91 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// UserDao is the data access object for table user.
type UserDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns UserColumns // columns contains all the column names of Table for convenient usage.
}
// UserColumns defines and stores column names for table user.
type UserColumns struct {
Id string //
Username string // 用户名
Password string // 密码
Phone string // 手机号码
Email string // 邮箱
RealName string // 真实姓名
Enabled string // 是否启用状态
RoleIds string // 角色 id
DeptId string // 所属部门 id
UpdatedAt string // 更新时间
}
// userColumns holds the columns for table user.
var userColumns = UserColumns{
Id: "id",
Username: "username",
Password: "password",
Phone: "phone",
Email: "email",
RealName: "real_name",
Enabled: "enabled",
RoleIds: "role_ids",
DeptId: "dept_id",
UpdatedAt: "updated_at",
}
// NewUserDao creates and returns a new DAO object for table data access.
func NewUserDao() *UserDao {
return &UserDao{
group: "default",
table: "user",
columns: userColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *UserDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *UserDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *UserDao) Columns() UserColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *UserDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *UserDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *UserDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

View File

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"devops-super/internal/dao/internal"
)
// internalPermissionDao is internal type for wrapping internal DAO implements.
type internalPermissionDao = *internal.PermissionDao
// permissionDao is the data access object for table permission.
// You can define custom methods on it to extend its functionality as you wish.
type permissionDao struct {
internalPermissionDao
}
var (
// Permission is globally public accessible object for table permission operations.
Permission = permissionDao{
internal.NewPermissionDao(),
}
)
// Fill with you ideas below.

27
internal/dao/role.go Normal file
View File

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"devops-super/internal/dao/internal"
)
// internalRoleDao is internal type for wrapping internal DAO implements.
type internalRoleDao = *internal.RoleDao
// roleDao is the data access object for table role.
// You can define custom methods on it to extend its functionality as you wish.
type roleDao struct {
internalRoleDao
}
var (
// Role is globally public accessible object for table role operations.
Role = roleDao{
internal.NewRoleDao(),
}
)
// Fill with you ideas below.

27
internal/dao/user.go Normal file
View File

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"devops-super/internal/dao/internal"
)
// internalUserDao is internal type for wrapping internal DAO implements.
type internalUserDao = *internal.UserDao
// userDao is the data access object for table user.
// You can define custom methods on it to extend its functionality as you wish.
type userDao struct {
internalUserDao
}
var (
// User is globally public accessible object for table user operations.
User = userDao{
internal.NewUserDao(),
}
)
// Fill with you ideas below.

0
internal/logic/.gitkeep Normal file
View File

View File

@ -0,0 +1,87 @@
package context
import (
"context"
"devops-super/internal/consts"
"devops-super/internal/model/entity/comb"
"devops-super/internal/service"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
"github.com/gogf/gf/v2/frame/g"
"strings"
)
func (*sContext) initCasbin(ctx context.Context) (*casbin.Enforcer, error) {
g.Log().Debug(ctx, "init casbin enforcer start.")
enforcer, err := casbin.NewEnforcer(newCasbinModel())
if err != nil {
return nil, err
}
roleList, err := service.Role().GetCombList(ctx)
if err != nil {
return nil, err
}
type recursiveHandlePermissionsFunc func(roleCode string, permissions []*comb.Permission) error
var recursiveHandlePermissions recursiveHandlePermissionsFunc
recursiveHandlePermissions = func(roleCode string, permissions []*comb.Permission) error {
for _, permission := range permissions {
if permission.Type == consts.PERMISSION_TYPE_ABLE {
for _, backendRouteInfo := range permission.BRoutes.Array() {
routeInfoArr := strings.SplitN(backendRouteInfo.(string), ":", 2)
method := strings.ToUpper(routeInfoArr[0])
routePath := routeInfoArr[1]
if enforcer.HasPolicy(roleCode, routePath, method) {
continue
}
if _, err := enforcer.AddPolicy(roleCode, routePath, method); err != nil {
return err
}
g.Log().Debugf(ctx, "casbin policy added: %s, %s, %s", roleCode, routePath, method)
}
} else {
if len(permission.Children) > 0 {
if err = recursiveHandlePermissions(roleCode, permission.Children); err != nil {
return err
}
}
}
}
return nil
}
for _, role := range roleList {
if err := recursiveHandlePermissions(role.Code, role.Permissions); err != nil {
return nil, err
}
}
userList, err := service.User().GetCombLst(ctx)
if err != nil {
return nil, err
}
for _, user := range userList {
var roleCodes []string
for _, role := range user.Roles {
roleCodes = append(roleCodes, role.Code)
}
if _, err := enforcer.AddRolesForUser(user.Username, roleCodes); err != nil {
return nil, err
}
g.Log().Debugf(ctx, "casbin roles added: %s, %v", user.Username, roleCodes)
}
g.Log().Debug(ctx, "init casbin enforcer successful.")
return enforcer, nil
}
func newCasbinModel() model.Model {
m := model.NewModel()
m.AddDef("r", "r", "sub, obj, act")
m.AddDef("p", "p", "sub, obj, act")
m.AddDef("g", "g", "_, _")
m.AddDef("e", "e", "some(where (p.eft == allow))")
m.AddDef("m", "m", `g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act) || g(r.sub, "admin")`)
return m
}

View File

@ -0,0 +1,48 @@
package context
import (
"context"
"devops-super/internal/model"
"devops-super/internal/service"
)
type sContext struct {
svcCtx *model.ServiceContext
ctx context.Context
}
func init() {
service.RegisterContext(New())
}
func New() *sContext {
return &sContext{}
}
func (s *sContext) Init(ctx context.Context) error {
s.ctx = ctx
return s.initServiceContext()
}
func (s *sContext) initServiceContext() (err error) {
s.svcCtx = new(model.ServiceContext)
// 初始化 casbin
err = s.RefreshCasbin(s.ctx)
if err != nil {
return
}
return
}
func (s *sContext) RefreshCasbin(ctx context.Context) error {
enforcer, err := s.initCasbin(ctx)
if err != nil {
return err
}
s.svcCtx.CasbinEnforcer = enforcer
return nil
}
func (s *sContext) Ctx() *model.ServiceContext {
return s.svcCtx
}

View File

@ -0,0 +1,72 @@
package permission
import (
"context"
"devops-super/internal/dao"
"devops-super/internal/model/do"
"devops-super/internal/model/entity"
"devops-super/internal/service"
"devops-super/utility/util"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/util/gutil"
)
type sDept struct{}
var (
cols = dao.Dept.Columns()
)
func init() {
service.RegisterDept(New())
}
func New() *sDept {
return &sDept{}
}
func (s *sDept) Add(ctx context.Context, in *entity.Dept) (err error) {
r, err := s.Get(ctx, &do.Dept{Name: in.Name})
if err != nil {
return err
}
if r != nil {
return gerror.Newf("已存在名称为 %s 部门", in.Name)
}
_, err = dao.Dept.Ctx(ctx).Insert(in)
return
}
func (*sDept) Get(ctx context.Context, in *do.Dept) (out *entity.Dept, err error) {
err = dao.Dept.Ctx(ctx).Where(in).OmitNilWhere().Limit(1).Scan(&out)
return
}
func (*sDept) GetLst(ctx context.Context, search string) (out []*entity.Dept, err error) {
m := dao.Dept.Ctx(ctx).Order(dao.Dept.Columns().Rank).Safe(true)
if !gutil.IsEmpty(search) {
m = m.WhereOr(m.Builder().WhereOrLike(cols.Name, util.SqlLikeStr(search)))
}
err = m.Scan(&out)
return
}
func (*sDept) Upt(ctx context.Context, in *do.Dept) (err error) {
if !gutil.IsEmpty(in.Name) {
r, err := dao.Dept.Ctx(ctx).WhereNot(cols.Id, in.Id).Where(cols.Name, in.Name).One()
if err != nil {
return err
}
if r != nil {
return gerror.Newf("已存在名称为 %s 部门", in.Name)
}
}
_, err = dao.Dept.Ctx(ctx).WherePri(in.Id).OmitNilData().Data(in).Update()
return
}
func (*sDept) Del(ctx context.Context, in *do.Dept) (err error) {
_, err = dao.Dept.Ctx(ctx).Where(in).OmitNilWhere().Delete()
return
}

14
internal/logic/logic.go Normal file
View File

@ -0,0 +1,14 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "devops-super/internal/logic/context"
_ "devops-super/internal/logic/dept"
_ "devops-super/internal/logic/middleware"
_ "devops-super/internal/logic/permission"
_ "devops-super/internal/logic/role"
_ "devops-super/internal/logic/user"
)

View File

@ -0,0 +1,64 @@
package middleware
import (
"devops-super/internal/service"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/text/gstr"
"net/http"
)
type sMiddleware struct{}
func init() {
service.RegisterMiddleware(New())
}
func New() *sMiddleware {
return &sMiddleware{}
}
func (*sMiddleware) Auth(r *ghttp.Request) {
service.Auth().MiddlewareFunc()(r)
var (
requestPath = r.Request.URL.Path
method = r.Request.Method
refreshPermissionPathPrefixes = []string{"/permission", "/role", "/user"}
)
pass, err := service.Context().Ctx().CasbinEnforcer.Enforce(service.CurrentUser(r.GetCtx()).Username, requestPath, method)
if err != nil {
r.Response.WriteJson(g.Map{
"code": http.StatusForbidden,
"message": err,
})
r.ExitAll()
}
if !pass {
r.Response.WriteJson(g.Map{
"code": http.StatusForbidden,
"message": "没有接口权限",
})
r.ExitAll()
}
r.Middleware.Next()
if method != "GET" {
for _, prefix := range refreshPermissionPathPrefixes {
if gstr.HasPrefix(requestPath, prefix) {
if err := service.Context().RefreshCasbin(r.GetCtx()); err != nil {
r.Response.WriteJson(g.Map{
"code": http.StatusInternalServerError,
"message": gerror.Newf("刷新权限失败: %v", err),
})
r.ExitAll()
}
break
}
}
}
}

View File

@ -0,0 +1,103 @@
package permission
import (
"context"
"devops-super/internal/consts"
"devops-super/internal/dao"
"devops-super/internal/model/do"
"devops-super/internal/model/entity"
"devops-super/internal/service"
"devops-super/utility/util"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/util/gutil"
)
type sPermission struct{}
var (
cols = dao.Permission.Columns()
)
func init() {
service.RegisterPermission(New())
}
func New() *sPermission {
return &sPermission{}
}
func (s *sPermission) Add(ctx context.Context, in *entity.Permission) (err error) {
r, err := s.Get(ctx, &do.Permission{Name: in.Name})
if err != nil {
return err
}
if r != nil {
return gerror.Newf("已存在名称为 %s 权限", in.Name)
}
if (in.Type == consts.PERMISSION_TYPE_DIR || in.Type == consts.PERMISSION_TYPE_MENU) && !gutil.IsEmpty(in.FRoute) {
r, err = s.Get(ctx, &do.Permission{FRoute: in.FRoute})
if err != nil {
return err
}
if r != nil {
return gerror.Newf("已存在前端路由为 %s 权限", in.FRoute)
}
}
_, err = dao.Permission.Ctx(ctx).Insert(in)
return
}
func (*sPermission) Get(ctx context.Context, in *do.Permission) (out *entity.Permission, err error) {
err = dao.Permission.Ctx(ctx).Where(in).OmitNilWhere().Limit(1).Scan(&out)
return
}
func (*sPermission) GetLst(ctx context.Context, search string) (out []*entity.Permission, err error) {
m := dao.Permission.Ctx(ctx).Order(dao.Permission.Columns().Rank).Safe(true)
if !gutil.IsEmpty(search) {
m = m.WhereOr(m.Builder().WhereOrLike(cols.Name, util.SqlLikeStr(search)).WhereOrLike(cols.Title, util.SqlLikeStr(search)))
}
err = m.Scan(&out)
return
}
func (*sPermission) Upt(ctx context.Context, in *do.Permission) (err error) {
if !gutil.IsEmpty(in.Name) {
r, err := dao.Permission.Ctx(ctx).WhereNot(cols.Id, in.Id).Where(cols.Name, in.Name).One()
if err != nil {
return err
}
if r != nil {
return gerror.Newf("已存在名称为 %s 权限", in.Name)
}
}
if (in.Type == consts.PERMISSION_TYPE_DIR || in.Type == consts.PERMISSION_TYPE_MENU) && !gutil.IsEmpty(in.FRoute) {
r, err := dao.Permission.Ctx(ctx).WhereNot(cols.Id, in.Id).Where(cols.FRoute, in.FRoute).One()
if err != nil {
return err
}
if r != nil {
return gerror.Newf("已存在前端路由为 %s 权限", in.FRoute)
}
}
_, err = dao.Permission.Ctx(ctx).WherePri(in.Id).OmitNilData().Data(in).Update()
return
}
func (*sPermission) Del(ctx context.Context, in *do.Permission) (err error) {
_, err = dao.Permission.Ctx(ctx).Where(in).OmitNilWhere().Delete()
return
}
func (s *sPermission) SystemRequired(ctx context.Context) (ePermission *entity.Permission, err error) {
requiredPermission, err := s.Get(ctx, &do.Permission{Name: consts.PERMISSION_SYSTEM_REQUIRED_NAME})
if err != nil {
return nil, err
}
if requiredPermission != nil && requiredPermission.Id > 0 {
return requiredPermission, nil
}
return nil, gerror.New("系统必需权限缺失")
}

View File

@ -0,0 +1,137 @@
package permission
import (
"context"
"devops-super/internal/consts"
"devops-super/internal/dao"
"devops-super/internal/model/do"
"devops-super/internal/model/entity"
"devops-super/internal/model/entity/comb"
"devops-super/internal/model/mid"
"devops-super/internal/service"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/util/gconv"
"sort"
)
func (*sPermission) GetRouteLst(ctx context.Context) (out []*mid.Route, err error) {
cUser, err := service.User().GetComb(ctx, &do.User{Id: service.CurrentUser(ctx).UserId})
if err != nil {
return nil, err
}
var permissionIdSet = gset.New()
for _, role := range cUser.Roles {
if role.Permission.IsNil() {
continue
}
for _, pId := range role.Permission.Array() {
permissionIdSet.Add(pId)
}
}
var cPermissions []*comb.Permission
if err = dao.Permission.Ctx(ctx).Order(cols.Rank).WithAll().WhereIn(cols.Id, permissionIdSet.Slice()).Scan(&cPermissions); err != nil {
return
}
var ePermissionMap = make(map[int]*entity.Permission, len(cPermissions))
for _, permission := range cPermissions {
ePermissionMap[permission.Id] = permission.Permission
}
type (
handleManyFunc = func(children []*comb.Permission) error
handleOneFunc = func(cPermission *comb.Permission) error
handleParentFunc = func(parentId int) (*mid.Route, error)
)
var (
finalRoutes mid.FrontendRouteList
routeMap = make(map[int]*mid.Route)
getOne = func(id int) *entity.Permission {
return ePermissionMap[id]
}
permissionToRoute = func(ePermission *entity.Permission) (route *mid.Route) {
_ = gconv.Struct(ePermission, &route)
return
}
handleMany handleManyFunc
handleOne handleOneFunc
handleParent handleParentFunc
)
handleParent = func(parentId int) (*mid.Route, error) {
var (
parent *mid.Route
ok bool
)
parent, ok = routeMap[parentId]
if !ok {
ePermission := new(entity.Permission)
if permissionIdSet.Contains(parentId) {
ePermission = getOne(parentId)
} else {
if err := dao.Permission.Ctx(ctx).WherePri(parentId).Scan(ePermission); err != nil {
return nil, err
}
parent = permissionToRoute(ePermission)
routeMap[parentId] = parent
finalRoutes = append(finalRoutes, parent)
}
if parent.ParentId > 0 {
if _, err := handleParent(parent.ParentId); err != nil {
return nil, err
}
}
}
return parent, nil
}
handleMany = func(children []*comb.Permission) error {
for _, child := range children {
if err := handleOne(child); err != nil {
return err
}
}
return nil
}
handleOne = func(cPermission *comb.Permission) error {
switch cPermission.Type {
case consts.PERMISSION_TYPE_DIR, consts.PERMISSION_TYPE_MENU:
route := permissionToRoute(cPermission.Permission)
if cPermission.Type == consts.PERMISSION_TYPE_DIR {
if err := handleMany(cPermission.Children); err != nil {
return err
}
} else {
route.Auths = cPermission.AuthCodes()
}
if _, ok := routeMap[route.Id]; !ok {
routeMap[route.Id] = route
finalRoutes = append(finalRoutes, route)
}
}
if parentId := cPermission.ParentId; parentId > 0 {
parent, err := handleParent(parentId)
if err != nil {
return err
}
if cPermission.Type == consts.PERMISSION_TYPE_ABLE {
parent.Auths = append(parent.Auths, cPermission.Name)
}
}
return nil
}
if err = handleMany(cPermissions); err != nil {
return
}
sort.Sort(finalRoutes)
return finalRoutes, nil
}

111
internal/logic/role/role.go Normal file
View File

@ -0,0 +1,111 @@
package user
import (
"context"
"devops-super/api"
"devops-super/internal/dao"
"devops-super/internal/model/do"
"devops-super/internal/model/entity"
"devops-super/internal/model/entity/comb"
"devops-super/internal/service"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/util/gutil"
)
type sRole struct{}
var cols = dao.Role.Columns()
func init() {
service.RegisterRole(New())
}
func New() *sRole {
return &sRole{}
}
func (*sRole) Add(ctx context.Context, in *entity.Role) (err error) {
r, err := dao.Role.Ctx(ctx).Where(cols.Code, in.Code).One()
if err != nil {
return err
}
if r != nil {
return gerror.New("已存在该代码的权限")
}
_, err = dao.Role.Ctx(ctx).Insert(in)
return
}
func (*sRole) Upt(ctx context.Context, in *do.Role) (err error) {
if !gutil.IsEmpty(in.Code) {
r, err := dao.Role.Ctx(ctx).WhereNot(cols.Id, in.Id).Where(cols.Code, in.Code).One()
if err != nil {
return err
}
if r != nil {
return gerror.New("已存在该代码的权限")
}
}
_, err = dao.Role.Ctx(ctx).WherePri(in.Id).OmitNilData().Data(in).Update()
return
}
func (*sRole) GetPageLst(ctx context.Context, in *api.PageLstReq) (out *api.PageLstRes[*entity.Role], err error) {
out = &api.PageLstRes[*entity.Role]{}
m := dao.Role.Ctx(ctx).Safe(true)
if !gutil.IsEmpty(in.Search) {
m = m.WhereOr(m.Builder().WhereOrLike(cols.Name, in.SearchStr()).WhereOrLike(cols.Code, in.SearchStr()))
}
err = m.Offset(in.Offset()).Limit(in.Limit()).
ScanAndCount(&out.List, &out.Total, false)
permission, err := service.Permission().SystemRequired(ctx)
if err != nil {
return nil, err
}
for _, u := range out.List {
u.Permission = gjson.New(append(u.Permission.Array(), permission.Id))
}
return
}
func (*sRole) GetLst(ctx context.Context) (out []*entity.Role, err error) {
err = dao.Role.Ctx(ctx).OrderDesc(cols.Id).FieldsEx(cols.Permission).Scan(&out)
return
}
func (*sRole) GetCombList(ctx context.Context) (out []*comb.Role, err error) {
if err = dao.Role.Ctx(ctx).Scan(&out); err != nil {
return
}
permission, err := service.Permission().SystemRequired(ctx)
if err != nil {
return nil, err
}
for _, role := range out {
role.Permission = gjson.New(append(role.Permission.Array(), permission.Id))
if err = dao.Permission.Ctx(ctx).WithAll().WhereIn(dao.Permission.Columns().Id, role.Permission.Array()).Scan(&role.Permissions); err != nil {
return
}
}
return
}
func (*sRole) Get(ctx context.Context, in *do.Role) (out *entity.Role, err error) {
err = dao.Role.Ctx(ctx).Where(in).OmitNilWhere().Limit(1).Scan(&out)
permission, err := service.Permission().SystemRequired(ctx)
if err != nil {
return nil, err
}
out.Permission = gjson.New(append(out.Permission.Array(), permission.Id))
return
}
func (*sRole) Del(ctx context.Context, in *do.Role) (err error) {
_, err = dao.Role.Ctx(ctx).Where(in).OmitNilWhere().Delete()
return
}

View File

@ -0,0 +1,98 @@
package user
import (
"context"
"devops-super/api"
"devops-super/internal/dao"
"devops-super/internal/model/do"
"devops-super/internal/model/entity"
"devops-super/internal/model/entity/comb"
"devops-super/internal/service"
"devops-super/utility/util"
"github.com/gogf/gf/v2/util/gutil"
)
type sUser struct{}
var cols = dao.User.Columns()
func init() {
service.RegisterUser(New())
}
func New() *sUser {
return &sUser{}
}
func (*sUser) Add(ctx context.Context, in *entity.User) (err error) {
in.Password, err = util.EncryptPassword(in.Password)
if err != nil {
return
}
_, err = dao.User.Ctx(ctx).Insert(in)
return
}
func (*sUser) Upt(ctx context.Context, in *do.User) (err error) {
if !gutil.IsEmpty(in.Password) {
in.Password, err = util.EncryptPassword(in.Password.(string))
if err != nil {
return
}
}
_, err = dao.User.Ctx(ctx).WherePri(in.Id).OmitNilData().Data(in).Update()
return
}
func (*sUser) GetPageLst(ctx context.Context, in *api.PageLstReq) (out *api.PageLstRes[*entity.User], err error) {
out = &api.PageLstRes[*entity.User]{}
m := dao.User.Ctx(ctx).Safe(true)
if !gutil.IsEmpty(in.Search) {
m = m.WhereOr(m.Builder().WhereOrLike(cols.Username, in.SearchStr()).WhereOrLike(cols.RealName, in.SearchStr()))
}
if enabled := in.Wheres.Get("enabled"); !enabled.IsNil() {
m = m.Where(cols.Enabled, enabled.Bool())
}
if deptId := in.Wheres.Get("deptId"); !deptId.IsNil() {
m = m.Where(cols.DeptId, deptId.Int())
}
err = m.Offset(in.Offset()).Limit(in.Limit()).FieldsEx(cols.Password).
ScanAndCount(&out.List, &out.Total, false)
return
}
func (*sUser) Get(ctx context.Context, userDo *do.User) (out *entity.User, err error) {
err = dao.User.Ctx(ctx).Where(userDo).OmitNilWhere().Limit(1).Scan(&out)
return
}
func (*sUser) GetComb(ctx context.Context, userDo *do.User) (out *comb.User, err error) {
if err = dao.User.Ctx(ctx).Where(userDo).OmitNilWhere().Limit(1).Scan(&out); err != nil {
return
}
if err = dao.Role.Ctx(ctx).WhereIn(dao.Role.Columns().Id, out.RoleIds.Array()).Scan(&out.Roles); err != nil {
return
}
return
}
func (*sUser) GetCombLst(ctx context.Context) (out []*comb.User, err error) {
if err = dao.User.Ctx(ctx).Where(cols.Enabled, true).Scan(&out); err != nil {
return
}
for _, user := range out {
if err = dao.Role.Ctx(ctx).WhereIn(dao.Role.Columns().Id, user.RoleIds.Array()).Scan(&user.Roles); err != nil {
return
}
}
return
}
func (*sUser) Del(ctx context.Context, in *do.User) (err error) {
_, err = dao.User.Ctx(ctx).Where(in).OmitNilWhere().Delete()
return
}

0
internal/model/.gitkeep Normal file
View File

13
internal/model/context.go Normal file
View File

@ -0,0 +1,13 @@
package model
import "github.com/casbin/casbin/v2"
type ServiceContext struct {
CasbinEnforcer *casbin.Enforcer
}
type RequestUser struct {
UserId int `json:"userId"`
RealName string `json:"realName"`
Username string `json:"username"`
}

View File

20
internal/model/do/dept.go Normal file
View File

@ -0,0 +1,20 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Dept is the golang structure of table dept for DAO operations like Where/Data.
type Dept struct {
g.Meta `orm:"table:dept, do:true"`
Id interface{} //
Name interface{} // 部门名称
Rank interface{} // 排序
ParentId interface{} // 上级部门 id
UpdatedAt *gtime.Time // 更新时间
}

View File

@ -0,0 +1,28 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
)
// Permission is the golang structure of table permission for DAO operations like Where/Data.
type Permission struct {
g.Meta `orm:"table:permission, do:true"`
Id interface{} //
Title interface{} // 标题
Name interface{} // 路由名称
Type interface{} // 类型:1-目录,2-菜单,3-功能
FRoute interface{} // 前端路由路径
BRoutes *gjson.Json // 后端路由路径
Redirect interface{} // 重定向路径
Icon interface{} // 图标
Rank interface{} // 排序
ShowLink interface{} // 是否在菜单中展示
ShowParent interface{} // 是否展示父级菜单
KeepAlive interface{} // 页面缓存
ParentId interface{} // 父级权限 id
}

21
internal/model/do/role.go Normal file
View File

@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// Role is the golang structure of table role for DAO operations like Where/Data.
type Role struct {
g.Meta `orm:"table:role, do:true"`
Id interface{} //
Name interface{} // 角色名称
Code interface{} // 角色代码
Permission *gjson.Json // 关联权限
UpdatedAt *gtime.Time // 更新时间
}

26
internal/model/do/user.go Normal file
View File

@ -0,0 +1,26 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// User is the golang structure of table user for DAO operations like Where/Data.
type User struct {
g.Meta `orm:"table:user, do:true"`
Id interface{} //
Username interface{} // 用户名
Password interface{} // 密码
Phone interface{} // 手机号码
Email interface{} // 邮箱
RealName interface{} // 真实姓名
Enabled interface{} // 是否启用状态
RoleIds *gjson.Json // 角色 id
DeptId interface{} // 所属部门 id
UpdatedAt *gtime.Time // 更新时间
}

View File

View File

@ -0,0 +1,21 @@
package comb
import (
"devops-super/internal/consts"
"devops-super/internal/model/entity"
)
type Permission struct {
*entity.Permission
//Parent *Permission `orm:"with:id=parent_id" json:"parent"`
Children []*Permission `orm:"with:parent_id=id" json:"children"`
}
func (s *Permission) AuthCodes() (codes []string) {
for _, child := range s.Children {
if child.Type == consts.PERMISSION_TYPE_ABLE {
codes = append(codes, child.Name)
}
}
return
}

View File

@ -0,0 +1,8 @@
package comb
import "devops-super/internal/model/entity"
type Role struct {
*entity.Role
Permissions []*Permission
}

View File

@ -0,0 +1,16 @@
package comb
import "devops-super/internal/model/entity"
type User struct {
*entity.User
Roles []*entity.Role
}
func (u *User) RoleCodes() []string {
codes := make([]string, 0)
for _, role := range u.Roles {
codes = append(codes, role.Code)
}
return codes
}

View File

@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// Dept is the golang structure for table dept.
type Dept struct {
Id int `json:"id" description:""` //
Name string `json:"name" description:"部门名称"` // 部门名称
Rank int `json:"rank" description:"排序"` // 排序
ParentId int `json:"parentId" description:"上级部门 id"` // 上级部门 id
UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"` // 更新时间
}

View File

@ -0,0 +1,26 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
)
// Permission is the golang structure for table permission.
type Permission struct {
Id int `json:"id" description:""` //
Title string `json:"title" description:"标题"` // 标题
Name string `json:"name" description:"路由名称"` // 路由名称
Type int `json:"type" description:"类型:1-目录,2-菜单,3-功能"` // 类型:1-目录,2-菜单,3-功能
FRoute string `json:"fRoute" description:"前端路由路径"` // 前端路由路径
BRoutes *gjson.Json `json:"bRoutes" description:"后端路由路径"` // 后端路由路径
Redirect string `json:"redirect" description:"重定向路径"` // 重定向路径
Icon string `json:"icon" description:"图标"` // 图标
Rank int `json:"rank" description:"排序"` // 排序
ShowLink bool `json:"showLink" description:"是否在菜单中展示"` // 是否在菜单中展示
ShowParent bool `json:"showParent" description:"是否展示父级菜单"` // 是否展示父级菜单
KeepAlive bool `json:"keepAlive" description:"页面缓存"` // 页面缓存
ParentId int `json:"parentId" description:"父级权限 id"` // 父级权限 id
}

View File

@ -0,0 +1,19 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
// Role is the golang structure for table role.
type Role struct {
Id int `json:"id" description:""` //
Name string `json:"name" description:"角色名称"` // 角色名称
Code string `json:"code" description:"角色代码"` // 角色代码
Permission *gjson.Json `json:"permission" description:"关联权限"` // 关联权限
UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"` // 更新时间
}

View File

@ -0,0 +1,24 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gtime"
)
// User is the golang structure for table user.
type User struct {
Id uint `json:"id" description:""` //
Username string `json:"username" description:"用户名"` // 用户名
Password string `json:"password" description:"密码"` // 密码
Phone string `json:"phone" description:"手机号码"` // 手机号码
Email string `json:"email" description:"邮箱"` // 邮箱
RealName string `json:"realName" description:"真实姓名"` // 真实姓名
Enabled bool `json:"enabled" description:"是否启用状态"` // 是否启用状态
RoleIds *gjson.Json `json:"roleIds" description:"角色 id"` // 角色 id
DeptId int `json:"deptId" description:"所属部门 id"` // 所属部门 id
UpdatedAt *gtime.Time `json:"updatedAt" description:"更新时间"` // 更新时间
}

View File

@ -0,0 +1,10 @@
package mid
import "github.com/gogf/gf/v2/os/gtime"
type Dept struct {
Name string `v:"required" json:"name"`
Rank int `v:"required" json:"rank"`
ParentId int `json:"parentId"`
CreatedAt *gtime.Time `json:"createdAt"`
}

View File

@ -0,0 +1,43 @@
package mid
import (
"github.com/gogf/gf/v2/encoding/gjson"
)
type Permission struct {
Title string `v:"required" json:"title"`
Name string `v:"required" json:"name"`
Type int `v:"required" json:"type"`
FRoute string `json:"fRoute"`
BRoutes *gjson.Json `json:"bRoutes"`
Redirect string `json:"redirect"`
Icon string `json:"icon"`
Rank int `json:"rank"`
ShowLink bool `v:"required" json:"showLink"`
ShowParent bool `v:"required" json:"showParent"`
KeepAlive bool `v:"required" json:"keepAlive"`
ParentId int `json:"parentId"`
}
type Route struct {
Id int `json:"id"`
Name string `json:"name"`
Title string `json:"title"`
FRoute string `json:"fRoute"`
Redirect string `json:"redirect"`
Icon string `json:"icon,omitempty"`
ParentId int `json:"parentId"`
Rank int `json:"rank"`
ShowLink bool `json:"showLink"`
ShowParent bool `json:"showParent"`
Auths []string `json:"auths,omitempty"`
KeepAlive bool `json:"keepAlive"`
}
type FrontendRouteList []*Route
func (s FrontendRouteList) Len() int { return len(s) }
func (s FrontendRouteList) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s FrontendRouteList) Less(i, j int) bool { return s[i].Rank < s[j].Rank }

View File

@ -0,0 +1,6 @@
package mid
type Role struct {
Name string `v:"required|max-length:30" json:"name"`
Code string `v:"required|max-length:30" json:"code"`
}

View File

@ -0,0 +1,12 @@
package mid
import "github.com/gogf/gf/v2/encoding/gjson"
type User struct {
Username string `v:"required|length:4,30" json:"username"`
Phone string `json:"phone"`
Email string `json:"email"`
RealName string `v:"required" json:"realName"`
RoleIds *gjson.Json `json:"roleIds"`
DeptId int `v:"required" json:"deptId"`
}

View File

@ -0,0 +1 @@
package packed

View File

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