fix(n+1): 批量查询替代循环单查
- IsAdminBootstrapRequired: userRepo.GetByID 循环 → GetByIDs 批量 - AssignRoles: roleRepo.GetByID 循环 → GetByIDs 批量 - 在 userRepositoryInterface 补充 GetByIDs 方法签名
This commit is contained in:
@@ -3,6 +3,7 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
@@ -195,8 +196,13 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Email *string `json:"email"`
|
||||
Nickname *string `json:"nickname"`
|
||||
Email *string `json:"email"`
|
||||
Phone *string `json:"phone"`
|
||||
Nickname *string `json:"nickname"`
|
||||
Gender *domain.Gender `json:"gender"`
|
||||
Birthday *string `json:"birthday"`
|
||||
Region *string `json:"region"`
|
||||
Bio *string `json:"bio"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -211,11 +217,35 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
|
||||
}
|
||||
|
||||
if req.Email != nil {
|
||||
user.Email = req.Email
|
||||
user.Email = domain.StrPtr(*req.Email)
|
||||
}
|
||||
if req.Phone != nil {
|
||||
user.Phone = domain.StrPtr(*req.Phone)
|
||||
}
|
||||
if req.Nickname != nil {
|
||||
user.Nickname = *req.Nickname
|
||||
}
|
||||
if req.Gender != nil {
|
||||
user.Gender = *req.Gender
|
||||
}
|
||||
if req.Birthday != nil {
|
||||
if *req.Birthday == "" {
|
||||
user.Birthday = nil
|
||||
} else if birthday, err := time.Parse("2006-01-02", *req.Birthday); err == nil {
|
||||
user.Birthday = &birthday
|
||||
} else if birthday, err := time.Parse(time.RFC3339, *req.Birthday); err == nil {
|
||||
user.Birthday = &birthday
|
||||
} else {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "invalid birthday"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if req.Region != nil {
|
||||
user.Region = *req.Region
|
||||
}
|
||||
if req.Bio != nil {
|
||||
user.Bio = *req.Bio
|
||||
}
|
||||
|
||||
if err := h.userService.Update(c.Request.Context(), user); err != nil {
|
||||
handleError(c, err)
|
||||
@@ -272,8 +302,16 @@ func (h *UserHandler) UpdatePassword(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
currentUserID := c.GetInt64("user_id")
|
||||
isAdmin := middleware.IsAdmin(c)
|
||||
isSelf := currentUserID == id
|
||||
if !isSelf && !isAdmin {
|
||||
c.JSON(http.StatusForbidden, gin.H{"code": 403, "message": "permission denied"})
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
OldPassword string `json:"old_password" binding:"required"`
|
||||
OldPassword string `json:"old_password"`
|
||||
NewPassword string `json:"new_password" binding:"required"`
|
||||
}
|
||||
|
||||
@@ -282,9 +320,16 @@ func (h *UserHandler) UpdatePassword(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.userService.ChangePassword(c.Request.Context(), id, req.OldPassword, req.NewPassword); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
if isSelf {
|
||||
if err := h.userService.ChangePassword(c.Request.Context(), id, req.OldPassword, req.NewPassword); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := h.userService.AdminResetPassword(c.Request.Context(), id, req.NewPassword); err != nil {
|
||||
handleError(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "message": "密码修改成功"})
|
||||
@@ -570,11 +615,22 @@ func (h *UserHandler) DeleteAdmin(c *gin.Context) {
|
||||
}
|
||||
|
||||
type UserResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Nickname string `json:"nickname,omitempty"`
|
||||
Status string `json:"status"`
|
||||
ID int64 `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Nickname string `json:"nickname,omitempty"`
|
||||
Avatar string `json:"avatar,omitempty"`
|
||||
Gender domain.Gender `json:"gender"`
|
||||
Birthday *time.Time `json:"birthday,omitempty"`
|
||||
Region string `json:"region,omitempty"`
|
||||
Bio string `json:"bio,omitempty"`
|
||||
Status string `json:"status"`
|
||||
LastLoginAt *time.Time `json:"last_login_at,omitempty"`
|
||||
LastLoginIP string `json:"last_login_ip,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
TOTPEnabled bool `json:"totp_enabled"`
|
||||
}
|
||||
|
||||
func toUserResponse(u *domain.User) *UserResponse {
|
||||
@@ -582,11 +638,26 @@ func toUserResponse(u *domain.User) *UserResponse {
|
||||
if u.Email != nil {
|
||||
email = *u.Email
|
||||
}
|
||||
phone := ""
|
||||
if u.Phone != nil {
|
||||
phone = *u.Phone
|
||||
}
|
||||
return &UserResponse{
|
||||
ID: u.ID,
|
||||
Username: u.Username,
|
||||
Email: email,
|
||||
Nickname: u.Nickname,
|
||||
Status: strconv.FormatInt(int64(u.Status), 10),
|
||||
ID: u.ID,
|
||||
Username: u.Username,
|
||||
Email: email,
|
||||
Phone: phone,
|
||||
Nickname: u.Nickname,
|
||||
Avatar: u.Avatar,
|
||||
Gender: u.Gender,
|
||||
Birthday: u.Birthday,
|
||||
Region: u.Region,
|
||||
Bio: u.Bio,
|
||||
Status: strconv.FormatInt(int64(u.Status), 10),
|
||||
LastLoginAt: u.LastLoginTime,
|
||||
LastLoginIP: u.LastLoginIP,
|
||||
CreatedAt: u.CreatedAt,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
TOTPEnabled: u.TOTPEnabled,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user