399 lines
10 KiB
Go
399 lines
10 KiB
Go
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"
|
||
)
|
||
|
||
// CreateProfile 创建档案
|
||
// @Summary 创建Minecraft档案
|
||
// @Description 创建新的Minecraft角色档案,UUID由后端自动生成
|
||
// @Tags profile
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security BearerAuth
|
||
// @Param request body types.CreateProfileRequest true "档案信息(仅需提供角色名)"
|
||
// @Success 200 {object} model.Response{data=types.ProfileInfo} "创建成功,返回完整档案信息(含自动生成的UUID)"
|
||
// @Failure 400 {object} model.ErrorResponse "请求参数错误或已达档案数量上限"
|
||
// @Failure 401 {object} model.ErrorResponse "未授权"
|
||
// @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,
|
||
))
|
||
return
|
||
}
|
||
|
||
// 解析请求
|
||
var req types.CreateProfileRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
|
||
model.CodeBadRequest,
|
||
"请求参数错误: "+err.Error(),
|
||
nil,
|
||
))
|
||
return
|
||
}
|
||
|
||
// TODO: 从配置或数据库读取限制
|
||
maxProfiles := 5
|
||
db := database.MustGetDB()
|
||
// 检查档案数量限制
|
||
if err := service.CheckProfileLimit(db, userID.(int64), maxProfiles); err != nil {
|
||
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
|
||
model.CodeBadRequest,
|
||
err.Error(),
|
||
nil,
|
||
))
|
||
return
|
||
}
|
||
|
||
// 创建档案
|
||
profile, err := service.CreateProfile(db, userID.(int64), req.Name)
|
||
if err != nil {
|
||
loggerInstance.Error("创建档案失败",
|
||
zap.Int64("user_id", userID.(int64)),
|
||
zap.String("name", req.Name),
|
||
zap.Error(err),
|
||
)
|
||
c.JSON(http.StatusInternalServerError, model.NewErrorResponse(
|
||
model.CodeServerError,
|
||
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,
|
||
}))
|
||
}
|
||
|
||
// GetProfiles 获取档案列表
|
||
// @Summary 获取档案列表
|
||
// @Description 获取当前用户的所有档案
|
||
// @Tags profile
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security BearerAuth
|
||
// @Success 200 {object} model.Response "获取成功"
|
||
// @Failure 401 {object} model.ErrorResponse "未授权"
|
||
// @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,
|
||
))
|
||
return
|
||
}
|
||
|
||
// 查询档案列表
|
||
profiles, err := service.GetUserProfiles(database.MustGetDB(), userID.(int64))
|
||
if err != nil {
|
||
loggerInstance.Error("获取档案列表失败",
|
||
zap.Int64("user_id", userID.(int64)),
|
||
zap.Error(err),
|
||
)
|
||
c.JSON(http.StatusInternalServerError, model.NewErrorResponse(
|
||
model.CodeServerError,
|
||
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))
|
||
}
|
||
|
||
// GetProfile 获取档案详情
|
||
// @Summary 获取档案详情
|
||
// @Description 根据UUID获取档案详细信息
|
||
// @Tags profile
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param uuid path string true "档案UUID"
|
||
// @Success 200 {object} model.Response "获取成功"
|
||
// @Failure 404 {object} model.ErrorResponse "档案不存在"
|
||
// @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("获取档案失败",
|
||
zap.String("uuid", uuid),
|
||
zap.Error(err),
|
||
)
|
||
c.JSON(http.StatusNotFound, model.NewErrorResponse(
|
||
model.CodeNotFound,
|
||
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,
|
||
}))
|
||
}
|
||
|
||
// UpdateProfile 更新档案
|
||
// @Summary 更新档案
|
||
// @Description 更新档案信息
|
||
// @Tags profile
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security BearerAuth
|
||
// @Param uuid path string true "档案UUID"
|
||
// @Param request body types.UpdateProfileRequest true "更新信息"
|
||
// @Success 200 {object} model.Response "更新成功"
|
||
// @Failure 400 {object} model.ErrorResponse "请求参数错误"
|
||
// @Failure 401 {object} model.ErrorResponse "未授权"
|
||
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
||
// @Failure 404 {object} model.ErrorResponse "档案不存在"
|
||
// @Failure 500 {object} model.ErrorResponse "服务器错误"
|
||
// @Router /api/v1/profile/{uuid} [put]
|
||
func UpdateProfile(c *gin.Context) {
|
||
loggerInstance := logger.MustGetLogger()
|
||
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,
|
||
))
|
||
return
|
||
}
|
||
|
||
// 更新档案
|
||
var namePtr *string
|
||
if req.Name != "" {
|
||
namePtr = &req.Name
|
||
}
|
||
|
||
profile, err := service.UpdateProfile(database.MustGetDB(), uuid, userID.(int64), namePtr, req.SkinID, req.CapeID)
|
||
if err != nil {
|
||
loggerInstance.Error("更新档案失败",
|
||
zap.String("uuid", uuid),
|
||
zap.Int64("user_id", userID.(int64)),
|
||
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,
|
||
))
|
||
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,
|
||
}))
|
||
}
|
||
|
||
// DeleteProfile 删除档案
|
||
// @Summary 删除档案
|
||
// @Description 删除指定的Minecraft档案
|
||
// @Tags profile
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security BearerAuth
|
||
// @Param uuid path string true "档案UUID"
|
||
// @Success 200 {object} model.Response "删除成功"
|
||
// @Failure 401 {object} model.ErrorResponse "未授权"
|
||
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
||
// @Failure 404 {object} model.ErrorResponse "档案不存在"
|
||
// @Failure 500 {object} model.ErrorResponse "服务器错误"
|
||
// @Router /api/v1/profile/{uuid} [delete]
|
||
func DeleteProfile(c *gin.Context) {
|
||
loggerInstance := logger.MustGetLogger()
|
||
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))
|
||
if err != nil {
|
||
loggerInstance.Error("删除档案失败",
|
||
zap.String("uuid", uuid),
|
||
zap.Int64("user_id", userID.(int64)),
|
||
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,
|
||
))
|
||
return
|
||
}
|
||
|
||
// 返回成功响应
|
||
c.JSON(http.StatusOK, model.NewSuccessResponse(gin.H{
|
||
"message": "删除成功",
|
||
}))
|
||
}
|
||
|
||
// SetActiveProfile 设置活跃档案
|
||
// @Summary 设置活跃档案
|
||
// @Description 将指定档案设置为活跃状态
|
||
// @Tags profile
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security BearerAuth
|
||
// @Param uuid path string true "档案UUID"
|
||
// @Success 200 {object} model.Response "设置成功"
|
||
// @Failure 401 {object} model.ErrorResponse "未授权"
|
||
// @Failure 403 {object} model.ErrorResponse "无权操作"
|
||
// @Failure 404 {object} model.ErrorResponse "档案不存在"
|
||
// @Failure 500 {object} model.ErrorResponse "服务器错误"
|
||
// @Router /api/v1/profile/{uuid}/activate [post]
|
||
func SetActiveProfile(c *gin.Context) {
|
||
loggerInstance := logger.MustGetLogger()
|
||
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))
|
||
if err != nil {
|
||
loggerInstance.Error("设置活跃档案失败",
|
||
zap.String("uuid", uuid),
|
||
zap.Int64("user_id", userID.(int64)),
|
||
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,
|
||
))
|
||
return
|
||
}
|
||
|
||
// 返回成功响应
|
||
c.JSON(http.StatusOK, model.NewSuccessResponse(gin.H{
|
||
"message": "设置成功",
|
||
}))
|
||
}
|