package api import ( "database/sql" "fmt" "net/http" "strconv" "strings" ) type ResellersAPI struct { resellerDB *sql.DB } func ResellersHandler(resellerDB *sql.DB) http.Handler { api := &ResellersAPI{resellerDB: resellerDB} return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { p := strings.TrimPrefix(r.URL.Path, "/api/resellers") if r.Method == http.MethodGet && p == "" { api.list(w, r) return } w.WriteHeader(http.StatusNotFound) }) } func (a *ResellersAPI) list(w http.ResponseWriter, r *http.Request) { q := r.URL.Query().Get("q") creatorParam := r.URL.Query().Get("creator") limitStr := r.URL.Query().Get("limit") limit := 2000 if limitStr != "" { if n, err := strconv.Atoi(limitStr); err == nil && n > 0 && n <= 10000 { limit = n } } // 从 context 中获取创建者 ID 列表和管理员状态 creatorIDs := CreatorIDsFrom(r) isAdmin := IsAdminFrom(r) // 构建 SQL 查询 sql1 := "SELECT id, COALESCE(name,'') AS name FROM reseller" args := []interface{}{} whereClauses := []string{} // 如果是超级管理员,跳过 creator 过滤条件 if isAdmin == 1 { // 超级管理员不应用任何 creator 过滤条件 } else if creatorParam != "" || len(creatorIDs) > 0 { // 构建 creator 过滤条件(URL 参数 OR context 中的创建者 ID) creatorConditions := []string{} // 添加 URL 参数的 creator 条件 if creatorParam != "" { if creatorID, err := strconv.Atoi(creatorParam); err == nil { creatorConditions = append(creatorConditions, "creator = ?") args = append(args, creatorID) } } // 添加 context 中的创建者 ID IN 条件 if len(creatorIDs) > 0 { placeholders := []string{} for _, id := range creatorIDs { placeholders = append(placeholders, "?") args = append(args, id) } creatorConditions = append(creatorConditions, fmt.Sprintf("creator IN (%s)", strings.Join(placeholders, ","))) } // 使用 OR 连接两个条件 if len(creatorConditions) > 0 { whereClauses = append(whereClauses, fmt.Sprintf("(%s)", strings.Join(creatorConditions, " OR "))) } } // 添加搜索条件 if q != "" { whereClauses = append(whereClauses, "(CAST(id AS CHAR) LIKE ? OR name LIKE ?)") like := "%" + q + "%" args = append(args, like, like) } // 组装 WHERE 子句 if len(whereClauses) > 0 { sql1 += " WHERE " + strings.Join(whereClauses, " AND ") } sql1 += " ORDER BY id ASC LIMIT ?" args = append(args, limit) rows, err := a.resellerDB.Query(sql1, args...) if err != nil { fail(w, r, http.StatusInternalServerError, err.Error()) return } defer rows.Close() out := []map[string]interface{}{} for rows.Next() { var id sql.NullInt64 var name sql.NullString if err := rows.Scan(&id, &name); err != nil { continue } if !id.Valid { continue } m := map[string]interface{}{"id": id.Int64, "name": name.String} out = append(out, m) } ok(w, r, out) }