feat: 添加种子数据初始化功能,重构多个处理程序以简化错误响应和用户验证

This commit is contained in:
lan
2025-12-02 10:33:19 +08:00
parent bdd2be5dc5
commit 10fdcd916b
30 changed files with 1291 additions and 1778 deletions

View File

@@ -1,12 +1,10 @@
package handler
import (
"carrotskin/internal/model"
"carrotskin/internal/service"
"carrotskin/internal/types"
"carrotskin/pkg/database"
"carrotskin/pkg/logger"
"net/http"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
@@ -26,70 +24,37 @@ import (
// @Failure 500 {object} model.ErrorResponse "服务器错误"
// @Router /api/v1/profile [post]
func CreateProfile(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
// 获取用户ID
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, model.NewErrorResponse(
model.CodeUnauthorized,
"未授权",
nil,
))
userID, ok := GetUserIDFromContext(c)
if !ok {
return
}
// 解析请求
var req types.CreateProfileRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
"请求参数错误: "+err.Error(),
nil,
))
RespondBadRequest(c, "请求参数错误: "+err.Error(), nil)
return
}
// TODO: 从配置或数据库读取限制
maxProfiles := 5
maxProfiles := service.GetMaxProfilesPerUser()
db := database.MustGetDB()
// 检查档案数量限制
if err := service.CheckProfileLimit(db, userID.(int64), maxProfiles); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
err.Error(),
nil,
))
if err := service.CheckProfileLimit(db, userID, maxProfiles); err != nil {
RespondBadRequest(c, err.Error(), nil)
return
}
// 创建档案
profile, err := service.CreateProfile(db, userID.(int64), req.Name)
profile, err := service.CreateProfile(db, userID, req.Name)
if err != nil {
loggerInstance.Error("创建档案失败",
zap.Int64("user_id", userID.(int64)),
logger.MustGetLogger().Error("创建档案失败",
zap.Int64("user_id", userID),
zap.String("name", req.Name),
zap.Error(err),
)
c.JSON(http.StatusInternalServerError, model.NewErrorResponse(
model.CodeServerError,
err.Error(),
nil,
))
RespondServerError(c, err.Error(), nil)
return
}
// 返回成功响应
c.JSON(http.StatusOK, model.NewSuccessResponse(&types.ProfileInfo{
UUID: profile.UUID,
UserID: profile.UserID,
Name: profile.Name,
SkinID: profile.SkinID,
CapeID: profile.CapeID,
IsActive: profile.IsActive,
LastUsedAt: profile.LastUsedAt,
CreatedAt: profile.CreatedAt,
UpdatedAt: profile.UpdatedAt,
}))
RespondSuccess(c, ProfileToProfileInfo(profile))
}
// GetProfiles 获取档案列表
@@ -104,50 +69,22 @@ func CreateProfile(c *gin.Context) {
// @Failure 500 {object} model.ErrorResponse "服务器错误"
// @Router /api/v1/profile [get]
func GetProfiles(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
// 获取用户ID
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, model.NewErrorResponse(
model.CodeUnauthorized,
"未授权",
nil,
))
userID, ok := GetUserIDFromContext(c)
if !ok {
return
}
// 查询档案列表
profiles, err := service.GetUserProfiles(database.MustGetDB(), userID.(int64))
profiles, err := service.GetUserProfiles(database.MustGetDB(), userID)
if err != nil {
loggerInstance.Error("获取档案列表失败",
zap.Int64("user_id", userID.(int64)),
logger.MustGetLogger().Error("获取档案列表失败",
zap.Int64("user_id", userID),
zap.Error(err),
)
c.JSON(http.StatusInternalServerError, model.NewErrorResponse(
model.CodeServerError,
err.Error(),
nil,
))
RespondServerError(c, err.Error(), nil)
return
}
// 转换为响应格式
result := make([]*types.ProfileInfo, 0, len(profiles))
for _, profile := range profiles {
result = append(result, &types.ProfileInfo{
UUID: profile.UUID,
UserID: profile.UserID,
Name: profile.Name,
SkinID: profile.SkinID,
CapeID: profile.CapeID,
IsActive: profile.IsActive,
LastUsedAt: profile.LastUsedAt,
CreatedAt: profile.CreatedAt,
UpdatedAt: profile.UpdatedAt,
})
}
c.JSON(http.StatusOK, model.NewSuccessResponse(result))
RespondSuccess(c, ProfilesToProfileInfos(profiles))
}
// GetProfile 获取档案详情
@@ -162,36 +99,19 @@ func GetProfiles(c *gin.Context) {
// @Failure 500 {object} model.ErrorResponse "服务器错误"
// @Router /api/v1/profile/{uuid} [get]
func GetProfile(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
uuid := c.Param("uuid")
// 查询档案
profile, err := service.GetProfileByUUID(database.MustGetDB(), uuid)
if err != nil {
loggerInstance.Error("获取档案失败",
logger.MustGetLogger().Error("获取档案失败",
zap.String("uuid", uuid),
zap.Error(err),
)
c.JSON(http.StatusNotFound, model.NewErrorResponse(
model.CodeNotFound,
err.Error(),
nil,
))
RespondNotFound(c, err.Error())
return
}
// 返回成功响应
c.JSON(http.StatusOK, model.NewSuccessResponse(&types.ProfileInfo{
UUID: profile.UUID,
UserID: profile.UserID,
Name: profile.Name,
SkinID: profile.SkinID,
CapeID: profile.CapeID,
IsActive: profile.IsActive,
LastUsedAt: profile.LastUsedAt,
CreatedAt: profile.CreatedAt,
UpdatedAt: profile.UpdatedAt,
}))
RespondSuccess(c, ProfileToProfileInfo(profile))
}
// UpdateProfile 更新档案
@@ -211,72 +131,36 @@ func GetProfile(c *gin.Context) {
// @Failure 500 {object} model.ErrorResponse "服务器错误"
// @Router /api/v1/profile/{uuid} [put]
func UpdateProfile(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
userID, ok := GetUserIDFromContext(c)
if !ok {
return
}
uuid := c.Param("uuid")
// 获取用户ID
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, model.NewErrorResponse(
model.CodeUnauthorized,
"未授权",
nil,
))
return
}
// 解析请求
var req types.UpdateProfileRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
"请求参数错误: "+err.Error(),
nil,
))
RespondBadRequest(c, "请求参数错误: "+err.Error(), nil)
return
}
// 更新档案
var namePtr *string
if req.Name != "" {
namePtr = &req.Name
}
profile, err := service.UpdateProfile(database.MustGetDB(), uuid, userID.(int64), namePtr, req.SkinID, req.CapeID)
profile, err := service.UpdateProfile(database.MustGetDB(), uuid, userID, namePtr, req.SkinID, req.CapeID)
if err != nil {
loggerInstance.Error("更新档案失败",
logger.MustGetLogger().Error("更新档案失败",
zap.String("uuid", uuid),
zap.Int64("user_id", userID.(int64)),
zap.Int64("user_id", userID),
zap.Error(err),
)
statusCode := http.StatusInternalServerError
if err.Error() == "档案不存在" {
statusCode = http.StatusNotFound
} else if err.Error() == "无权操作此档案" {
statusCode = http.StatusForbidden
}
c.JSON(statusCode, model.NewErrorResponse(
model.CodeServerError,
err.Error(),
nil,
))
RespondWithError(c, err)
return
}
// 返回成功响应
c.JSON(http.StatusOK, model.NewSuccessResponse(&types.ProfileInfo{
UUID: profile.UUID,
UserID: profile.UserID,
Name: profile.Name,
SkinID: profile.SkinID,
CapeID: profile.CapeID,
IsActive: profile.IsActive,
LastUsedAt: profile.LastUsedAt,
CreatedAt: profile.CreatedAt,
UpdatedAt: profile.UpdatedAt,
}))
RespondSuccess(c, ProfileToProfileInfo(profile))
}
// DeleteProfile 删除档案
@@ -294,48 +178,25 @@ func UpdateProfile(c *gin.Context) {
// @Failure 500 {object} model.ErrorResponse "服务器错误"
// @Router /api/v1/profile/{uuid} [delete]
func DeleteProfile(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
userID, ok := GetUserIDFromContext(c)
if !ok {
return
}
uuid := c.Param("uuid")
// 获取用户ID
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, model.NewErrorResponse(
model.CodeUnauthorized,
"未授权",
nil,
))
return
}
// 删除档案
err := service.DeleteProfile(database.MustGetDB(), uuid, userID.(int64))
err := service.DeleteProfile(database.MustGetDB(), uuid, userID)
if err != nil {
loggerInstance.Error("删除档案失败",
logger.MustGetLogger().Error("删除档案失败",
zap.String("uuid", uuid),
zap.Int64("user_id", userID.(int64)),
zap.Int64("user_id", userID),
zap.Error(err),
)
statusCode := http.StatusInternalServerError
if err.Error() == "档案不存在" {
statusCode = http.StatusNotFound
} else if err.Error() == "无权操作此档案" {
statusCode = http.StatusForbidden
}
c.JSON(statusCode, model.NewErrorResponse(
model.CodeServerError,
err.Error(),
nil,
))
RespondWithError(c, err)
return
}
// 返回成功响应
c.JSON(http.StatusOK, model.NewSuccessResponse(gin.H{
"message": "删除成功",
}))
RespondSuccess(c, gin.H{"message": "删除成功"})
}
// SetActiveProfile 设置活跃档案
@@ -353,46 +214,23 @@ func DeleteProfile(c *gin.Context) {
// @Failure 500 {object} model.ErrorResponse "服务器错误"
// @Router /api/v1/profile/{uuid}/activate [post]
func SetActiveProfile(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
userID, ok := GetUserIDFromContext(c)
if !ok {
return
}
uuid := c.Param("uuid")
// 获取用户ID
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, model.NewErrorResponse(
model.CodeUnauthorized,
"未授权",
nil,
))
return
}
// 设置活跃状态
err := service.SetActiveProfile(database.MustGetDB(), uuid, userID.(int64))
err := service.SetActiveProfile(database.MustGetDB(), uuid, userID)
if err != nil {
loggerInstance.Error("设置活跃档案失败",
logger.MustGetLogger().Error("设置活跃档案失败",
zap.String("uuid", uuid),
zap.Int64("user_id", userID.(int64)),
zap.Int64("user_id", userID),
zap.Error(err),
)
statusCode := http.StatusInternalServerError
if err.Error() == "档案不存在" {
statusCode = http.StatusNotFound
} else if err.Error() == "无权操作此档案" {
statusCode = http.StatusForbidden
}
c.JSON(statusCode, model.NewErrorResponse(
model.CodeServerError,
err.Error(),
nil,
))
RespondWithError(c, err)
return
}
// 返回成功响应
c.JSON(http.StatusOK, model.NewSuccessResponse(gin.H{
"message": "设置成功",
}))
RespondSuccess(c, gin.H{"message": "设置成功"})
}