|
@@ -2,6 +2,7 @@ package com.etotem.cfc.service;
|
|
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.etotem.cfc.dto.CartItemDTO;
|
|
import com.etotem.cfc.dto.CartItemDTO;
|
|
|
|
|
+import com.etotem.cfc.dto.CartListResultDTO;
|
|
|
import com.etotem.cfc.entity.Cart;
|
|
import com.etotem.cfc.entity.Cart;
|
|
|
import com.etotem.cfc.entity.Product;
|
|
import com.etotem.cfc.entity.Product;
|
|
|
import com.etotem.cfc.entity.ProductBundleItem;
|
|
import com.etotem.cfc.entity.ProductBundleItem;
|
|
@@ -13,6 +14,7 @@ import com.etotem.cfc.mapper.ProductMapper;
|
|
|
import com.etotem.cfc.service.PpointService;
|
|
import com.etotem.cfc.service.PpointService;
|
|
|
import com.etotem.cfc.service.ProductGiftRuleService;
|
|
import com.etotem.cfc.service.ProductGiftRuleService;
|
|
|
import com.etotem.cfc.service.ProductSkuService;
|
|
import com.etotem.cfc.service.ProductSkuService;
|
|
|
|
|
+import com.etotem.cfc.service.SysConfigService;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
@@ -45,6 +47,9 @@ public class CartService {
|
|
|
@Resource
|
|
@Resource
|
|
|
private ProductGiftRuleService productGiftRuleService;
|
|
private ProductGiftRuleService productGiftRuleService;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private SysConfigService sysConfigService;
|
|
|
|
|
+
|
|
|
@Transactional
|
|
@Transactional
|
|
|
public CartItemDTO addToCart(Long userId, Long productId, Integer quantity, Long skuId) {
|
|
public CartItemDTO addToCart(Long userId, Long productId, Integer quantity, Long skuId) {
|
|
|
Product product = productMapper.selectById(productId);
|
|
Product product = productMapper.selectById(productId);
|
|
@@ -84,7 +89,7 @@ public class CartService {
|
|
|
return buildCartItemDTO(saved);
|
|
return buildCartItemDTO(saved);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public List<CartItemDTO> getCartList(Long userId) {
|
|
|
|
|
|
|
+ public CartListResultDTO getCartList(Long userId) {
|
|
|
List<Cart> cartList = cartMapper.selectList(
|
|
List<Cart> cartList = cartMapper.selectList(
|
|
|
new LambdaQueryWrapper<Cart>()
|
|
new LambdaQueryWrapper<Cart>()
|
|
|
.eq(Cart::getUserId, userId)
|
|
.eq(Cart::getUserId, userId)
|
|
@@ -122,7 +127,13 @@ public class CartService {
|
|
|
// 自动套餐模式:检测购物车子商品组合是否凑成某套餐,命中则挂 bundleMatch 提示
|
|
// 自动套餐模式:检测购物车子商品组合是否凑成某套餐,命中则挂 bundleMatch 提示
|
|
|
attachBundleMatches(cartList, result);
|
|
attachBundleMatches(cartList, result);
|
|
|
|
|
|
|
|
- return result;
|
|
|
|
|
|
|
+ // 计算送会员商品聚合信息
|
|
|
|
|
+ CartItemDTO.GiftPromo giftPromo = computeGiftPromo(cartList, productMap);
|
|
|
|
|
+
|
|
|
|
|
+ CartListResultDTO cartResult = new CartListResultDTO();
|
|
|
|
|
+ cartResult.setItems(result);
|
|
|
|
|
+ cartResult.setGiftPromo(giftPromo);
|
|
|
|
|
+ return cartResult;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -395,4 +406,88 @@ public class CartService {
|
|
|
}
|
|
}
|
|
|
return dto;
|
|
return dto;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 计算购物车中送会员商品的聚合信息:原价合计、是否达标、折扣金额等。
|
|
|
|
|
+ * 购物车所有商品默认视为已选中(checked=true)。
|
|
|
|
|
+ */
|
|
|
|
|
+ private CartItemDTO.GiftPromo computeGiftPromo(List<Cart> cartList, Map<Long, Product> productMap) {
|
|
|
|
|
+ if (cartList == null || cartList.isEmpty()) {
|
|
|
|
|
+ return buildEmptyGiftPromo();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查询购物车中所有商品的送会员规则
|
|
|
|
|
+ List<Long> giftProductIds = new ArrayList<>();
|
|
|
|
|
+ for (Cart cart : cartList) {
|
|
|
|
|
+ Long pid = cart.getProductId();
|
|
|
|
|
+ if (pid != null && !giftProductIds.contains(pid)) {
|
|
|
|
|
+ giftProductIds.add(pid);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ List<ProductGiftRule> giftRules = productGiftRuleService.listActiveByProductIds(giftProductIds);
|
|
|
|
|
+
|
|
|
|
|
+ // 按 productId 建立 rule 映射
|
|
|
|
|
+ Map<Long, ProductGiftRule> ruleMap = new HashMap<>();
|
|
|
|
|
+ for (ProductGiftRule rule : giftRules) {
|
|
|
|
|
+ if (rule.getProductId() != null) {
|
|
|
|
|
+ ruleMap.put(rule.getProductId(), rule);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 计算送会员商品原价合计
|
|
|
|
|
+ int giftOriginalTotal = 0;
|
|
|
|
|
+ for (Cart cart : cartList) {
|
|
|
|
|
+ if (ruleMap.containsKey(cart.getProductId())) {
|
|
|
|
|
+ Product product = productMap.get(cart.getProductId());
|
|
|
|
|
+ if (product != null && product.getPrice() != null && cart.getQuantity() != null) {
|
|
|
|
|
+ giftOriginalTotal += product.getPrice() * cart.getQuantity();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 读取配置
|
|
|
|
|
+ String thresholdStr = sysConfigService.getValue("gift_membership_original_threshold");
|
|
|
|
|
+ int threshold;
|
|
|
|
|
+ try {
|
|
|
|
|
+ threshold = thresholdStr != null ? Integer.parseInt(thresholdStr) : 0;
|
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
|
+ threshold = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String payPriceStr = sysConfigService.getValue("gift_membership_pay_price");
|
|
|
|
|
+ int payPrice;
|
|
|
|
|
+ try {
|
|
|
|
|
+ payPrice = payPriceStr != null ? Integer.parseInt(payPriceStr) : 0;
|
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
|
+ payPrice = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (threshold <= 0) {
|
|
|
|
|
+ return buildEmptyGiftPromo();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ boolean active = giftOriginalTotal >= threshold;
|
|
|
|
|
+ int discount = active ? Math.max(0, giftOriginalTotal - payPrice) : 0;
|
|
|
|
|
+ int remaining = active ? 0 : Math.max(0, threshold - giftOriginalTotal);
|
|
|
|
|
+
|
|
|
|
|
+ CartItemDTO.GiftPromo promo = new CartItemDTO.GiftPromo();
|
|
|
|
|
+ promo.setGiftOriginalTotal(giftOriginalTotal);
|
|
|
|
|
+ promo.setThreshold(threshold);
|
|
|
|
|
+ promo.setPayPrice(active ? payPrice : 0);
|
|
|
|
|
+ promo.setDiscount(discount);
|
|
|
|
|
+ promo.setActive(active);
|
|
|
|
|
+ promo.setRemaining(remaining);
|
|
|
|
|
+ return promo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private CartItemDTO.GiftPromo buildEmptyGiftPromo() {
|
|
|
|
|
+ CartItemDTO.GiftPromo promo = new CartItemDTO.GiftPromo();
|
|
|
|
|
+ promo.setGiftOriginalTotal(0);
|
|
|
|
|
+ promo.setThreshold(0);
|
|
|
|
|
+ promo.setPayPrice(0);
|
|
|
|
|
+ promo.setDiscount(0);
|
|
|
|
|
+ promo.setActive(false);
|
|
|
|
|
+ promo.setRemaining(0);
|
|
|
|
|
+ return promo;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|