用户管理: 编辑用户信息(用户名/邮箱/重置密码/角色/状态)
- AdminPatchUser 扩展 username/email/password 更新, 含唯一性与格式校验 - 编辑弹窗补充用户名/邮箱/重置密码字段(留空不改密码) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,9 @@ package api
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -46,14 +48,57 @@ func (h *Handler) AdminPatchUser(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
Role *string `json:"role"`
|
||||
Status *string `json:"status"`
|
||||
Username *string `json:"username"`
|
||||
Email *string `json:"email"`
|
||||
Password *string `json:"password"`
|
||||
Role *string `json:"role"`
|
||||
Status *string `json:"status"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
resp.Fail(c, http.StatusBadRequest, "invalid input")
|
||||
return
|
||||
}
|
||||
updates := map[string]any{}
|
||||
if req.Username != nil {
|
||||
u := strings.TrimSpace(*req.Username)
|
||||
if len(u) < 3 || len(u) > 32 {
|
||||
resp.Fail(c, http.StatusBadRequest, "username must be 3-32 chars")
|
||||
return
|
||||
}
|
||||
var n int64
|
||||
h.a.DB.Model(&store.User{}).Where("username = ? AND id != ?", u, id).Count(&n)
|
||||
if n > 0 {
|
||||
resp.Fail(c, http.StatusConflict, "username already taken")
|
||||
return
|
||||
}
|
||||
updates["username"] = u
|
||||
}
|
||||
if req.Email != nil {
|
||||
e := strings.ToLower(strings.TrimSpace(*req.Email))
|
||||
if _, err := mail.ParseAddress(e); err != nil {
|
||||
resp.Fail(c, http.StatusBadRequest, "invalid email")
|
||||
return
|
||||
}
|
||||
var n int64
|
||||
h.a.DB.Model(&store.User{}).Where("email = ? AND id != ?", e, id).Count(&n)
|
||||
if n > 0 {
|
||||
resp.Fail(c, http.StatusConflict, "email already taken")
|
||||
return
|
||||
}
|
||||
updates["email"] = e
|
||||
}
|
||||
if req.Password != nil && *req.Password != "" {
|
||||
if len(*req.Password) < 8 {
|
||||
resp.Fail(c, http.StatusBadRequest, "password must be at least 8 chars")
|
||||
return
|
||||
}
|
||||
hash, err := h.a.Hasher.HashPassword(*req.Password)
|
||||
if err != nil {
|
||||
resp.Fail(c, http.StatusInternalServerError, "failed to hash password")
|
||||
return
|
||||
}
|
||||
updates["password_hash"] = hash
|
||||
}
|
||||
if req.Role != nil {
|
||||
if *req.Role != store.RoleUser && *req.Role != store.RoleAdmin {
|
||||
resp.Fail(c, http.StatusBadRequest, "role must be user or admin")
|
||||
|
||||
Reference in New Issue
Block a user