|
@@ -1,39 +1,38 @@
|
|
|
package cn.iocoder.yudao.module.trade.service.cart;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
-import cn.hutool.core.lang.Assert;
|
|
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|
|
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
|
|
-import cn.iocoder.yudao.module.promotion.api.price.PriceApi;
|
|
|
-import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO;
|
|
|
-import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum;
|
|
|
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
|
|
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
|
|
-import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO;
|
|
|
-import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO;
|
|
|
-import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO;
|
|
|
-import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO;
|
|
|
+import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
|
|
+import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
|
|
+import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartAddReqVO;
|
|
|
+import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartListRespVO;
|
|
|
+import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartUpdateReqVO;
|
|
|
import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert;
|
|
|
-import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO;
|
|
|
-import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartItemMapper;
|
|
|
+import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
|
|
|
+import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartMapper;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
-import java.util.ArrayList;
|
|
|
import java.util.Collection;
|
|
|
+import java.util.Comparator;
|
|
|
import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
|
|
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
|
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
|
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH;
|
|
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.CARD_ITEM_NOT_FOUND;
|
|
|
+import static java.util.Collections.emptyList;
|
|
|
|
|
|
/**
|
|
|
* 购物车 Service 实现类
|
|
|
*
|
|
|
+ * // TODO 芋艿:秒杀、拼团、砍价对购物车的影响
|
|
|
+ * // TODO 芋艿:未来优化:购物车的价格计算,支持营销信息
|
|
|
+ *
|
|
|
* @author 芋道源码
|
|
|
*/
|
|
|
@Service
|
|
@@ -41,123 +40,92 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.CARD_ITEM_N
|
|
|
public class TradeCartServiceImpl implements TradeCartService {
|
|
|
|
|
|
@Resource
|
|
|
- private TradeCartItemMapper cartItemMapper;
|
|
|
+ private TradeCartMapper cartMapper;
|
|
|
|
|
|
@Resource
|
|
|
- private ProductSkuApi productSkuApi;
|
|
|
+ private ProductSpuApi productSpuApi;
|
|
|
@Resource
|
|
|
- private PriceApi priceApi;
|
|
|
+ private ProductSkuApi productSkuApi;
|
|
|
|
|
|
@Override
|
|
|
- public void addCartItemCount(Long userId, AppTradeCartItemAddCountReqVO addCountReqVO) {
|
|
|
- Long skuId = addCountReqVO.getSkuId();
|
|
|
- Integer count = addCountReqVO.getCount();
|
|
|
- // 查询 CartItemDO
|
|
|
- TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, addCountReqVO.getSkuId());
|
|
|
-
|
|
|
- // 存在,则进行数量更新
|
|
|
- if (tradeItem != null) {
|
|
|
- checkProductSku(skuId, tradeItem.getCount() + count);
|
|
|
- cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId())
|
|
|
- .setSelected(true).setCount(tradeItem.getCount() + count));
|
|
|
- return;
|
|
|
+ public Long addCart(Long userId, AppTradeCartAddReqVO addReqVO) {
|
|
|
+ // 查询 TradeCartDO
|
|
|
+ TradeCartDO cart = cartMapper.selectByUserIdAndSkuId(userId, addReqVO.getSkuId(),
|
|
|
+ addReqVO.getAddStatus(), false);
|
|
|
+ // 校验 SKU
|
|
|
+ Integer count = cart != null && addReqVO.getAddStatus() ?
|
|
|
+ cart.getCount() + addReqVO.getCount() : addReqVO.getCount();
|
|
|
+ ProductSkuRespDTO sku = checkProductSku(addReqVO.getSkuId(), count);
|
|
|
+
|
|
|
+ // 情况一:存在,则进行数量更新
|
|
|
+ if (cart != null) {
|
|
|
+ cartMapper.updateById(new TradeCartDO().setId(cart.getId()).setCount(count));
|
|
|
+ return cart.getId();
|
|
|
+ // 情况二:不存在,则进行插入
|
|
|
+ } else {
|
|
|
+ cart = new TradeCartDO().setUserId(userId)
|
|
|
+ .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count)
|
|
|
+ .setAddStatus(addReqVO.getAddStatus()).setOrderStatus(false);
|
|
|
+ cartMapper.insert(cart);
|
|
|
}
|
|
|
-
|
|
|
- // 不存在,则进行插入
|
|
|
- ProductSkuRespDTO sku = checkProductSku(skuId, count);
|
|
|
- cartItemMapper.insert(new TradeCartItemDO().setUserId(userId).setSpuId(sku.getSpuId()).setSkuId(sku.getId())
|
|
|
- .setSelected(true).setCount(count));
|
|
|
+ return cart.getId();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO) {
|
|
|
- // 校验 TradeCartItemDO 存在
|
|
|
- TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, updateCountReqVO.getSkuId());
|
|
|
- if (tradeItem == null) {
|
|
|
+ public void updateCart(Long userId, AppTradeCartUpdateReqVO updateReqVO) {
|
|
|
+ // 校验 TradeCartDO 存在
|
|
|
+ TradeCartDO cart = cartMapper.selectById(updateReqVO.getId(), userId);
|
|
|
+ if (cart == null) {
|
|
|
throw exception(CARD_ITEM_NOT_FOUND);
|
|
|
}
|
|
|
// 校验商品 SKU
|
|
|
- checkProductSku(updateCountReqVO.getSkuId(), updateCountReqVO.getCount());
|
|
|
+ checkProductSku(cart.getSkuId(), updateReqVO.getCount());
|
|
|
|
|
|
// 更新数量
|
|
|
- cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId()).setCount(updateCountReqVO.getCount()));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) {
|
|
|
- // 查询 CartItemDO 列表
|
|
|
- List<TradeCartItemDO> cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, updateSelectedReqVO.getSkuIds());
|
|
|
- if (CollUtil.isEmpty(cartItems)) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 更新选中
|
|
|
- cartItemMapper.updateByIds(CollectionUtils.convertList(cartItems, TradeCartItemDO::getId),
|
|
|
- new TradeCartItemDO().setSelected(updateSelectedReqVO.getSelected()));
|
|
|
+ cartMapper.updateById(new TradeCartDO().setId(cart.getId())
|
|
|
+ .setCount(updateReqVO.getCount()));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 购物车删除商品
|
|
|
*
|
|
|
* @param userId 用户编号
|
|
|
- * @param skuIds 商品 SKU 编号的数组
|
|
|
+ * @param ids 商品 SKU 编号的数组
|
|
|
*/
|
|
|
@Override
|
|
|
- public void deleteCartItems(Long userId, Collection<Long> skuIds) {
|
|
|
- // 查询 CartItemDO 列表
|
|
|
- List<TradeCartItemDO> cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds);
|
|
|
- if (CollUtil.isEmpty(cartItems)) {
|
|
|
+ public void deleteCart(Long userId, Collection<Long> ids) {
|
|
|
+ // 查询 TradeCartDO 列表
|
|
|
+ List<TradeCartDO> carts = cartMapper.selectListByIds(ids, userId);
|
|
|
+ if (CollUtil.isEmpty(carts)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 批量标记删除
|
|
|
- cartItemMapper.deleteBatchIds(CollectionUtils.convertSet(cartItems, TradeCartItemDO::getId));
|
|
|
+ cartMapper.deleteBatchIds(ids);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public Integer getCartCount(Long userId) {
|
|
|
- return cartItemMapper.selectSumByUserId(userId);
|
|
|
+ return cartMapper.selectSumByUserId(userId);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public AppTradeCartDetailRespVO getCartDetail(Long userId) {
|
|
|
+ public AppTradeCartListRespVO getCartList(Long userId) {
|
|
|
// 获得购物车的商品
|
|
|
- List<TradeCartItemDO> cartItems = cartItemMapper.selectListByUserId(userId, null);
|
|
|
+ List<TradeCartDO> carts = cartMapper.selectListByUserId(userId);
|
|
|
+ carts.sort(Comparator.comparing(TradeCartDO::getId).reversed());
|
|
|
// 如果未空,则返回空结果
|
|
|
- if (CollUtil.isEmpty(cartItems)) {
|
|
|
- return TradeCartConvert.INSTANCE.buildEmptyAppTradeCartDetailRespVO();
|
|
|
+ if (CollUtil.isEmpty(carts)) {
|
|
|
+ return new AppTradeCartListRespVO().setValidList(emptyList())
|
|
|
+ .setInvalidList(emptyList());
|
|
|
}
|
|
|
|
|
|
- // 调用价格服务,计算价格
|
|
|
- PriceCalculateRespDTO priceCalculate = priceApi.calculatePrice(TradeCartConvert.INSTANCE.convert(userId, cartItems));
|
|
|
-
|
|
|
- // 转换返回
|
|
|
- Map<Long, TradeCartItemDO> cartItemMap = convertMap(cartItems, TradeCartItemDO::getSkuId);
|
|
|
- Map<Long, PriceCalculateRespDTO.OrderItem> orderItemMap = convertMap(priceCalculate.getOrder().getItems(),
|
|
|
- PriceCalculateRespDTO.OrderItem::getSkuId);
|
|
|
- List<AppTradeCartDetailRespVO.ItemGroup> itemGroups = new ArrayList<>(cartItems.size());
|
|
|
- // ① 场景一,营销活动,订单级别 TODO 芋艿:待测试
|
|
|
- priceCalculate.getPromotions().stream().filter(promotion -> PromotionLevelEnum.ORDER.getLevel().equals(promotion.getLevel()))
|
|
|
- .forEach(promotion -> {
|
|
|
- AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>())
|
|
|
- .setPromotion(TradeCartConvert.INSTANCE.convert(promotion));
|
|
|
- itemGroups.add(itemGroup);
|
|
|
- promotion.getItems().forEach(promotionItem -> {
|
|
|
- PriceCalculateRespDTO.OrderItem orderItem = orderItemMap.remove(promotionItem.getSkuId());
|
|
|
- Assert.notNull(orderItem, "商品 SKU({}) 对应的订单项不能为空", promotionItem.getSkuId());
|
|
|
- TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId());
|
|
|
- itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu
|
|
|
- });
|
|
|
- });
|
|
|
- // ② 场景二,营销活动,商品级别
|
|
|
- orderItemMap.values().forEach(orderItem -> {
|
|
|
- AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>(1)).setPromotion(null);
|
|
|
- itemGroups.add(itemGroup);
|
|
|
- TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId());
|
|
|
- itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu
|
|
|
- });
|
|
|
- return new AppTradeCartDetailRespVO().setItemGroups(itemGroups)
|
|
|
- .setOrder(TradeCartConvert.INSTANCE.convert(priceCalculate.getOrder()));
|
|
|
+ // 查询 SPU、SKU 列表
|
|
|
+ List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(convertSet(carts, TradeCartDO::getSpuId));
|
|
|
+ List<ProductSkuRespDTO> skus = productSkuApi.getSkuList(convertSet(carts, TradeCartDO::getSpuId));
|
|
|
+
|
|
|
+ // 拼接数据
|
|
|
+ return TradeCartConvert.INSTANCE.convertList(carts, spus, skus);
|
|
|
}
|
|
|
|
|
|
/**
|