feat(权限管理): 增加超级管理员权限支持

在认证中间件中增加对超级管理员权限的支持,并修改经销商列表接口以跳过管理员的条件过滤
当用户是超级管理员时,可以查看所有经销商数据
This commit is contained in:
zhouyonggao 2025-12-26 16:57:57 +08:00
parent 55a171fff3
commit 686df08da8
2 changed files with 56 additions and 8 deletions

View File

@ -17,6 +17,7 @@ var sqlKey ctxKey = "sql"
var metaKey ctxKey = "req_meta"
var payloadKey ctxKey = "payload"
var creatorIDsKey ctxKey = "creator_ids" // 存储用户的创建者ID列表
var isAdminKey ctxKey = "is_admin" // 存储是否超级管理员
func withTrace(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -88,9 +89,10 @@ func PayloadFrom(r *http.Request) string {
// AuthResponse 营销系统鉴权接口返回结构
type AuthResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data []int `json:"data"` // 创建者ID列表
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"` // 创建者ID列表或权限数据
IsAdmin int `json:"isAdmin"` // 1:超级管理员 0:普通用户
}
// withAuth 认证中间件:验证 token 并获取用户数据权限
@ -147,8 +149,40 @@ func withAuth(apiDomain string) func(http.Handler) http.Handler {
return
}
// 将创建者ID列表存储到 context 中
ctx := context.WithValue(r.Context(), creatorIDsKey, authResp.Data)
// 将创建者ID列表和isAdmin信息存储到 context 中
var creatorIDs []int
var isAdmin int = authResp.IsAdmin // 从响应中获取 isAdmin 信息
// 处理 Data 字段(可能是数组或对象)
if data, ok := authResp.Data.([]interface{}); ok {
// Data 是数组,转换为 []int
creatorIDs = make([]int, 0, len(data))
for _, v := range data {
if num, ok := v.(float64); ok {
creatorIDs = append(creatorIDs, int(num))
}
}
} else if dataMap, ok := authResp.Data.(map[string]interface{}); ok {
// Data 是对象从中提取创建者ID列表
if ids, ok := dataMap["creatorIDs"].([]interface{}); ok {
creatorIDs = make([]int, 0, len(ids))
for _, v := range ids {
if num, ok := v.(float64); ok {
creatorIDs = append(creatorIDs, int(num))
}
}
}
// 如果 isAdmin 也存在于 data 对象中,优先使用 data 中的值
if adminVal, ok := dataMap["isAdmin"].(float64); ok {
isAdmin = int(adminVal)
}
} else if dataSlice, ok := authResp.Data.([]int); ok {
// Data 直接是 []int
creatorIDs = dataSlice
}
ctx := context.WithValue(r.Context(), creatorIDsKey, creatorIDs)
ctx = context.WithValue(ctx, isAdminKey, isAdmin)
h.ServeHTTP(w, r.WithContext(ctx))
})
}
@ -163,3 +197,13 @@ func CreatorIDsFrom(r *http.Request) []int {
ids, _ := v.([]int)
return ids
}
// IsAdminFrom 从 context 中获取是否超级管理员
func IsAdminFrom(r *http.Request) int {
v := r.Context().Value(isAdminKey)
if v == nil {
return 0
}
admin, _ := v.(int)
return admin
}

View File

@ -35,16 +35,20 @@ func (a *ResellersAPI) list(w http.ResponseWriter, r *http.Request) {
}
}
// 从 context 中获取创建者 ID 列表
// 从 context 中获取创建者 ID 列表和管理员状态
creatorIDs := CreatorIDsFrom(r)
isAdmin := IsAdminFrom(r)
// 构建 SQL 查询
sql1 := "SELECT id, COALESCE(name,'') AS name FROM reseller"
args := []interface{}{}
whereClauses := []string{}
// 构建 creator 过滤条件URL 参数 OR context 中的创建者 ID
if creatorParam != "" || len(creatorIDs) > 0 {
// 如果是超级管理员,跳过 creator 过滤条件
if isAdmin == 1 {
// 超级管理员不应用任何 creator 过滤条件
} else if creatorParam != "" || len(creatorIDs) > 0 {
// 构建 creator 过滤条件URL 参数 OR context 中的创建者 ID
creatorConditions := []string{}
// 添加 URL 参数的 creator 条件