@@ -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的第一个字母 | AppCfgCacheKey = "cfg_cache:%s" // 占位符: key的第一个字母 | ||||
CfgCacheTime = 86400 | 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" | "github.com/gin-gonic/gin" | ||||
) | ) | ||||
// cors跨域 | |||||
// Cors 跨域 | |||||
func Cors(c *gin.Context) { | func Cors(c *gin.Context) { | ||||
// 放行所有OPTIONS方法 | // 放行所有OPTIONS方法 | ||||
if c.Request.Method == "OPTIONS" { | if c.Request.Method == "OPTIONS" { | ||||
@@ -10,7 +10,7 @@ import ( | |||||
"applet/app/utils/cache" | "applet/app/utils/cache" | ||||
) | ) | ||||
// 限流器 | |||||
// Limiter 限流器 | |||||
func Limiter(c *gin.Context) { | func Limiter(c *gin.Context) { | ||||
limit := 100 // 限流次数 | limit := 100 // 限流次数 | ||||
ttl := 1 // 限流过期时间 | ttl := 1 // 限流过期时间 | ||||
@@ -3,6 +3,7 @@ package router | |||||
import ( | import ( | ||||
"applet/app/cfg" | "applet/app/cfg" | ||||
"applet/app/hdl" | "applet/app/hdl" | ||||
"applet/app/hdl/comm" | |||||
"applet/app/hdl/institutional_management/public_platoon" | "applet/app/hdl/institutional_management/public_platoon" | ||||
"applet/app/mw" | "applet/app/mw" | ||||
_ "applet/docs" | _ "applet/docs" | ||||
@@ -49,9 +50,10 @@ func Init() *gin.Engine { | |||||
func route(r *gin.RouterGroup) { | func route(r *gin.RouterGroup) { | ||||
r.GET("/test", hdl.Demo) | r.GET("/test", hdl.Demo) | ||||
r.POST("/login", hdl.Login) | r.POST("/login", hdl.Login) | ||||
rInstitutionalManagement(r.Group("/institutionalManagement")) | |||||
r.Use(mw.Auth) // 以下接口需要JWT验证 | r.Use(mw.Auth) // 以下接口需要JWT验证 | ||||
rComm(r.Group("/comm")) | |||||
r.Use(mw.CheckPermission) // 检测权限 | |||||
rInstitutionalManagement(r.Group("/institutionalManagement")) | |||||
} | } | ||||
func rInstitutionalManagement(r *gin.RouterGroup) { //制度管理 | func rInstitutionalManagement(r *gin.RouterGroup) { //制度管理 | ||||
@@ -60,3 +62,7 @@ func rInstitutionalManagement(r *gin.RouterGroup) { //制度管理 | |||||
rPublicPlatoon.GET("/getBasic", public_platoon.GetPublicPlatoonBasic) | 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, "/") | |||||
} |