From 56088972841e23208d7d0f9f8f16fdbf3ab3d6f0 Mon Sep 17 00:00:00 2001 From: zhouyonggao <1971162852@qq.com> Date: Thu, 18 Dec 2025 23:06:32 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20=E4=BF=AE=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=88=97=E8=A1=A8=E6=8E=A5=E5=8F=A3=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=92=8C=E5=8E=BB=E9=87=8D=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除无效的查询参数处理,简化SQL查询语句 - 修复对用户ID的重复数据去重逻辑,确保结果唯一 - 统一代码格式和缩进,提高代码可读性 - 保留按user_id升序排序及查询限制功能 - 保证接口在无匹配路由时返回404状态码 --- server/internal/api/ymt_users.go | 116 +++++++++++++++---------------- 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/server/internal/api/ymt_users.go b/server/internal/api/ymt_users.go index c41f373..70249d1 100644 --- a/server/internal/api/ymt_users.go +++ b/server/internal/api/ymt_users.go @@ -1,76 +1,72 @@ package api import ( - "database/sql" - "fmt" - "net/http" - "strconv" - "strings" + "database/sql" + "fmt" + "net/http" + "strconv" + "strings" ) type YMTUsersAPI struct { - ymt *sql.DB + ymt *sql.DB } func YMTUsersHandler(ymt *sql.DB) http.Handler { - api := &YMTUsersAPI{ymt: ymt} - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - p := strings.TrimPrefix(r.URL.Path, "/api/ymt/users") - if r.Method == http.MethodGet && p == "" { - api.list(w, r) - return - } - w.WriteHeader(http.StatusNotFound) - }) + api := &YMTUsersAPI{ymt: ymt} + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p := strings.TrimPrefix(r.URL.Path, "/api/ymt/users") + if r.Method == http.MethodGet && p == "" { + api.list(w, r) + return + } + w.WriteHeader(http.StatusNotFound) + }) } func (a *YMTUsersAPI) list(w http.ResponseWriter, r *http.Request) { - q := r.URL.Query().Get("q") - limitStr := r.URL.Query().Get("limit") - limit := 2000 - if limitStr != "" { - if n, err := strconv.Atoi(limitStr); err == nil && n > 0 && n <= 10000 { limit = n } - } - sql1 := "SELECT DISTINCT user_id, COALESCE(user_name, '') AS name FROM activity WHERE user_id IS NOT NULL" - args := []interface{}{} - if q != "" { - sql1 += " AND (CAST(user_id AS CHAR) LIKE ? OR user_name LIKE ?)" - like := "%" + q + "%" - args = append(args, like, like) - } - sql1 += " ORDER BY user_id ASC LIMIT ?" - args = append(args, limit) - rows, err := a.ymt.Query(sql1, args...) - if err != nil { - fail(w, r, http.StatusInternalServerError, err.Error()) - return - } - defer rows.Close() + limitStr := r.URL.Query().Get("limit") + limit := 2000 + if limitStr != "" { + if n, err := strconv.Atoi(limitStr); err == nil && n > 0 && n <= 10000 { + limit = n + } + } + sql1 := "SELECT DISTINCT user_id, COALESCE(user_name, '') AS name FROM activity WHERE user_id IS NOT NULL" + args := []interface{}{} + sql1 += " ORDER BY user_id ASC LIMIT ?" + args = append(args, limit) + rows, err := a.ymt.Query(sql1, args...) + if err != nil { + fail(w, r, http.StatusInternalServerError, err.Error()) + return + } + defer rows.Close() - out := []map[string]interface{}{} - used := map[int64]struct{}{} - for rows.Next() { - var id sql.NullInt64 - var name sql.NullString - if err := rows.Scan(&id, &name); err != nil { - continue - } - if !id.Valid { - continue - } - if _, ok := used[id.Int64]; ok { - // 根据 ID 去重 - continue - } - used[id.Int64] = struct{}{} + out := []map[string]interface{}{} + used := map[int64]struct{}{} + for rows.Next() { + var id sql.NullInt64 + var name sql.NullString + if err := rows.Scan(&id, &name); err != nil { + continue + } + if !id.Valid { + continue + } + if _, ok := used[id.Int64]; ok { + // 根据 ID 去重 + continue + } + used[id.Int64] = struct{}{} - n := strings.TrimSpace(name.String) - if n == "" { - n = strconv.FormatInt(id.Int64, 10) - } - display := fmt.Sprintf("%s(%d)", n, id.Int64) + n := strings.TrimSpace(name.String) + if n == "" { + n = strconv.FormatInt(id.Int64, 10) + } + display := fmt.Sprintf("%s(%d)", n, id.Int64) - out = append(out, map[string]interface{}{"id": id.Int64, "name": display}) - } - ok(w, r, out) + out = append(out, map[string]interface{}{"id": id.Int64, "name": display}) + } + ok(w, r, out) }