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,15 +1,13 @@
package handler
import (
"carrotskin/internal/model"
"carrotskin/internal/service"
"carrotskin/internal/types"
"carrotskin/pkg/auth"
"carrotskin/pkg/email"
"carrotskin/pkg/logger"
"carrotskin/pkg/redis"
"net/http"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
@@ -28,59 +26,32 @@ func Register(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
jwtService := auth.MustGetJWTService()
redisClient := redis.MustGetClient()
var req types.RegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
"请求参数错误",
err,
))
RespondBadRequest(c, "请求参数错误", err)
return
}
// 验证邮箱验证码
if err := service.VerifyCode(c.Request.Context(), redisClient, req.Email, req.VerificationCode, service.VerificationTypeRegister); err != nil {
loggerInstance.Warn("验证码验证失败",
zap.String("email", req.Email),
zap.Error(err),
)
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
err.Error(),
nil,
))
loggerInstance.Warn("验证码验证失败", zap.String("email", req.Email), zap.Error(err))
RespondBadRequest(c, err.Error(), nil)
return
}
// 调用service层注册用户传递可选的头像URL
// 注册用户
user, token, err := service.RegisterUser(jwtService, req.Username, req.Password, req.Email, req.Avatar)
if err != nil {
loggerInstance.Error("用户注册失败", zap.Error(err))
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
err.Error(),
nil,
))
RespondBadRequest(c, err.Error(), nil)
return
}
// 返回响应
c.JSON(http.StatusOK, model.NewSuccessResponse(&types.LoginResponse{
Token: token,
UserInfo: &types.UserInfo{
ID: user.ID,
Username: user.Username,
Email: user.Email,
Avatar: user.Avatar,
Points: user.Points,
Role: user.Role,
Status: user.Status,
LastLoginAt: user.LastLoginAt,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
},
}))
RespondSuccess(c, &types.LoginResponse{
Token: token,
UserInfo: UserToUserInfo(user),
})
}
// Login 用户登录
@@ -97,53 +68,32 @@ func Register(c *gin.Context) {
func Login(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
jwtService := auth.MustGetJWTService()
redisClient := redis.MustGetClient()
var req types.LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
"请求参数错误",
err,
))
RespondBadRequest(c, "请求参数错误", err)
return
}
// 获取IP和UserAgent
ipAddress := c.ClientIP()
userAgent := c.GetHeader("User-Agent")
// 调用service层登录
user, token, err := service.LoginUser(jwtService, req.Username, req.Password, ipAddress, userAgent)
user, token, err := service.LoginUserWithRateLimit(redisClient, jwtService, req.Username, req.Password, ipAddress, userAgent)
if err != nil {
loggerInstance.Warn("用户登录失败",
zap.String("username_or_email", req.Username),
zap.String("ip", ipAddress),
zap.Error(err),
)
c.JSON(http.StatusUnauthorized, model.NewErrorResponse(
model.CodeUnauthorized,
err.Error(),
nil,
))
RespondUnauthorized(c, err.Error())
return
}
// 返回响应
c.JSON(http.StatusOK, model.NewSuccessResponse(&types.LoginResponse{
Token: token,
UserInfo: &types.UserInfo{
ID: user.ID,
Username: user.Username,
Email: user.Email,
Avatar: user.Avatar,
Points: user.Points,
Role: user.Role,
Status: user.Status,
LastLoginAt: user.LastLoginAt,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
},
}))
RespondSuccess(c, &types.LoginResponse{
Token: token,
UserInfo: UserToUserInfo(user),
})
}
// SendVerificationCode 发送验证码
@@ -160,35 +110,24 @@ func SendVerificationCode(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
redisClient := redis.MustGetClient()
emailService := email.MustGetService()
var req types.SendVerificationCodeRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
"请求参数错误",
err,
))
RespondBadRequest(c, "请求参数错误", err)
return
}
// 发送验证码
if err := service.SendVerificationCode(c.Request.Context(), redisClient, emailService, req.Email, req.Type); err != nil {
loggerInstance.Error("发送验证码失败",
zap.String("email", req.Email),
zap.String("type", req.Type),
zap.Error(err),
)
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
err.Error(),
nil,
))
RespondBadRequest(c, err.Error(), nil)
return
}
c.JSON(http.StatusOK, model.NewSuccessResponse(gin.H{
"message": "验证码已发送,请查收邮件",
}))
RespondSuccess(c, gin.H{"message": "验证码已发送,请查收邮件"})
}
// ResetPassword 重置密码
@@ -204,46 +143,26 @@ func SendVerificationCode(c *gin.Context) {
func ResetPassword(c *gin.Context) {
loggerInstance := logger.MustGetLogger()
redisClient := redis.MustGetClient()
var req types.ResetPasswordRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
"请求参数错误",
err,
))
RespondBadRequest(c, "请求参数错误", err)
return
}
// 验证验证码
if err := service.VerifyCode(c.Request.Context(), redisClient, req.Email, req.VerificationCode, service.VerificationTypeResetPassword); err != nil {
loggerInstance.Warn("验证码验证失败",
zap.String("email", req.Email),
zap.Error(err),
)
c.JSON(http.StatusBadRequest, model.NewErrorResponse(
model.CodeBadRequest,
err.Error(),
nil,
))
loggerInstance.Warn("验证码验证失败", zap.String("email", req.Email), zap.Error(err))
RespondBadRequest(c, err.Error(), nil)
return
}
// 重置密码
if err := service.ResetUserPassword(req.Email, req.NewPassword); err != nil {
loggerInstance.Error("重置密码失败",
zap.String("email", req.Email),
zap.Error(err),
)
c.JSON(http.StatusInternalServerError, model.NewErrorResponse(
model.CodeServerError,
err.Error(),
nil,
))
loggerInstance.Error("重置密码失败", zap.String("email", req.Email), zap.Error(err))
RespondServerError(c, err.Error(), nil)
return
}
c.JSON(http.StatusOK, model.NewSuccessResponse(gin.H{
"message": "密码重置成功",
}))
RespondSuccess(c, gin.H{"message": "密码重置成功"})
}