feat: 交付官方 Docker 运行时,外观改背景图并下线自定义 CSS/JS
站点/后台分轨背景与用户列表排序一并落地;生产 CORS 改走 SITE_URL,健康检查带版本号。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,10 +2,13 @@ package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/freefire/jiang13-bbs/model"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// 管理员用户操作的业务护栏(handler 层映射为 4xx,前端只展示消息)
|
||||
@@ -86,6 +89,43 @@ type AdminUserListQuery struct {
|
||||
Keyword string // 用户名 / 昵称 / 邮箱模糊匹配
|
||||
Role string // "" 全部 | "staff" 管理团队 | 具体角色枚举
|
||||
Status string // "" 全部 | "banned" 已封禁 | "normal" 正常
|
||||
Sort string // 白名单列:id / role / status / points / last_login / counts / created_at / online
|
||||
Dir string // asc | desc;非法值按 desc
|
||||
}
|
||||
|
||||
// adminUserOrderSQL 生成 ORDER BY 表达式。sort/dir 均走白名单,默认 id DESC(与历史行为一致)。
|
||||
func adminUserOrderSQL(sort, dir string) string {
|
||||
ord := "DESC"
|
||||
if strings.EqualFold(strings.TrimSpace(dir), "asc") {
|
||||
ord = "ASC"
|
||||
}
|
||||
switch strings.TrimSpace(sort) {
|
||||
case "role":
|
||||
return fmt.Sprintf(
|
||||
"CASE users.role WHEN 'owner' THEN 100 WHEN 'super_admin' THEN 80 WHEN 'admin' THEN 50 WHEN 'board_admin' THEN 30 ELSE 0 END %s, users.id DESC",
|
||||
ord,
|
||||
)
|
||||
case "status":
|
||||
return fmt.Sprintf("users.banned %s, users.id DESC", ord)
|
||||
case "points":
|
||||
return fmt.Sprintf("users.points %s, users.id DESC", ord)
|
||||
case "created_at":
|
||||
return fmt.Sprintf("users.created_at %s, users.id DESC", ord)
|
||||
case "online":
|
||||
return fmt.Sprintf("users.last_seen_at %s NULLS LAST, users.id DESC", ord)
|
||||
case "last_login":
|
||||
return fmt.Sprintf(
|
||||
"(SELECT MAX(created_at) FROM login_logs WHERE login_logs.user_id = users.id AND login_logs.success = true) %s NULLS LAST, users.id DESC",
|
||||
ord,
|
||||
)
|
||||
case "counts":
|
||||
return fmt.Sprintf(
|
||||
"(SELECT COUNT(*) FROM posts WHERE posts.user_id = users.id AND posts.status = '%s' AND posts.deleted_at IS NULL) %s, users.id DESC",
|
||||
model.ContentStatusPublished, ord,
|
||||
)
|
||||
default:
|
||||
return "users.id " + ord
|
||||
}
|
||||
}
|
||||
|
||||
// AdminUserListResult 分页结果 + 汇总
|
||||
@@ -129,7 +169,9 @@ func (s *AdminUserService) List(q AdminUserListQuery) (*AdminUserListResult, err
|
||||
}
|
||||
|
||||
var users []model.User
|
||||
if err := query.Order("id DESC").
|
||||
if err := query.Clauses(clause.OrderBy{
|
||||
Expression: clause.Expr{SQL: adminUserOrderSQL(q.Sort, q.Dir)},
|
||||
}).
|
||||
Offset((q.Page - 1) * q.Size).Limit(q.Size).
|
||||
Find(&users).Error; err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user