Files
2025-11-17 13:32:54 +08:00

509 lines
12 KiB
Go

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"`
}
// 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": "登录成功",
})
}
// 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)
}