110 lines
2.7 KiB
Go
110 lines
2.7 KiB
Go
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)
|
||
|
||
// 构建 SQL 查询
|
||
sql1 := "SELECT id, COALESCE(name,'') AS name FROM reseller"
|
||
args := []interface{}{}
|
||
whereClauses := []string{}
|
||
|
||
// 构建 creator 过滤条件(URL 参数 OR context 中的创建者 ID)
|
||
if creatorParam != "" || len(creatorIDs) > 0 {
|
||
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)
|
||
}
|