更新
This commit is contained in:
1 parent
5718a00e31
commit
1850ac640e
226 files changed
+37772
-12071
No files matched your search
+59
-17
@@ -2,13 +2,55 @@ package services
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"server/models"
|
||||
)
|
||||
|
||||
// ParseMenuRights 将角色 rights 解析为菜单 ID 集合(兼容 JSON 数组 / 逗号分隔)。
|
||||
// 数字数组是角色保存接口 json.Marshal([]uint64) 写回的规范格式,必须支持;
|
||||
// 若只按 []string 反序列化会整体失败并退化成逗号切分,
|
||||
// 首尾元素会带上 [ / ] 而解析不出数字,导致第一个和最后一个菜单被静默丢弃。
|
||||
func ParseMenuRights(raw string) map[uint64]bool {
|
||||
set := map[uint64]bool{}
|
||||
var arr []interface{}
|
||||
if err := json.Unmarshal([]byte(raw), &arr); err == nil {
|
||||
for _, v := range arr {
|
||||
if n := menuIDOf(v); n > 0 {
|
||||
set[n] = true
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
for _, s := range strings.Split(raw, ",") {
|
||||
if n, e := strconv.ParseUint(strings.TrimSpace(s), 10, 64); e == nil {
|
||||
set[n] = true
|
||||
}
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
// menuIDOf 把 JSON 元素(数字或字符串)转成菜单 ID,无效时返回 0
|
||||
func menuIDOf(v interface{}) uint64 {
|
||||
switch t := v.(type) {
|
||||
case float64:
|
||||
if t > 0 {
|
||||
return uint64(t)
|
||||
}
|
||||
case string:
|
||||
if n, e := strconv.ParseUint(strings.TrimSpace(t), 10, 64); e == nil {
|
||||
return n
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// CheckUserPermission 校验用户是否拥有指定权限标识。
|
||||
// 兼容 rights 为 JSON 数组 / 逗号分隔字符串;解析失败时默认放行,避免历史数据阻断请求。
|
||||
// rights 里存的是菜单 ID 而不是权限串,必须经 yz_system_menu.permission 换算后再比对;
|
||||
// 直接拿 rights 元素和权限串比永远不相等,会把本来有权限的角色全部判成无权访问。
|
||||
// rights 为空(nil / 空串)视为全权限,与菜单过滤 filterMenusByRights 口径一致;
|
||||
// rights 有内容却解析不出任何菜单 ID(历史脏数据)按无权限处理,不放行。
|
||||
func CheckUserPermission(userID int, permission string) (bool, error) {
|
||||
if permission == "" || userID <= 0 {
|
||||
return true, nil
|
||||
@@ -26,25 +68,25 @@ func CheckUserPermission(userID int, permission string) (bool, error) {
|
||||
if role.Rights == nil || strings.TrimSpace(*role.Rights) == "" {
|
||||
return true, nil
|
||||
}
|
||||
rightsRaw := strings.TrimSpace(*role.Rights)
|
||||
|
||||
// 1) JSON 数组格式
|
||||
var arr []string
|
||||
if err := json.Unmarshal([]byte(rightsRaw), &arr); err == nil {
|
||||
for _, p := range arr {
|
||||
if strings.TrimSpace(p) == permission {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
menuIDs := ParseMenuRights(*role.Rights)
|
||||
if len(menuIDs) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// 2) 逗号分隔字符串
|
||||
for _, p := range strings.Split(rightsRaw, ",") {
|
||||
if strings.TrimSpace(p) == permission {
|
||||
return true, nil
|
||||
}
|
||||
idList := make([]uint64, 0, len(menuIDs))
|
||||
for id := range menuIDs {
|
||||
idList = append(idList, id)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
// 只有启用且未删除的菜单才能授予权限,禁用的菜单不应继续放行其权限标识
|
||||
count, err := models.Orm.QueryTable(new(models.SystemMenu)).
|
||||
Filter("id__in", idList).
|
||||
Filter("permission", permission).
|
||||
Filter("status", 1).
|
||||
Filter("delete_time__isnull", true).
|
||||
Count()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
Reference in new issue
Block a user