Files

661 lines
16 KiB
Go
Raw Permalink Normal View History

2025-11-17 13:32:54 +08:00
package service
import (
"dianshang/internal/model"
"dianshang/internal/repository"
"errors"
"fmt"
"time"
"gorm.io/gorm"
)
// CartService 购物车服务
type CartService struct {
orderRepo *repository.OrderRepository
productRepo *repository.ProductRepository
userRepo *repository.UserRepository
}
// NewCartService 创建购物车服务
func NewCartService(orderRepo *repository.OrderRepository, productRepo *repository.ProductRepository, userRepo *repository.UserRepository) *CartService {
return &CartService{
orderRepo: orderRepo,
productRepo: productRepo,
userRepo: userRepo,
}
}
// GetCart 获取购物车
func (s *CartService) GetCart(userID uint) ([]model.Cart, error) {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return nil, errors.New("用户不存在")
}
return s.orderRepo.GetCart(userID)
}
// AddToCart 添加到购物车
func (s *CartService) AddToCart(userID, productID uint, skuID uint, quantity int) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
// 检查产品是否存在
product, err := s.productRepo.GetByID(productID)
if err != nil {
return errors.New("产品不存在")
}
// 检查产品状态
if product.Status != 1 {
return errors.New("产品已下架")
}
// 检查库存
if product.Stock < quantity {
return errors.New("库存不足")
}
// 检查购物车中是否已存在该商品包括SKU
existingCart, err := s.orderRepo.GetCartItemBySKU(userID, productID, skuID)
if err == nil && existingCart != nil {
// 已存在,更新数量
newQuantity := existingCart.Quantity + quantity
if product.Stock < newQuantity {
return errors.New("库存不足")
}
return s.orderRepo.UpdateCartItem(existingCart.ID, newQuantity)
}
// 如果不是记录不存在的错误,返回错误
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
// 不存在,添加新项
var skuPtr *uint
if skuID != 0 {
skuPtr = &skuID
}
cart := &model.Cart{
UserID: userID,
ProductID: productID,
SKUID: skuPtr,
Quantity: quantity,
Selected: true,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
return s.orderRepo.AddToCart(cart)
}
// UpdateCartItem 更新购物车项
func (s *CartService) UpdateCartItem(userID, productID uint, quantity int) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
// 获取该用户该产品的所有购物车项
cartItems, err := s.orderRepo.GetCart(userID)
if err != nil {
return errors.New("获取购物车失败")
}
// 查找匹配的购物车项
var targetCartItem *model.Cart
for _, item := range cartItems {
if item.ProductID == productID {
targetCartItem = &item
break
}
}
if targetCartItem == nil {
return errors.New("购物车项不存在")
}
if quantity == 0 {
// 数量为0删除该项
return s.orderRepo.RemoveFromCart(userID, productID)
}
// 检查产品库存
product, err := s.productRepo.GetByID(productID)
if err != nil {
return errors.New("产品不存在")
}
if product.Stock < quantity {
return errors.New("库存不足")
}
return s.orderRepo.UpdateCartItem(targetCartItem.ID, quantity)
}
// UpdateCartItemBySKU 基于SKU更新购物车项
func (s *CartService) UpdateCartItemBySKU(userID, productID, skuID uint, quantity int) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
// 使用SKU查找购物车项
cartItem, err := s.orderRepo.GetCartItemBySKU(userID, productID, skuID)
if err != nil {
return errors.New("购物车项不存在")
}
if quantity == 0 {
// 数量为0删除该项
return s.orderRepo.RemoveFromCartBySKU(userID, productID, skuID)
}
// 检查产品库存
product, err := s.productRepo.GetByID(productID)
if err != nil {
return errors.New("产品不存在")
}
if product.Stock < quantity {
return errors.New("库存不足")
}
return s.orderRepo.UpdateCartItem(cartItem.ID, quantity)
}
// RemoveFromCart 从购物车移除
func (s *CartService) RemoveFromCart(userID, productID uint) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
// 获取该用户该产品的所有购物车项
cartItems, err := s.orderRepo.GetCart(userID)
if err != nil {
return errors.New("获取购物车失败")
}
// 查找匹配的购物车项
var found bool
for _, item := range cartItems {
if item.ProductID == productID {
found = true
break
}
}
if !found {
return errors.New("购物车项不存在")
}
return s.orderRepo.RemoveFromCart(userID, productID)
}
// RemoveFromCartBySKU 基于SKU从购物车移除
func (s *CartService) RemoveFromCartBySKU(userID, productID, skuID uint) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
// 使用SKU查找购物车项
_, err = s.orderRepo.GetCartItemBySKU(userID, productID, skuID)
if err != nil {
return errors.New("购物车项不存在")
}
return s.orderRepo.RemoveFromCartBySKU(userID, productID, skuID)
}
// ClearCart 清空购物车
func (s *CartService) ClearCart(userID uint) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
return s.orderRepo.ClearCart(userID)
}
// GetCartCount 获取购物车商品数量
func (s *CartService) GetCartCount(userID uint) (int, error) {
cart, err := s.GetCart(userID)
if err != nil {
return 0, err
}
var count int
for _, item := range cart {
count += int(item.Quantity)
}
return count, nil
}
// GetCartTotal 获取购物车总金额
func (s *CartService) GetCartTotal(userID uint) (float64, error) {
cart, err := s.GetCart(userID)
if err != nil {
return 0, err
}
var total float64
for _, item := range cart {
if item.Product.ID != 0 {
// 将价格从分转换为元
total += (float64(item.Product.Price) / 100) * float64(item.Quantity)
}
}
return total, nil
}
// SelectCartItem 选择/取消选择购物车项
func (s *CartService) SelectCartItem(userID, cartID uint, selected bool) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
return s.orderRepo.SelectCartItem(userID, cartID, selected)
}
// SelectAllCartItems 全选/取消全选购物车
func (s *CartService) SelectAllCartItems(userID uint, selected bool) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
return s.orderRepo.SelectAllCartItems(userID, selected)
}
// BatchAddToCart 批量添加到购物车
func (s *CartService) BatchAddToCart(userID uint, items []struct {
ProductID uint `json:"product_id"`
SKUID uint `json:"sku_id"`
Quantity int `json:"quantity"`
}) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
// 验证所有商品
for _, item := range items {
product, err := s.productRepo.GetByID(item.ProductID)
if err != nil {
return errors.New("商品不存在: " + err.Error())
}
if product.Status != 1 {
return errors.New("商品已下架")
}
if product.Stock < item.Quantity {
return errors.New("商品库存不足")
}
}
// 批量添加
for _, item := range items {
err := s.AddToCart(userID, item.ProductID, item.SKUID, item.Quantity)
if err != nil {
return err
}
}
return nil
}
// BatchRemoveFromCart 批量从购物车移除
func (s *CartService) BatchRemoveFromCart(userID uint, cartIDs []uint) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
return s.orderRepo.BatchRemoveFromCart(userID, cartIDs)
}
// BatchUpdateCartItems 批量更新购物车项
func (s *CartService) BatchUpdateCartItems(userID uint, updates []struct {
CartID uint `json:"cart_id"`
Quantity int `json:"quantity"`
}) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
// 获取购物车项并验证
for _, update := range updates {
cartItem, err := s.orderRepo.GetCartItem(userID, update.CartID)
if err != nil {
return errors.New("购物车项不存在")
}
// 检查库存
product, err := s.productRepo.GetByID(cartItem.ProductID)
if err != nil {
return errors.New("商品不存在")
}
if product.Stock < update.Quantity {
return errors.New("商品库存不足")
}
// 更新数量
if update.Quantity == 0 {
err = s.orderRepo.RemoveCartItem(update.CartID)
} else {
err = s.orderRepo.UpdateCartItem(update.CartID, update.Quantity)
}
if err != nil {
return err
}
}
return nil
}
// GetCartWithDetails 获取购物车详细信息(包含商品详情)
func (s *CartService) GetCartWithDetails(userID uint) (map[string]interface{}, error) {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return nil, errors.New("用户不存在")
}
cart, err := s.orderRepo.GetCart(userID)
if err != nil {
return nil, err
}
var validItems []model.Cart
var invalidItems []model.Cart
var totalAmount float64
var totalQuantity int
var selectedAmount float64
var selectedQuantity int
for _, item := range cart {
// 检查商品是否有效
product, err := s.productRepo.GetByID(item.ProductID)
if err != nil || product.Status != 1 {
invalidItems = append(invalidItems, item)
continue
}
// 检查库存
if product.Stock < item.Quantity {
item.Product = *product
invalidItems = append(invalidItems, item)
continue
}
// 计算价格
item.Product = *product
itemPrice := float64(product.Price) / 100 * float64(item.Quantity)
totalAmount += itemPrice
totalQuantity += item.Quantity
if item.Selected {
selectedAmount += itemPrice
selectedQuantity += item.Quantity
}
validItems = append(validItems, item)
}
return map[string]interface{}{
"valid_items": validItems,
"invalid_items": invalidItems,
"total_amount": totalAmount,
"total_quantity": totalQuantity,
"selected_amount": selectedAmount,
"selected_quantity": selectedQuantity,
"valid_count": len(validItems),
"invalid_count": len(invalidItems),
}, nil
}
// ValidateCartItems 验证购物车商品有效性
func (s *CartService) ValidateCartItems(userID uint) (map[string]interface{}, error) {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return nil, errors.New("用户不存在")
}
cart, err := s.orderRepo.GetCart(userID)
if err != nil {
return nil, err
}
var validItems []uint
var invalidItems []struct {
CartID uint `json:"cart_id"`
Reason string `json:"reason"`
}
for _, item := range cart {
// 检查商品是否存在
product, err := s.productRepo.GetByID(item.ProductID)
if err != nil {
invalidItems = append(invalidItems, struct {
CartID uint `json:"cart_id"`
Reason string `json:"reason"`
}{
CartID: item.ID,
Reason: "商品不存在",
})
continue
}
// 检查商品状态
if product.Status != 1 {
invalidItems = append(invalidItems, struct {
CartID uint `json:"cart_id"`
Reason string `json:"reason"`
}{
CartID: item.ID,
Reason: "商品已下架",
})
continue
}
// 检查库存
if product.Stock < item.Quantity {
invalidItems = append(invalidItems, struct {
CartID uint `json:"cart_id"`
Reason string `json:"reason"`
}{
CartID: item.ID,
Reason: "库存不足",
})
continue
}
validItems = append(validItems, item.ID)
}
return map[string]interface{}{
"valid_items": validItems,
"invalid_items": invalidItems,
"valid_count": len(validItems),
"invalid_count": len(invalidItems),
}, nil
}
// CleanInvalidCartItems 清理无效的购物车项
func (s *CartService) CleanInvalidCartItems(userID uint) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
validation, err := s.ValidateCartItems(userID)
if err != nil {
return err
}
invalidItems := validation["invalid_items"].([]struct {
CartID uint `json:"cart_id"`
Reason string `json:"reason"`
})
if len(invalidItems) == 0 {
return nil
}
var cartIDs []uint
for _, item := range invalidItems {
cartIDs = append(cartIDs, item.CartID)
}
return s.orderRepo.BatchRemoveFromCart(userID, cartIDs)
}
// GetCartSummary 获取购物车摘要信息
func (s *CartService) GetCartSummary(userID uint) (map[string]interface{}, error) {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return nil, errors.New("用户不存在")
}
details, err := s.GetCartWithDetails(userID)
if err != nil {
return nil, err
}
return map[string]interface{}{
"total_items": details["valid_count"].(int) + details["invalid_count"].(int),
"valid_items": details["valid_count"],
"invalid_items": details["invalid_count"],
"total_amount": details["total_amount"],
"selected_amount": details["selected_amount"],
"total_quantity": details["total_quantity"],
"selected_quantity": details["selected_quantity"],
}, nil
}
// MergeCart 合并购物车(用于登录后合并游客购物车)
func (s *CartService) MergeCart(userID uint, guestCartItems []struct {
ProductID uint `json:"product_id"`
SKUID uint `json:"sku_id"`
Quantity int `json:"quantity"`
}) error {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return errors.New("用户不存在")
}
// 获取用户现有购物车
existingCart, err := s.orderRepo.GetCart(userID)
if err != nil {
return err
}
// 创建现有购物车的映射
existingMap := make(map[string]*model.Cart)
for i, item := range existingCart {
key := fmt.Sprintf("%d_%d", item.ProductID, item.SKUID)
if item.SKUID == nil {
key = fmt.Sprintf("%d_0", item.ProductID)
}
existingMap[key] = &existingCart[i]
}
// 合并游客购物车项
for _, guestItem := range guestCartItems {
key := fmt.Sprintf("%d_%d", guestItem.ProductID, guestItem.SKUID)
if guestItem.SKUID == 0 {
key = fmt.Sprintf("%d_0", guestItem.ProductID)
}
if existingItem, exists := existingMap[key]; exists {
// 已存在,更新数量
newQuantity := existingItem.Quantity + guestItem.Quantity
err = s.orderRepo.UpdateCartItem(existingItem.ID, newQuantity)
if err != nil {
return err
}
} else {
// 不存在,添加新项
err = s.AddToCart(userID, guestItem.ProductID, guestItem.SKUID, guestItem.Quantity)
if err != nil {
return err
}
}
}
return nil
}
// GetSelectedCartItems 获取选中的购物车项
func (s *CartService) GetSelectedCartItems(userID uint) ([]model.Cart, error) {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return nil, errors.New("用户不存在")
}
return s.orderRepo.GetSelectedCartItems(userID)
}
// CalculateCartDiscount 计算购物车优惠(预留接口)
func (s *CartService) CalculateCartDiscount(userID uint, couponID uint) (map[string]interface{}, error) {
// 检查用户是否存在
_, err := s.userRepo.GetByID(userID)
if err != nil {
return nil, errors.New("用户不存在")
}
selectedItems, err := s.GetSelectedCartItems(userID)
if err != nil {
return nil, err
}
var originalAmount float64
for _, item := range selectedItems {
product, err := s.productRepo.GetByID(item.ProductID)
if err != nil {
continue
}
originalAmount += float64(product.Price) / 100 * float64(item.Quantity)
}
// 这里可以添加优惠券计算逻辑
discountAmount := 0.0
finalAmount := originalAmount - discountAmount
return map[string]interface{}{
"original_amount": originalAmount,
"discount_amount": discountAmount,
"final_amount": finalAmount,
"coupon_id": couponID,
}, nil
}