refactor: 移除全局单例、修复分层违规、统一错误与响应
Some checks failed
Build / build (push) Successful in 7m52s
Build / build-docker (push) Has been cancelled

This commit is contained in:
lafay
2026-06-15 16:40:36 +08:00
parent d9de39a0a3
commit 7d1c78f965
55 changed files with 593 additions and 1744 deletions

View File

@@ -1,9 +1,11 @@
package handler
import (
"errors"
"net/http"
"strconv"
apperrors "carrotskin/internal/errors"
"carrotskin/internal/container"
"carrotskin/internal/model"
@@ -46,11 +48,16 @@ func (h *AdminHandler) SetUserRole(c *gin.Context) {
return
}
// 获取当前操作者ID
operatorID, _ := c.Get("user_id")
// 获取当前操作者ID(安全类型断言,防止中间件异常时 panic
operatorIDVal, _ := c.Get("user_id")
operatorID, ok := operatorIDVal.(int64)
if !ok {
RespondServerError(c, "操作者ID类型错误", nil)
return
}
// 不能修改自己的角色
if req.UserID == operatorID.(int64) {
if req.UserID == operatorID {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
"不能修改自己的角色",
@@ -59,9 +66,13 @@ func (h *AdminHandler) SetUserRole(c *gin.Context) {
return
}
// 检查目标用户是否存在
targetUser, err := h.container.UserRepo.FindByID(c.Request.Context(), req.UserID)
if err != nil || targetUser == nil {
// 检查目标用户是否存在(区分 DB 错误与"用户不存在"
targetUser, err := h.container.UserService.GetByID(c.Request.Context(), req.UserID)
if err != nil {
RespondServerError(c, "查询用户失败", err)
return
}
if targetUser == nil {
c.JSON(http.StatusNotFound, model.NewErrorResponse(
model.CodeNotFound,
"用户不存在",
@@ -71,16 +82,13 @@ func (h *AdminHandler) SetUserRole(c *gin.Context) {
}
// 更新用户角色
err = h.container.UserRepo.UpdateFields(c.Request.Context(), req.UserID, map[string]interface{}{
"role": req.Role,
})
if err != nil {
if err := h.container.UserService.SetRole(c.Request.Context(), req.UserID, req.Role); err != nil {
RespondServerError(c, "更新用户角色失败", err)
return
}
h.container.Logger.Info("管理员修改用户角色",
zap.Int64("operator_id", operatorID.(int64)),
zap.Int64("operator_id", operatorID),
zap.Int64("target_user_id", req.UserID),
zap.String("new_role", req.Role),
)
@@ -114,13 +122,12 @@ func (h *AdminHandler) GetUserList(c *gin.Context) {
pageSize = 20
}
// 使用数据库直接查询用户列表
var users []model.User
var total int64
db := h.container.DB
db.Model(&model.User{}).Count(&total)
db.Offset((page - 1) * pageSize).Limit(pageSize).Order("id DESC").Find(&users)
// 通过 Service 层查询用户列表
users, total, err := h.container.UserService.ListUsers(c.Request.Context(), page, pageSize)
if err != nil {
RespondServerError(c, "获取用户列表失败", err)
return
}
// 构建响应(隐藏敏感信息)
userList := make([]gin.H, len(users))
@@ -163,7 +170,7 @@ func (h *AdminHandler) GetUserDetail(c *gin.Context) {
return
}
user, err := h.container.UserRepo.FindByID(c.Request.Context(), userID)
user, err := h.container.UserService.GetByID(c.Request.Context(), userID)
if err != nil || user == nil {
c.JSON(http.StatusNotFound, model.NewErrorResponse(
model.CodeNotFound,
@@ -212,10 +219,15 @@ func (h *AdminHandler) SetUserStatus(c *gin.Context) {
return
}
operatorID, _ := c.Get("user_id")
operatorIDVal, _ := c.Get("user_id")
operatorID, ok := operatorIDVal.(int64)
if !ok {
RespondServerError(c, "操作者ID类型错误", nil)
return
}
// 不能修改自己的状态
if req.UserID == operatorID.(int64) {
if req.UserID == operatorID {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
"不能修改自己的状态",
@@ -224,9 +236,13 @@ func (h *AdminHandler) SetUserStatus(c *gin.Context) {
return
}
// 检查目标用户是否存在
targetUser, err := h.container.UserRepo.FindByID(c.Request.Context(), req.UserID)
if err != nil || targetUser == nil {
// 检查目标用户是否存在(区分 DB 错误与"用户不存在"
targetUser, err := h.container.UserService.GetByID(c.Request.Context(), req.UserID)
if err != nil {
RespondServerError(c, "查询用户失败", err)
return
}
if targetUser == nil {
c.JSON(http.StatusNotFound, model.NewErrorResponse(
model.CodeNotFound,
"用户不存在",
@@ -236,10 +252,7 @@ func (h *AdminHandler) SetUserStatus(c *gin.Context) {
}
// 更新用户状态
err = h.container.UserRepo.UpdateFields(c.Request.Context(), req.UserID, map[string]interface{}{
"status": req.Status,
})
if err != nil {
if err := h.container.UserService.SetStatus(c.Request.Context(), req.UserID, req.Status); err != nil {
RespondServerError(c, "更新用户状态失败", err)
return
}
@@ -247,7 +260,7 @@ func (h *AdminHandler) SetUserStatus(c *gin.Context) {
statusText := map[int16]string{1: "正常", 0: "禁用", -1: "删除"}[req.Status]
h.container.Logger.Info("管理员修改用户状态",
zap.Int64("operator_id", operatorID.(int64)),
zap.Int64("operator_id", operatorID),
zap.Int64("target_user_id", req.UserID),
zap.Int16("new_status", req.Status),
)
@@ -277,30 +290,30 @@ func (h *AdminHandler) DeleteTexture(c *gin.Context) {
return
}
operatorID, _ := c.Get("user_id")
// 检查材质是否存在
var texture model.Texture
if err := h.container.DB.First(&texture, textureID).Error; err != nil {
c.JSON(http.StatusNotFound, model.NewErrorResponse(
model.CodeNotFound,
"材质不存在",
nil,
))
operatorIDVal, _ := c.Get("user_id")
operatorID, ok := operatorIDVal.(int64)
if !ok {
RespondServerError(c, "操作者ID类型错误", nil)
return
}
// 删除材质
if err := h.container.DB.Delete(&texture).Error; err != nil {
// 通过 Service 删除材质Service 会检查存在性)
if err := h.container.TextureService.AdminDelete(c.Request.Context(), textureID); err != nil {
if errors.Is(err, apperrors.ErrTextureNotFound) {
c.JSON(http.StatusNotFound, model.NewErrorResponse(
model.CodeNotFound,
"材质不存在",
nil,
))
return
}
RespondServerError(c, "删除材质失败", err)
return
}
h.container.Logger.Info("管理员删除材质",
zap.Int64("operator_id", operatorID.(int64)),
zap.Int64("operator_id", operatorID),
zap.Int64("texture_id", textureID),
zap.Int64("uploader_id", texture.UploaderID),
zap.String("texture_name", texture.Name),
)
c.JSON(http.StatusOK, model.NewSuccessResponse(gin.H{
@@ -330,12 +343,12 @@ func (h *AdminHandler) GetTextureList(c *gin.Context) {
pageSize = 20
}
var textures []model.Texture
var total int64
db := h.container.DB
db.Model(&model.Texture{}).Count(&total)
db.Preload("Uploader").Offset((page - 1) * pageSize).Limit(pageSize).Order("id DESC").Find(&textures)
// 通过 Service 层查询材质列表
textures, total, err := h.container.TextureService.ListForAdmin(c.Request.Context(), page, pageSize)
if err != nil {
RespondServerError(c, "获取材质列表失败", err)
return
}
// 构建响应
textureList := make([]gin.H, len(textures))