package cn.lili.modules.order.cart.render.impl; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import cn.lili.cache.Cache; import cn.lili.common.enums.PromotionTypeEnum; import cn.lili.common.enums.ResultCode; import cn.lili.common.exception.ServiceException; import cn.lili.common.security.context.UserContext; import cn.lili.common.utils.CurrencyUtil; import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.service.MemberService; import cn.lili.modules.order.cart.entity.dto.TradeDTO; import cn.lili.modules.order.cart.entity.enums.RenderStepEnums; import cn.lili.modules.order.cart.entity.vo.CartSkuVO; import cn.lili.modules.order.cart.entity.vo.CartVO; import cn.lili.modules.order.cart.render.CartRenderStep; import cn.lili.modules.order.order.entity.dto.DiscountPriceItem; import cn.lili.modules.order.order.entity.dto.PriceDetailDTO; import cn.lili.modules.promotion.entity.dto.search.KanjiaActivitySearchParams; import cn.lili.modules.promotion.entity.enums.KanJiaStatusEnum; import cn.lili.modules.promotion.entity.vos.PromotionSkuVO; import cn.lili.modules.promotion.entity.vos.kanjia.KanjiaActivityVO; import cn.lili.modules.promotion.service.KanjiaActivityGoodsService; import cn.lili.modules.promotion.service.KanjiaActivityService; import cn.lili.modules.promotion.service.PointsGoodsService; import cn.lili.modules.promotion.service.PromotionGoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.Objects; /** * 购物促销信息渲染实现 * * @author Chopper * @since 2020-07-02 14:47 */ @Service public class SkuPromotionRender implements CartRenderStep { @Autowired private KanjiaActivityService kanjiaActivityService; @Autowired private KanjiaActivityGoodsService kanjiaActivityGoodsService; @Autowired private PointsGoodsService pointsGoodsService; /** * 促销商品 */ @Autowired private PromotionGoodsService promotionGoodsService; @Autowired private MemberService memberService; @Autowired private Cache cache; @Override public RenderStepEnums step() { return RenderStepEnums.SKU_PROMOTION; } @Override public void render(TradeDTO tradeDTO) { //基础价格渲染 renderBasePrice(tradeDTO); //渲染单品促销 renderSkuPromotion(tradeDTO); //检查促销库存 checkPromotionQuantity(tradeDTO); } /** * 基础价格渲染 * * @param tradeDTO */ private void renderBasePrice(TradeDTO tradeDTO) { tradeDTO.getCartList().forEach( cartVO -> cartVO.getCheckedSkuList().forEach(cartSkuVO -> { PriceDetailDTO priceDetailDTO = cartSkuVO.getPriceDetailDTO(); priceDetailDTO.setGoodsPrice(cartSkuVO.getSubTotal()); priceDetailDTO.setDiscountPrice(CurrencyUtil.sub(priceDetailDTO.getOriginalPrice(), cartSkuVO.getSubTotal())); }) ); } /** * 渲染单品优惠 积分/拼团/秒杀/砍价 * * @param tradeDTO 购物车视图 */ private void renderSkuPromotion(TradeDTO tradeDTO) { switch (tradeDTO.getCartTypeEnum()) { //这里是双重循环,但是实际积分购买或者是砍价购买时,购物车只有一个商品,所以没有循环操作数据库或者其他的问题 case POINTS: Member userInfo = memberService.getUserInfo(); long totalPayPoints = 0; //处理积分商品购买 for (CartVO cartVO : tradeDTO.getCartList()) { for (CartSkuVO cartSkuVO : cartVO.getCheckedSkuList()) { cartSkuVO.getPriceDetailDTO().setPayPoint(cartSkuVO.getPoint()); PromotionSkuVO promotionSkuVO = new PromotionSkuVO(PromotionTypeEnum.POINTS_GOODS.name(), cartSkuVO.getPointsId()); cartSkuVO.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO); totalPayPoints += cartSkuVO.getPoint(); //记录优惠由来 cartSkuVO.getPriceDetailDTO().setDiscountPriceItem( DiscountPriceItem.builder() .discountPrice(CurrencyUtil.sub(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getPurchasePrice())) .promotionId(promotionSkuVO.getActivityId()) .promotionTypeEnum(PromotionTypeEnum.POINTS_GOODS) .skuId(cartSkuVO.getGoodsSku().getId()) .goodsId(cartSkuVO.getGoodsSku().getGoodsId()) .build() ); } } if (userInfo.getPoint() < totalPayPoints) { throw new ServiceException(ResultCode.POINT_NOT_ENOUGH); } return; case KANJIA: for (CartVO cartVO : tradeDTO.getCartList()) { for (CartSkuVO cartSkuVO : cartVO.getCheckedSkuList()) { KanjiaActivitySearchParams kanjiaActivitySearchParams = new KanjiaActivitySearchParams(); kanjiaActivitySearchParams.setGoodsSkuId(cartSkuVO.getGoodsSku().getId()); kanjiaActivitySearchParams.setMemberId(Objects.requireNonNull(UserContext.getCurrentUser()).getId()); kanjiaActivitySearchParams.setStatus(KanJiaStatusEnum.SUCCESS.name()); KanjiaActivityVO kanjiaActivityVO = kanjiaActivityService.getKanjiaActivityVO(kanjiaActivitySearchParams); //可以砍价金额购买,则处理信息 if (Boolean.TRUE.equals(kanjiaActivityVO.getPass())) { cartSkuVO.setKanjiaId(kanjiaActivityVO.getId()); cartSkuVO.setPurchasePrice(kanjiaActivityVO.getPurchasePrice()); cartSkuVO.setSubTotal(kanjiaActivityVO.getPurchasePrice()); cartSkuVO.getPriceDetailDTO().setGoodsPrice(kanjiaActivityVO.getPurchasePrice()); } PromotionSkuVO promotionSkuVO = new PromotionSkuVO(PromotionTypeEnum.KANJIA.name(), cartSkuVO.getKanjiaId()); cartSkuVO.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO); //记录优惠由来 cartSkuVO.getPriceDetailDTO().setDiscountPriceItem( DiscountPriceItem.builder() .discountPrice(CurrencyUtil.sub(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getPurchasePrice())) .promotionId(promotionSkuVO.getActivityId()) .promotionTypeEnum(PromotionTypeEnum.KANJIA) .skuId(cartSkuVO.getGoodsSku().getId()) .goodsId(cartSkuVO.getGoodsSku().getGoodsId()) .build() ); } } return; case PINTUAN: for (CartVO cartVO : tradeDTO.getCartList()) { for (CartSkuVO cartSkuVO : cartVO.getCheckedSkuList()) { PromotionSkuVO promotionSkuVO = new PromotionSkuVO(PromotionTypeEnum.PINTUAN.name(), cartSkuVO.getPintuanId()); cartSkuVO.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO); //记录优惠由来 cartSkuVO.getPriceDetailDTO().setDiscountPriceItem( DiscountPriceItem.builder() .discountPrice(CurrencyUtil.sub(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getPurchasePrice())) .promotionId(promotionSkuVO.getActivityId()) .promotionTypeEnum(PromotionTypeEnum.PINTUAN) .skuId(cartSkuVO.getGoodsSku().getId()) .goodsId(cartSkuVO.getGoodsSku().getGoodsId()) .build() ); } } return; case CART: case BUY_NOW: case VIRTUAL: //循环购物车 for (CartVO cartVO : tradeDTO.getCartList()) { //循环sku for (CartSkuVO cartSkuVO : cartVO.getCheckedSkuList()) { //赋予商品促销信息 for (Map.Entry entry : cartSkuVO.getPromotionMap().entrySet()) { if (ignorePromotion(entry.getKey())) { continue; } JSONObject promotionsObj = JSONUtil.parseObj(entry.getValue()); PromotionSkuVO promotionSkuVO = new PromotionSkuVO(entry.getKey().split("-")[0], promotionsObj.get("id", String.class)); cartSkuVO.setSubTotal(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum())); cartSkuVO.getPriceDetailDTO().setGoodsPrice(cartSkuVO.getSubTotal()); cartSkuVO.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO); //如果是秒杀活动 if (promotionSkuVO.getPromotionType().equals(PromotionTypeEnum.SECKILL.name())) { //需记录秒杀活动详情 cartSkuVO.getPriceDetailDTO().setDiscountPriceItem( DiscountPriceItem.builder() .discountPrice(CurrencyUtil.sub(cartSkuVO.getGoodsSku().getPrice(), cartSkuVO.getPurchasePrice())) .promotionId(promotionSkuVO.getActivityId()) .promotionTypeEnum(PromotionTypeEnum.SECKILL) .skuId(cartSkuVO.getGoodsSku().getId()) .goodsId(cartSkuVO.getGoodsSku().getGoodsId()) .build()); } } } } return; default: } } /** * 检查促销库存 * * @param tradeDTO 购物车视图 */ private void checkPromotionQuantity(TradeDTO tradeDTO) { for (CartSkuVO cartSkuVO : tradeDTO.getCheckedSkuList()) { List joinPromotion = cartSkuVO.getPriceDetailDTO().getJoinPromotion(); if (!joinPromotion.isEmpty()) { for (PromotionSkuVO promotionSkuVO : joinPromotion) { this.checkPromotionGoodsQuantity(cartSkuVO, promotionSkuVO); } } } } private void checkPromotionGoodsQuantity(CartSkuVO cartSkuVO, PromotionSkuVO promotionSkuVO) { String promotionGoodsStockCacheKey = PromotionGoodsService.getPromotionGoodsStockCacheKey(PromotionTypeEnum.valueOf(promotionSkuVO.getPromotionType()), promotionSkuVO.getActivityId(), cartSkuVO.getGoodsSku().getId()); Object quantity = cache.get(promotionGoodsStockCacheKey); if (quantity == null) { //如果促销有库存信息 PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(promotionSkuVO.getPromotionType()); switch (promotionTypeEnum) { case KANJIA: quantity = kanjiaActivityGoodsService.getKanjiaGoodsBySkuId(cartSkuVO.getGoodsSku().getId()).getStock(); break; case POINTS_GOODS: quantity = pointsGoodsService.getPointsGoodsDetailBySkuId(cartSkuVO.getGoodsSku().getId()).getActiveStock(); break; case SECKILL: case PINTUAN: quantity = promotionGoodsService.getPromotionGoodsStock(PromotionTypeEnum.valueOf(promotionSkuVO.getPromotionType()), promotionSkuVO.getActivityId(), cartSkuVO.getGoodsSku().getId()); break; default: return; } } if (quantity != null && cartSkuVO.getNum() > (Integer) quantity) {//设置购物车未选中 cartSkuVO.setChecked(false); //设置失效消息 cartSkuVO.setErrorMessage("促销商品库存不足,现有库存数量[" + quantity + "]"); } } /** * 购物车促销类型 */ private boolean ignorePromotion(String promotionKey) { // 忽略积分活动活动 忽略砍价活动 忽略优惠券活动 忽略拼团活动 return promotionKey.contains(PromotionTypeEnum.POINTS_GOODS.name()) || promotionKey.contains(PromotionTypeEnum.KANJIA.name()) || promotionKey.contains(PromotionTypeEnum.COUPON.name()) || promotionKey.contains(PromotionTypeEnum.PINTUAN.name()); } }