Files
ai_dianshang/server/internal/handler/user.go
2025-11-28 15:18:10 +08:00

572 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handler
import (
"dianshang/internal/config"
"dianshang/internal/model"
"dianshang/internal/repository"
"dianshang/internal/service"
"dianshang/pkg/response"
"dianshang/pkg/utils"
"strconv"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// UserHandler 用户处理器
type UserHandler struct {
userService *service.UserService
wechatService *service.WeChatService
}
// NewUserHandler 创建用户处理器
func NewUserHandler(db *gorm.DB, cfg *config.Config) *UserHandler {
// 创建积分相关服务
pointsRepo := repository.NewPointsRepository(db)
pointsService := service.NewPointsService(pointsRepo, db)
return &UserHandler{
userService: service.NewUserService(db),
wechatService: service.NewWeChatService(db, pointsService, cfg.WeChat.AppID, cfg.WeChat.AppSecret),
}
}
// LoginRequest 登录请求结构
type LoginRequest struct {
Code string `json:"code" binding:"required"`
}
// EmailLoginRequest 邮箱登录请求结构
type EmailLoginRequest struct {
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=6"`
}
// EmailRegisterRequest 邮箱注册请求结构
type EmailRegisterRequest struct {
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=6"`
Nickname string `json:"nickname" binding:"required"`
}
// WeChatLoginRequest 微信登录请求结构
type WeChatLoginRequest struct {
Code string `json:"code" binding:"required"`
UserInfo *service.WeChatUserInfo `json:"userInfo,omitempty"`
}
// Login 用户登录(兼容旧版本)
func (h *UserHandler) Login(c *gin.Context) {
var req LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误")
return
}
// 获取客户端IP和UserAgent
clientIP := utils.GetClientIP(
c.ClientIP(),
c.GetHeader("X-Forwarded-For"),
c.GetHeader("X-Real-IP"),
)
userAgent := c.Request.UserAgent()
// 调用新的微信登录服务
user, token, err := h.wechatService.Login(req.Code, clientIP, userAgent)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, gin.H{
"user": user,
"token": token,
})
}
// WeChatLogin 微信登录
func (h *UserHandler) WeChatLogin(c *gin.Context) {
var req WeChatLoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误: "+err.Error())
return
}
// 验证必要参数
if req.Code == "" {
response.BadRequest(c, "微信登录code不能为空")
return
}
// 获取客户端IP和UserAgent
clientIP := utils.GetClientIP(
c.ClientIP(),
c.GetHeader("X-Forwarded-For"),
c.GetHeader("X-Real-IP"),
)
userAgent := c.Request.UserAgent()
var user *model.User
var token string
var err error
if req.UserInfo != nil {
// 带用户信息的登录
user, token, err = h.wechatService.LoginWithUserInfo(req.Code, *req.UserInfo, clientIP, userAgent)
} else {
// 基本登录
user, token, err = h.wechatService.Login(req.Code, clientIP, userAgent)
}
if err != nil {
// 根据错误类型返回不同的错误码
if err.Error() == "用户已被禁用,请联系客服" {
response.ErrorWithMessage(c, response.ERROR_USER_DISABLED, err.Error())
} else {
response.ErrorWithMessage(c, response.ERROR, err.Error())
}
return
}
// 确保用户信息完整
if user == nil {
response.ErrorWithMessage(c, response.ERROR, "用户信息获取失败")
return
}
response.Success(c, gin.H{
"user": user,
"token": token,
"message": "登录成功",
})
}
// EmailLogin 邮箱登录Web端使用
func (h *UserHandler) EmailLogin(c *gin.Context) {
var req EmailLoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误")
return
}
// 获取客户端IP和UserAgent
clientIP := utils.GetClientIP(
c.ClientIP(),
c.GetHeader("X-Forwarded-For"),
c.GetHeader("X-Real-IP"),
)
userAgent := c.Request.UserAgent()
// 调用用户服务进行邮箱登录
user, token, err := h.userService.EmailLogin(req.Email, req.Password, clientIP, userAgent)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, gin.H{
"user": user,
"token": token,
})
}
// EmailRegister 邮箱注册Web端使用
func (h *UserHandler) EmailRegister(c *gin.Context) {
var req EmailRegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误")
return
}
// 调用用户服务进行注册
user, err := h.userService.EmailRegister(req.Email, req.Password, req.Nickname)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, gin.H{
"user_id": user.ID,
"message": "注册成功",
})
}
// GetWeChatSession 获取微信会话信息
func (h *UserHandler) GetWeChatSession(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
session, err := h.wechatService.GetUserSession(userID.(uint))
if err != nil {
response.ErrorWithMessage(c, response.ERROR, "获取会话信息失败")
return
}
response.Success(c, session)
}
// RegisterRequest 注册请求结构
type RegisterRequest struct {
OpenID string `json:"openid" binding:"required"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Gender uint8 `json:"gender"`
}
// Register 用户注册
func (h *UserHandler) Register(c *gin.Context) {
var req RegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误")
return
}
user := &model.User{
OpenID: req.OpenID,
Nickname: req.Nickname,
Avatar: req.Avatar,
Gender: int(req.Gender),
}
if err := h.userService.CreateUser(user); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, user)
}
// GetProfile 获取用户信息
func (h *UserHandler) GetProfile(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
user, err := h.userService.GetUserByID(userID.(uint))
if err != nil {
response.ErrorWithMessage(c, response.ERROR_USER_NOT_FOUND, "用户不存在")
return
}
response.Success(c, user)
}
// UpdateProfileRequest 更新用户信息请求结构
type UpdateProfileRequest struct {
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Gender uint8 `json:"gender"`
Phone string `json:"phone"`
Email string `json:"email"`
}
// UpdateProfile 更新用户信息
func (h *UserHandler) UpdateProfile(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
// 获取原始JSON数据来判断哪些字段被明确提供
var rawData map[string]interface{}
if err := c.ShouldBindJSON(&rawData); err != nil {
response.BadRequest(c, "参数错误")
return
}
// 只更新明确提供的字段
updates := make(map[string]interface{})
// 检查每个字段是否在请求中被明确提供,并转换为正确的类型
if nickname, exists := rawData["nickname"]; exists {
if str, ok := nickname.(string); ok {
updates["nickname"] = str
}
}
if avatar, exists := rawData["avatar"]; exists {
if str, ok := avatar.(string); ok {
updates["avatar"] = str
}
}
if gender, exists := rawData["gender"]; exists {
if num, ok := gender.(float64); ok {
updates["gender"] = uint8(num)
}
}
if phone, exists := rawData["phone"]; exists {
if str, ok := phone.(string); ok {
updates["phone"] = str
}
}
if email, exists := rawData["email"]; exists {
if str, ok := email.(string); ok {
updates["email"] = str
}
}
// 如果没有任何字段需要更新,返回成功
if len(updates) == 0 {
response.Success(c, nil)
return
}
if err := h.userService.UpdateUser(userID.(uint), updates); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// GetFavorites 获取用户收藏列表
func (h *UserHandler) GetFavorites(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
favorites, total, err := h.userService.GetFavorites(userID.(uint), page, limit)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, gin.H{
"list": favorites,
"total": total,
"page": page,
"limit": limit,
})
}
// AddToFavorite 添加收藏
func (h *UserHandler) AddToFavorite(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
productID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
response.BadRequest(c, "商品ID无效")
return
}
if err := h.userService.AddToFavorite(userID.(uint), uint(productID)); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// RemoveFromFavorite 取消收藏
func (h *UserHandler) RemoveFromFavorite(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
productID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
response.BadRequest(c, "商品ID无效")
return
}
if err := h.userService.RemoveFromFavorite(userID.(uint), uint(productID)); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// GetFavoriteStatus 获取收藏状态
func (h *UserHandler) GetFavoriteStatus(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
productID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
response.BadRequest(c, "商品ID无效")
return
}
isFavorite := h.userService.IsFavorite(userID.(uint), uint(productID))
response.Success(c, gin.H{
"is_favorite": isFavorite,
})
}
// GetAddresses 获取用户地址列表
func (h *UserHandler) GetAddresses(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
addresses, err := h.userService.GetUserAddresses(userID.(uint))
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, addresses)
}
// CreateAddressRequest 创建地址请求结构
type CreateAddressRequest struct {
Name string `json:"name" binding:"required"`
Phone string `json:"phone" binding:"required"`
Province string `json:"province" binding:"required"`
City string `json:"city" binding:"required"`
District string `json:"district" binding:"required"`
Detail string `json:"detail" binding:"required"`
IsDefault uint8 `json:"is_default"`
}
// CreateAddress 创建用户地址
func (h *UserHandler) CreateAddress(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
var req CreateAddressRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误")
return
}
address := &model.UserAddress{
UserID: userID.(uint),
Name: req.Name,
Phone: req.Phone,
ProvinceName: req.Province,
CityName: req.City,
DistrictName: req.District,
DetailAddress: req.Detail,
IsDefault: req.IsDefault == 1,
}
if err := h.userService.CreateAddress(address); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, address)
}
// UpdateAddress 更新用户地址
func (h *UserHandler) UpdateAddress(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
addressID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
response.BadRequest(c, "地址ID无效")
return
}
var req CreateAddressRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误")
return
}
updates := map[string]interface{}{
"name": req.Name,
"phone": req.Phone,
"province_name": req.Province,
"city_name": req.City,
"district_name": req.District,
"detail_address": req.Detail,
"is_default": req.IsDefault,
}
if err := h.userService.UpdateAddress(userID.(uint), uint(addressID), updates); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
// 获取更新后的地址数据并返回
updatedAddress := &model.UserAddress{
ID: uint(addressID),
UserID: userID.(uint),
Name: req.Name,
Phone: req.Phone,
ProvinceName: req.Province,
CityName: req.City,
DistrictName: req.District,
DetailAddress: req.Detail,
IsDefault: req.IsDefault == 1,
}
response.Success(c, updatedAddress)
}
// DeleteAddress 删除用户地址
func (h *UserHandler) DeleteAddress(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
addressID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
response.BadRequest(c, "地址ID无效")
return
}
if err := h.userService.DeleteAddress(userID.(uint), uint(addressID)); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// SetDefaultAddress 设置默认地址
func (h *UserHandler) SetDefaultAddress(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
addressID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
response.BadRequest(c, "地址ID无效")
return
}
if err := h.userService.SetDefaultAddress(userID.(uint), uint(addressID)); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}