Files

540 lines
13 KiB
Go
Raw Permalink Normal View History

2025-11-17 14:11:46 +08:00
package handler
import (
"dianshang/internal/service"
"dianshang/pkg/response"
"dianshang/pkg/utils"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
// CartHandler 购物车处理器
type CartHandler struct {
cartService *service.CartService
}
// NewCartHandler 创建购物车处理器
func NewCartHandler(cartService *service.CartService) *CartHandler {
return &CartHandler{
cartService: cartService,
}
}
// GetCart 获取购物车
func (h *CartHandler) GetCart(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
cart, err := h.cartService.GetCart(userID.(uint))
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
2025-11-28 15:18:10 +08:00
// 优化: 在一次查询结果基础上计算统计信息,避免重复查询
var count int
var total float64
for _, item := range cart {
count += item.Quantity
if item.Product.ID != 0 {
// 将价格从分转换为元
total += (float64(item.Product.Price) / 100) * float64(item.Quantity)
}
}
2025-11-17 14:11:46 +08:00
result := map[string]interface{}{
"items": cart,
"count": count,
"total": fmt.Sprintf("%.2f", total),
}
response.Success(c, result)
}
// AddToCart 添加到购物车
func (h *CartHandler) AddToCart(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
var req struct {
ProductID uint `json:"product_id" binding:"required"`
SKUID uint `json:"sku_id"`
Quantity uint `json:"quantity" binding:"required,min=1"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误: "+err.Error())
return
}
if err := h.cartService.AddToCart(userID.(uint), req.ProductID, req.SKUID, int(req.Quantity)); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// UpdateCartItem 更新购物车项
func (h *CartHandler) UpdateCartItem(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
productIDStr := c.Param("product_id")
productID := utils.StringToUint(productIDStr)
if productID == 0 {
response.BadRequest(c, "无效的产品ID")
return
}
var req struct {
Quantity uint `json:"quantity" binding:"required"`
SKUID uint `json:"sku_id"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误: "+err.Error())
return
}
// 添加调试日志
fmt.Printf("🔍 [UpdateCartItem] 用户ID: %d, 产品ID: %d, SKU ID: %d, 数量: %d\n",
userID.(uint), productID, req.SKUID, req.Quantity)
if err := h.cartService.UpdateCartItemBySKU(userID.(uint), productID, req.SKUID, int(req.Quantity)); err != nil {
fmt.Printf("❌ [UpdateCartItem] 服务层错误: %v\n", err)
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// RemoveFromCart 从购物车移除
func (h *CartHandler) RemoveFromCart(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
productIDStr := c.Param("product_id")
productID := utils.StringToUint(productIDStr)
if productID == 0 {
response.BadRequest(c, "无效的产品ID")
return
}
// 从查询参数获取sku_id
skuIDStr := c.Query("sku_id")
skuID := utils.StringToUint(skuIDStr)
if err := h.cartService.RemoveFromCartBySKU(userID.(uint), productID, skuID); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// ClearCart 清空购物车
func (h *CartHandler) ClearCart(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
if err := h.cartService.ClearCart(userID.(uint)); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// GetCartCount 获取购物车商品数量
func (h *CartHandler) GetCartCount(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
count, err := h.cartService.GetCartCount(userID.(uint))
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, map[string]interface{}{"count": count})
}
// SelectCartItem 选择/取消选择购物车项
func (h *CartHandler) SelectCartItem(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
cartIDStr := c.Param("id")
cartID := utils.StringToUint(cartIDStr)
if cartID == 0 {
response.BadRequest(c, "无效的购物车ID")
return
}
var req struct {
Selected bool `json:"selected"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误: "+err.Error())
return
}
if err := h.cartService.SelectCartItem(userID.(uint), cartID, req.Selected); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// SelectAllCartItems 全选/取消全选购物车
func (h *CartHandler) SelectAllCartItems(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
var req struct {
Selected bool `json:"selected"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "参数错误: "+err.Error())
return
}
if err := h.cartService.SelectAllCartItems(userID.(uint), req.Selected); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// BatchAddToCartRequest 批量添加到购物车请求
type BatchAddToCartRequest struct {
Items []struct {
ProductID uint `json:"product_id" binding:"required"`
SKUID uint `json:"sku_id"`
Quantity int `json:"quantity" binding:"required,min=1"`
} `json:"items" binding:"required"`
}
// BatchAddToCart 批量添加到购物车
func (h *CartHandler) BatchAddToCart(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
var req BatchAddToCartRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 转换请求参数类型
items := make([]struct {
ProductID uint `json:"product_id"`
SKUID uint `json:"sku_id"`
Quantity int `json:"quantity"`
}, len(req.Items))
for i, item := range req.Items {
items[i] = struct {
ProductID uint `json:"product_id"`
SKUID uint `json:"sku_id"`
Quantity int `json:"quantity"`
}{
ProductID: item.ProductID,
SKUID: item.SKUID,
Quantity: item.Quantity,
}
}
err := h.cartService.BatchAddToCart(userID.(uint), items)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "批量添加成功"})
}
// BatchRemoveFromCartRequest 批量移除购物车请求
type BatchRemoveFromCartRequest struct {
CartIDs []uint `json:"cart_ids" binding:"required"`
}
// BatchRemoveFromCart 批量从购物车移除
func (h *CartHandler) BatchRemoveFromCart(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
var req BatchRemoveFromCartRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err := h.cartService.BatchRemoveFromCart(userID.(uint), req.CartIDs)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "批量删除成功"})
}
// BatchUpdateCartItemsRequest 批量更新购物车项请求
type BatchUpdateCartItemsRequest struct {
Updates []struct {
CartID uint `json:"cart_id" binding:"required"`
Quantity int `json:"quantity" binding:"min=0"`
} `json:"updates" binding:"required"`
}
// BatchUpdateCartItems 批量更新购物车项
func (h *CartHandler) BatchUpdateCartItems(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
var req BatchUpdateCartItemsRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 转换请求参数类型
updates := make([]struct {
CartID uint `json:"cart_id"`
Quantity int `json:"quantity"`
}, len(req.Updates))
for i, update := range req.Updates {
updates[i] = struct {
CartID uint `json:"cart_id"`
Quantity int `json:"quantity"`
}{
CartID: update.CartID,
Quantity: update.Quantity,
}
}
err := h.cartService.BatchUpdateCartItems(userID.(uint), updates)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "批量更新成功"})
}
// GetCartWithDetails 获取购物车详细信息
func (h *CartHandler) GetCartWithDetails(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
details, err := h.cartService.GetCartWithDetails(userID.(uint))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"data": details,
})
}
// ValidateCartItems 验证购物车商品有效性
func (h *CartHandler) ValidateCartItems(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
validation, err := h.cartService.ValidateCartItems(userID.(uint))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"data": validation,
})
}
// CleanInvalidCartItems 清理无效的购物车项
func (h *CartHandler) CleanInvalidCartItems(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
err := h.cartService.CleanInvalidCartItems(userID.(uint))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "清理完成"})
}
// GetCartSummary 获取购物车摘要信息
func (h *CartHandler) GetCartSummary(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
summary, err := h.cartService.GetCartSummary(userID.(uint))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"data": summary,
})
}
// MergeCartRequest 合并购物车请求
type MergeCartRequest struct {
GuestCartItems []struct {
ProductID uint `json:"product_id" binding:"required"`
SKUID uint `json:"sku_id"`
Quantity int `json:"quantity" binding:"required,min=1"`
} `json:"guest_cart_items" binding:"required"`
}
// MergeCart 合并购物车
func (h *CartHandler) MergeCart(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
var req MergeCartRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 转换请求参数类型
guestCartItems := make([]struct {
ProductID uint `json:"product_id"`
SKUID uint `json:"sku_id"`
Quantity int `json:"quantity"`
}, len(req.GuestCartItems))
for i, item := range req.GuestCartItems {
guestCartItems[i] = struct {
ProductID uint `json:"product_id"`
SKUID uint `json:"sku_id"`
Quantity int `json:"quantity"`
}{
ProductID: item.ProductID,
SKUID: item.SKUID,
Quantity: item.Quantity,
}
}
err := h.cartService.MergeCart(userID.(uint), guestCartItems)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "购物车合并成功"})
}
// GetSelectedCartItems 获取选中的购物车项
func (h *CartHandler) GetSelectedCartItems(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
items, err := h.cartService.GetSelectedCartItems(userID.(uint))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"data": items,
})
}
// CalculateCartDiscountRequest 计算购物车优惠请求
type CalculateCartDiscountRequest struct {
CouponID uint `json:"coupon_id"`
}
// CalculateCartDiscount 计算购物车优惠
func (h *CartHandler) CalculateCartDiscount(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
return
}
var req CalculateCartDiscountRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
discount, err := h.cartService.CalculateCartDiscount(userID.(uint), req.CouponID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"data": discount,
})
}