@@ -0,0 +1,37 @@ | |||
package enum | |||
type AdminState int32 | |||
const ( | |||
AdminStateForNormal = 1 | |||
AdminStateForFreeze = 2 | |||
) | |||
func (gt AdminState) String() string { | |||
switch gt { | |||
case AdminStateForNormal: | |||
return "正常" | |||
case AdminStateForFreeze: | |||
return "冻结" | |||
default: | |||
return "未知" | |||
} | |||
} | |||
type IsSuperAdministrator int32 | |||
const ( | |||
IsSuperAdministratorTure = 1 | |||
IsSuperAdministratorFalse = 2 | |||
) | |||
func (gt IsSuperAdministrator) String() string { | |||
switch gt { | |||
case IsSuperAdministratorTure: | |||
return "超管" | |||
case IsSuperAdministratorFalse: | |||
return "非超管" | |||
default: | |||
return "未知" | |||
} | |||
} |
@@ -0,0 +1,19 @@ | |||
package enum | |||
type PermissionGroupState int32 | |||
const ( | |||
PermissionGroupStateForNormal = 1 | |||
PermissionGroupStateForDiscard = 2 | |||
) | |||
func (gt PermissionGroupState) String() string { | |||
switch gt { | |||
case PermissionGroupStateForNormal: | |||
return "正常" | |||
case PermissionGroupStateForDiscard: | |||
return "废弃" | |||
default: | |||
return "未知" | |||
} | |||
} |
@@ -0,0 +1,108 @@ | |||
package comm | |||
import ( | |||
"applet/app/db" | |||
"applet/app/e" | |||
"applet/app/enum" | |||
"applet/app/md" | |||
"applet/app/svc" | |||
"applet/app/utils" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/implement" | |||
"github.com/gin-gonic/gin" | |||
) | |||
func MenuList(c *gin.Context) { | |||
engine := db.Db | |||
admin := svc.GetUser(c) | |||
qrcodeWithBatchRecordsDb := implement.NewPermissionGroupDb(engine) | |||
groupList, err := qrcodeWithBatchRecordsDb.FindPermissionGroupV2() | |||
if err != nil { | |||
e.OutErr(c, e.ERR_DB_ORM, err.Error()) | |||
return | |||
} | |||
// 1、查询出当前用户所有角色 | |||
adminRoleDb := implement.NewAdminRoleDb(engine) | |||
roles, err := adminRoleDb.FindAdminRole(admin.AdmId) | |||
if err != nil { | |||
e.OutErr(c, e.ERR_DB_ORM, err.Error()) | |||
return | |||
} | |||
roleDb := implement.NewRoleDb(engine, 0) | |||
var adminHasPermissionGroupIds []string | |||
for _, v := range *roles { | |||
list, _, err1 := roleDb.FindPermissionGroupByRole(v.RoleId) | |||
if err1 != nil { | |||
e.OutErr(c, e.ERR_DB_ORM, err1.Error()) | |||
return | |||
} | |||
for _, v1 := range list { | |||
adminHasPermissionGroupIds = append(adminHasPermissionGroupIds, utils.IntToStr(v1.PermissionGroup.Id)) | |||
} | |||
} | |||
var tempRespMap = map[string]*md.PermissionGroupListResp{} | |||
var tempRespMapKeys []string | |||
for _, v := range *groupList { | |||
var isCheck bool | |||
if admin.IsSuperAdministrator == enum.IsSuperAdministratorTure { | |||
isCheck = true | |||
} else { | |||
isCheck = false | |||
} | |||
if utils.InArr(utils.IntToStr(v.Id), adminHasPermissionGroupIds) { | |||
isCheck = true | |||
} | |||
if v.State == enum.PermissionGroupStateForDiscard { | |||
isCheck = false | |||
} | |||
tempRespMap[utils.IntToStr(v.Id)] = &md.PermissionGroupListResp{ | |||
Id: v.Id, | |||
Name: v.Name, | |||
Key: v.Key, | |||
State: v.State, | |||
ParentId: v.ParentId, | |||
CreateAt: v.CreateAt, | |||
UpdateAt: v.UpdateAt, | |||
IsCheck: isCheck, | |||
} | |||
tempRespMapKeys = append(tempRespMapKeys, utils.IntToStr(v.Id)) | |||
} | |||
for _, v := range tempRespMap { | |||
if v.ParentId != 0 && tempRespMap[utils.IntToStr(v.ParentId)].ParentId != 0 { | |||
tempRespMap[utils.IntToStr(v.ParentId)].SubPermissionGroupList = append(tempRespMap[utils.IntToStr(v.ParentId)].SubPermissionGroupList, *v) | |||
} | |||
} | |||
for _, v := range tempRespMap { | |||
if v.ParentId != 0 && tempRespMap[utils.IntToStr(v.ParentId)].ParentId == 0 { | |||
tempRespMap[utils.IntToStr(v.ParentId)].SubPermissionGroupList = append(tempRespMap[utils.IntToStr(v.ParentId)].SubPermissionGroupList, *v) | |||
} | |||
} | |||
var resp []*md.PermissionGroupListResp | |||
for _, v := range tempRespMapKeys { | |||
if tempRespMap[v].ParentId == 0 { | |||
resp = append(resp, tempRespMap[v]) | |||
} | |||
} | |||
e.OutSuc(c, map[string]interface{}{ | |||
"list": resp, | |||
"state": []map[string]interface{}{ | |||
{ | |||
"name": enum.PermissionGroupState(enum.PermissionGroupStateForNormal).String(), | |||
"value": enum.PermissionGroupStateForNormal, | |||
}, | |||
{ | |||
"name": enum.PermissionGroupState(enum.PermissionGroupStateForDiscard).String(), | |||
"value": enum.PermissionGroupStateForDiscard, | |||
}, | |||
}, | |||
}, nil) | |||
return | |||
} |
@@ -9,4 +9,8 @@ const ( | |||
AppCfgCacheKey = "cfg_cache:%s" // 占位符: key的第一个字母 | |||
CfgCacheTime = 86400 | |||
AdminRolePermissionKey = "egg_admin_role_permission:%s" // 占位符:admin:id | |||
AdminRolePermissionCacheTime = 3600 * 24 * 0.5 | |||
) |
@@ -0,0 +1,99 @@ | |||
package md | |||
import ( | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/model" | |||
) | |||
type RoleListResp struct { | |||
Data model.Role `json:"data"` | |||
AdminList []struct { | |||
Name string `json:"name"` | |||
} `json:"admin_list"` | |||
} | |||
type UpdateRoleStateReq struct { | |||
RoleId int `json:"role_id" binding:"required" label:"id"` | |||
State int `json:"state" binding:"required" label:"状态"` | |||
} | |||
type AddRoleReq struct { | |||
Name string `json:"name" binding:"required" label:"名称"` | |||
Memo string `json:"memo" binding:"required" label:"备注"` | |||
Logo string `json:"logo" label:"左边图标"` | |||
Label string `json:"label" label:"身份标签"` | |||
SeoLogo string `json:"seo_logo" label:"seo"` | |||
SeoTitle string `json:"seo_title" label:"seo"` | |||
} | |||
type UpdateRoleReq struct { | |||
RoleId int `json:"role_id" binding:"required" label:"id"` | |||
Name string `json:"name" binding:"required" label:"名称"` | |||
Memo string `json:"memo" binding:"required" label:"备注"` | |||
Logo string `json:"logo" label:"左边图标"` | |||
Label string `json:"label" label:"身份标签"` | |||
SeoLogo string `json:"seo_logo" label:"seo"` | |||
SeoTitle string `json:"seo_title" label:"seo"` | |||
} | |||
type RoleBindPermissionGroupReq struct { | |||
RoleId int `json:"role_id" binding:"required" label:"id"` | |||
PermissionIds []int `json:"permission_ids" label:"权限组id"` | |||
} | |||
type PermissionGroupListResp struct { | |||
Id int `json:"id"` | |||
Name string `json:"name"` //菜单名称 | |||
Key string `json:"key"` //唯一标识符 | |||
State int `json:"state"` | |||
ParentId int `json:"parent_id"` //父级id,为0则代表没有父级 | |||
CreateAt string `json:"create_at"` | |||
UpdateAt string `json:"update_at"` | |||
IsCheck bool `json:"is_check"` //是否用用 | |||
SubPermissionGroupList []PermissionGroupListResp `json:"sub_permission_group_list"` //子集菜单 | |||
} | |||
type AdminListReq struct { | |||
Limit int `json:"limit"` | |||
Page int `json:"page" ` | |||
UserName string `json:"username"` | |||
State int `json:"state"` | |||
} | |||
type AdminListResp struct { | |||
AdmId int `json:"adm_id"` | |||
Username string `json:"username"` | |||
State int `json:"state"` | |||
IsSuperAdministrator int `json:"is_super_administrator"` | |||
Memo string `json:"memo"` | |||
CreateAt string `json:"create_at"` | |||
UpdateAt string `json:"update_at"` | |||
RoleList []string `json:"role_list"` | |||
} | |||
type UpdateAdminStateReq struct { | |||
AdmId int `json:"adm_id" binding:"required" label:"管理员id"` | |||
State int `json:"state" binding:"required" label:"状态"` | |||
} | |||
type AddAdminReq struct { | |||
Username string `json:"username" binding:"required" label:"名称"` | |||
Password string `json:"password" binding:"required" label:"密码"` | |||
Memo string `json:"memo" label:"备注"` | |||
} | |||
type UpdateAdminReq struct { | |||
AdmId int `json:"adm_id" binding:"required" label:"管理员id"` | |||
Username string `json:"username" binding:"required" label:"名称"` | |||
Password string `json:"password" binding:"required" label:"密码"` | |||
Memo string `json:"memo" label:"备注"` | |||
} | |||
type BindAdminRoleReq struct { | |||
AdmId int `json:"adm_id" binding:"required" label:"管理员id"` | |||
RoleIds []int `json:"role_ids" label:"角色id"` | |||
} | |||
type BindAdminWithEnterpriseReq struct { | |||
AdmId int `json:"adm_id" binding:"required" label:"管理员id"` | |||
Ids []int `json:"ids" label:"记录id"` | |||
} |
@@ -0,0 +1,5 @@ | |||
package md | |||
var WhiteUri = []string{ | |||
"/api/admin/comm/getMenuList", | |||
} |
@@ -0,0 +1,33 @@ | |||
package mw | |||
import ( | |||
"applet/app/e" | |||
"applet/app/enum" | |||
"applet/app/md" | |||
"applet/app/svc" | |||
"applet/app/utils" | |||
"fmt" | |||
"github.com/gin-gonic/gin" | |||
) | |||
// CheckPermission 检查权限 | |||
func CheckPermission(c *gin.Context) { | |||
admin := svc.GetUser(c) | |||
// TODO::判断是否为超管 | |||
if admin.IsSuperAdministrator == enum.IsSuperAdministratorTure { | |||
c.Next() | |||
} else { | |||
rolePermissionKey := fmt.Sprintf(md.AdminRolePermissionKey, utils.AnyToString(admin.AdmId)) | |||
isHasPermission, err := svc.CheckUserRole(c, rolePermissionKey, c.Request.RequestURI, admin.AdmId) | |||
if err != nil { | |||
e.OutErr(c, e.ERR, err.Error()) | |||
return | |||
} | |||
if !isHasPermission { | |||
e.OutErr(c, e.ERR_FORBIDEN, "当前用户暂未拥有该路由权限,请联系管理员") | |||
return | |||
} | |||
c.Next() | |||
} | |||
} |
@@ -4,7 +4,7 @@ import ( | |||
"github.com/gin-gonic/gin" | |||
) | |||
// cors跨域 | |||
// Cors 跨域 | |||
func Cors(c *gin.Context) { | |||
// 放行所有OPTIONS方法 | |||
if c.Request.Method == "OPTIONS" { | |||
@@ -10,7 +10,7 @@ import ( | |||
"applet/app/utils/cache" | |||
) | |||
// 限流器 | |||
// Limiter 限流器 | |||
func Limiter(c *gin.Context) { | |||
limit := 100 // 限流次数 | |||
ttl := 1 // 限流过期时间 | |||
@@ -3,6 +3,7 @@ package router | |||
import ( | |||
"applet/app/cfg" | |||
"applet/app/hdl" | |||
"applet/app/hdl/comm" | |||
"applet/app/hdl/institutional_management/public_platoon" | |||
"applet/app/mw" | |||
_ "applet/docs" | |||
@@ -49,9 +50,10 @@ func Init() *gin.Engine { | |||
func route(r *gin.RouterGroup) { | |||
r.GET("/test", hdl.Demo) | |||
r.POST("/login", hdl.Login) | |||
rInstitutionalManagement(r.Group("/institutionalManagement")) | |||
r.Use(mw.Auth) // 以下接口需要JWT验证 | |||
rComm(r.Group("/comm")) | |||
r.Use(mw.CheckPermission) // 检测权限 | |||
rInstitutionalManagement(r.Group("/institutionalManagement")) | |||
} | |||
func rInstitutionalManagement(r *gin.RouterGroup) { //制度管理 | |||
@@ -60,3 +62,7 @@ func rInstitutionalManagement(r *gin.RouterGroup) { //制度管理 | |||
rPublicPlatoon.GET("/getBasic", public_platoon.GetPublicPlatoonBasic) | |||
} | |||
} | |||
func rComm(r *gin.RouterGroup) { | |||
r.POST("/getMenuList", comm.MenuList) // 获取菜单栏列表 | |||
} |
@@ -0,0 +1,195 @@ | |||
package svc | |||
import ( | |||
"applet/app/db" | |||
"applet/app/md" | |||
"applet/app/utils" | |||
"applet/app/utils/cache" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/implement" | |||
"code.fnuoos.com/EggPlanet/egg_models.git/src/model" | |||
"encoding/json" | |||
"errors" | |||
"fmt" | |||
"github.com/gin-gonic/gin" | |||
"regexp" | |||
"strings" | |||
"time" | |||
) | |||
func CheckUserRole(c *gin.Context, cacheKey, uri string, admId int) (isHasPermission bool, err error) { | |||
uri = utils.UriFilterExcludeQueryString(uri) // 去除uri中?后的query参数 | |||
isHasPermission = false | |||
var rolePermission []string | |||
var rolePermissionString string | |||
rolePermissionString, _ = cache.GetString(cacheKey) | |||
// TODO::判断是否在白名单中 | |||
if utils.InArr(uri, md.WhiteUri) { | |||
isHasPermission = true | |||
return | |||
} | |||
if rolePermissionString != "" { | |||
// if false { | |||
if err = json.Unmarshal([]byte(rolePermissionString), &rolePermission); err != nil { | |||
return | |||
} | |||
} else { | |||
adminDb := implement.NewAdminDb(db.Db) | |||
list, _, err1 := adminDb.GetAdminRolePermission(admId) | |||
if err1 != nil { | |||
return isHasPermission, err1 | |||
} | |||
for _, v := range list { | |||
rolePermission = append(rolePermission, v.Permission.Action) | |||
} | |||
marshal, err1 := json.Marshal(rolePermission) | |||
if err1 != nil { | |||
return isHasPermission, err1 | |||
} | |||
rolePermissionString = string(marshal) | |||
_, err = cache.SetEx(cacheKey, rolePermissionString, md.AdminRolePermissionCacheTime) | |||
} | |||
if utils.InArr(uri, rolePermission) { | |||
isHasPermission = true | |||
} else { | |||
// 正则匹配占位符情况 | |||
compileRegex := regexp.MustCompile("[0-9]+") | |||
matchArr := compileRegex.FindAllString(uri, -1) | |||
if len(matchArr) > 0 { | |||
uri = strings.Replace(uri, matchArr[len(matchArr)-1], ":id", 1) | |||
if utils.InArr(uri, rolePermission) { | |||
isHasPermission = true | |||
} | |||
} | |||
} | |||
return | |||
} | |||
func DeleteRole(c *gin.Context, roleId int) (err error) { | |||
engine := db.Db | |||
session := engine.NewSession() | |||
defer session.Close() | |||
session.Begin() | |||
// 1、删除 `role` | |||
roleDb := implement.NewRoleDb(engine, roleId) | |||
_, err = roleDb.RoleDeleteBySession(session, roleId) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
// 2、删除 `role_permission_group` | |||
rolePermissionGroupDb := implement.NewRolePermissionGroupDb(db.Db) | |||
_, err = rolePermissionGroupDb.RolePermissionGroupDeleteForRoleBySession(session, roleId) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
// 3、删除 `admin_role` | |||
adminRoleDb := implement.NewAdminRoleDb(db.Db) | |||
_, err = adminRoleDb.AdminRoleDeleteForRoleBySession(session, roleId) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
return session.Commit() | |||
} | |||
func RoleBindPermissionGroup(c *gin.Context, req md.RoleBindPermissionGroupReq) (err error) { | |||
engine := db.Db | |||
session := engine.NewSession() | |||
defer session.Close() | |||
session.Begin() | |||
// 1、查询 `role` | |||
roleDb := implement.NewRoleDb(db.Db, req.RoleId) | |||
role, err := roleDb.GetRole() | |||
if err != nil { | |||
return | |||
} | |||
if role == nil { | |||
return errors.New("未查询到相应记录") | |||
} | |||
// 1、删除 `role_permission_group` | |||
rolePermissionGroupDb := implement.NewRolePermissionGroupDb(db.Db) | |||
_, err = rolePermissionGroupDb.RolePermissionGroupDeleteForRoleBySession(session, req.RoleId) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
// 2、新增 `role_permission_group`` | |||
var mm []*model.RolePermissionGroup | |||
now := time.Now() | |||
for _, v := range req.PermissionIds { | |||
mm = append(mm, &model.RolePermissionGroup{ | |||
RoleId: role.Id, | |||
GroupId: v, | |||
CreateAt: now.Format("2006-01-02 15:04:05"), | |||
UpdateAt: now.Format("2006-01-02 15:04:05"), | |||
}) | |||
} | |||
_, err = rolePermissionGroupDb.BatchAddRolePermissionGroupBySession(session, mm) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
session.Commit() | |||
var data []model.AdminRole | |||
engine.Where("role_id=?", role.Id).Find(&data) | |||
for _, v := range data { | |||
rolePermissionKey := fmt.Sprintf(md.AdminRolePermissionKey, utils.AnyToString(v.AdmId)) | |||
cache.Del(rolePermissionKey) | |||
} | |||
return nil | |||
} | |||
func BindAdminRole(c *gin.Context, req md.BindAdminRoleReq) (err error) { | |||
engine := db.Db | |||
session := engine.NewSession() | |||
defer session.Close() | |||
session.Begin() | |||
// 1、查询 `role` | |||
adminDb := implement.NewAdminDb(db.Db) | |||
role, err := adminDb.GetAdmin(req.AdmId) | |||
if err != nil { | |||
return | |||
} | |||
if role == nil { | |||
return errors.New("未查询到相应记录") | |||
} | |||
// 1、删除 `admin_role` | |||
adminRoleDb := implement.NewAdminRoleDb(db.Db) | |||
_, err = adminRoleDb.AdminRoleDeleteBySession(session, req.AdmId) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
// 2、新增 `删除 `admin_role`` | |||
var mm []*model.AdminRole | |||
now := time.Now() | |||
for _, v := range req.RoleIds { | |||
mm = append(mm, &model.AdminRole{ | |||
AdmId: req.AdmId, | |||
RoleId: v, | |||
State: 1, | |||
CreateAt: now.Format("2006-01-02 15:04:05"), | |||
UpdateAt: now.Format("2006-01-02 15:04:05"), | |||
}) | |||
} | |||
_, err = adminRoleDb.BatchAddAdminRoleBySession(session, mm) | |||
if err != nil { | |||
_ = session.Rollback() | |||
return | |||
} | |||
return session.Commit() | |||
} |
@@ -0,0 +1,16 @@ | |||
package utils | |||
import ( | |||
"net/url" | |||
"strings" | |||
) | |||
func UriFilterExcludeQueryString(uri string) string { | |||
URL, _ := url.Parse(uri) | |||
clearUri := strings.ReplaceAll(uri, URL.RawQuery, "") | |||
clearUri = strings.TrimRight(clearUri, "?") | |||
return strings.TrimRight(clearUri, "/") | |||
} |