From 686df08da85e529097de8d227bd41fca227ad53e Mon Sep 17 00:00:00 2001 From: zhouyonggao <1971162852@qq.com> Date: Fri, 26 Dec 2025 16:57:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86):=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=B6=85=E7=BA=A7=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在认证中间件中增加对超级管理员权限的支持,并修改经销商列表接口以跳过管理员的条件过滤 当用户是超级管理员时,可以查看所有经销商数据 --- server/internal/api/middleware.go | 54 ++++++++++++++++++++++++++++--- server/internal/api/resellers.go | 10 ++++-- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/server/internal/api/middleware.go b/server/internal/api/middleware.go index 4007de7..e3d45d1 100644 --- a/server/internal/api/middleware.go +++ b/server/internal/api/middleware.go @@ -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 +} diff --git a/server/internal/api/resellers.go b/server/internal/api/resellers.go index 4a32e9e..dc31111 100644 --- a/server/internal/api/resellers.go +++ b/server/internal/api/resellers.go @@ -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 条件