package handler import ( "carrotskin/internal/container" "carrotskin/internal/service" "carrotskin/internal/types" "github.com/gin-gonic/gin" "go.uber.org/zap" ) // UserHandler 用户处理器(依赖注入版本) type UserHandler struct { container *container.Container logger *zap.Logger } // NewUserHandler 创建UserHandler实例 func NewUserHandler(c *container.Container) *UserHandler { return &UserHandler{ container: c, logger: c.Logger, } } // GetProfile 获取用户信息 func (h *UserHandler) GetProfile(c *gin.Context) { userID, ok := GetUserIDFromContext(c) if !ok { return } user, err := h.container.UserService.GetByID(c.Request.Context(), userID) if err != nil || user == nil { h.logger.Error("获取用户信息失败", zap.Int64("user_id", userID), zap.Error(err), ) RespondNotFound(c, "用户不存在") return } RespondSuccess(c, UserToUserInfo(user)) } // UpdateProfile 更新用户信息 func (h *UserHandler) UpdateProfile(c *gin.Context) { userID, ok := GetUserIDFromContext(c) if !ok { return } var req types.UpdateUserRequest if err := c.ShouldBindJSON(&req); err != nil { RespondBadRequest(c, "请求参数错误", err) return } user, err := h.container.UserService.GetByID(c.Request.Context(), userID) if err != nil || user == nil { RespondNotFound(c, "用户不存在") return } // 处理密码修改 if req.NewPassword != "" { if req.OldPassword == "" { RespondBadRequest(c, "修改密码需要提供原密码", nil) return } if err := h.container.UserService.ChangePassword(c.Request.Context(), userID, req.OldPassword, req.NewPassword); err != nil { h.logger.Error("修改密码失败", zap.Int64("user_id", userID), zap.Error(err)) RespondBadRequest(c, err.Error(), nil) return } h.logger.Info("用户修改密码成功", zap.Int64("user_id", userID)) } // 更新头像 if req.Avatar != "" { if err := h.container.UserService.ValidateAvatarURL(c.Request.Context(), req.Avatar); err != nil { RespondBadRequest(c, err.Error(), nil) return } user.Avatar = req.Avatar if err := h.container.UserService.UpdateInfo(c.Request.Context(), user); err != nil { h.logger.Error("更新用户信息失败", zap.Int64("user_id", user.ID), zap.Error(err)) RespondServerError(c, "更新失败", err) return } } // 重新获取更新后的用户信息 updatedUser, err := h.container.UserService.GetByID(c.Request.Context(), userID) if err != nil || updatedUser == nil { RespondNotFound(c, "用户不存在") return } RespondSuccess(c, UserToUserInfo(updatedUser)) } // GenerateAvatarUploadURL 生成头像上传URL func (h *UserHandler) GenerateAvatarUploadURL(c *gin.Context) { userID, ok := GetUserIDFromContext(c) if !ok { return } var req types.GenerateAvatarUploadURLRequest if err := c.ShouldBindJSON(&req); err != nil { RespondBadRequest(c, "请求参数错误", err) return } if h.container.Storage == nil { RespondServerError(c, "存储服务不可用", nil) return } result, err := h.container.UploadService.GenerateAvatarUploadURL(c.Request.Context(), userID, req.FileName) if err != nil { h.logger.Error("生成头像上传URL失败", zap.Int64("user_id", userID), zap.String("file_name", req.FileName), zap.Error(err), ) RespondBadRequest(c, err.Error(), nil) return } RespondSuccess(c, &types.GenerateAvatarUploadURLResponse{ PostURL: result.PostURL, FormData: result.FormData, AvatarURL: result.FileURL, ExpiresIn: 900, }) } // UpdateAvatar 更新头像URL func (h *UserHandler) UpdateAvatar(c *gin.Context) { userID, ok := GetUserIDFromContext(c) if !ok { return } avatarURL := c.Query("avatar_url") if avatarURL == "" { RespondBadRequest(c, "头像URL不能为空", nil) return } if err := h.container.UserService.ValidateAvatarURL(c.Request.Context(), avatarURL); err != nil { RespondBadRequest(c, err.Error(), nil) return } if err := h.container.UserService.UpdateAvatar(c.Request.Context(), userID, avatarURL); err != nil { h.logger.Error("更新头像失败", zap.Int64("user_id", userID), zap.String("avatar_url", avatarURL), zap.Error(err), ) RespondServerError(c, "更新头像失败", err) return } user, err := h.container.UserService.GetByID(c.Request.Context(), userID) if err != nil || user == nil { RespondNotFound(c, "用户不存在") return } RespondSuccess(c, UserToUserInfo(user)) } // ChangeEmail 更换邮箱 func (h *UserHandler) ChangeEmail(c *gin.Context) { userID, ok := GetUserIDFromContext(c) if !ok { return } var req types.ChangeEmailRequest if err := c.ShouldBindJSON(&req); err != nil { RespondBadRequest(c, "请求参数错误", err) return } if err := h.container.VerificationService.VerifyCode(c.Request.Context(), req.NewEmail, req.VerificationCode, service.VerificationTypeChangeEmail); err != nil { h.logger.Warn("验证码验证失败", zap.String("new_email", req.NewEmail), zap.Error(err)) RespondBadRequest(c, err.Error(), nil) return } if err := h.container.UserService.ChangeEmail(c.Request.Context(), userID, req.NewEmail); err != nil { h.logger.Error("更换邮箱失败", zap.Int64("user_id", userID), zap.String("new_email", req.NewEmail), zap.Error(err), ) RespondBadRequest(c, err.Error(), nil) return } user, err := h.container.UserService.GetByID(c.Request.Context(), userID) if err != nil || user == nil { RespondNotFound(c, "用户不存在") return } RespondSuccess(c, UserToUserInfo(user)) } // ResetYggdrasilPassword 重置Yggdrasil密码 func (h *UserHandler) ResetYggdrasilPassword(c *gin.Context) { userID, ok := GetUserIDFromContext(c) if !ok { return } newPassword, err := h.container.YggdrasilService.ResetYggdrasilPassword(c.Request.Context(), userID) if err != nil { h.logger.Error("重置Yggdrasil密码失败", zap.Error(err), zap.Int64("userId", userID)) RespondServerError(c, "重置Yggdrasil密码失败", nil) return } h.logger.Info("Yggdrasil密码重置成功", zap.Int64("userId", userID)) RespondSuccess(c, gin.H{"password": newPassword}) }