package cn.lili.modules.order.cart.render.impl; import cn.hutool.core.text.CharSequenceUtil; import cn.lili.common.enums.PromotionTypeEnum; import cn.lili.common.utils.CurrencyUtil; import cn.lili.common.utils.StringUtils; import cn.lili.modules.order.cart.entity.dto.MemberCouponDTO; 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.render.CartRenderStep; import cn.lili.modules.order.cart.render.util.PromotionPriceUtil; import cn.lili.modules.order.order.entity.dto.PriceDetailDTO; import cn.lili.modules.promotion.entity.dos.MemberCoupon; import cn.lili.modules.promotion.entity.enums.CouponTypeEnum; import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum; import cn.lili.modules.promotion.entity.vos.MemberCouponVO; import cn.lili.modules.promotion.service.MemberCouponService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; /** * 购物促销信息渲染实现 * * @author Chopper * @since 2020-07-02 14:47 */ @Service public class CouponRender implements CartRenderStep { @Autowired private MemberCouponService memberCouponService; @Override public RenderStepEnums step() { return RenderStepEnums.COUPON; } @Override public void render(TradeDTO tradeDTO) { //优惠券列表 this.renderCouponRule(tradeDTO); //主要渲染各个优惠的价格 this.renderCoupon(tradeDTO); } /** * 渲染优惠券规则 * * @param tradeDTO 交易dto */ private void renderCouponRule(TradeDTO tradeDTO) { // 清除之前的优惠券 tradeDTO.removeCoupon(); List memberCouponList = memberCouponService.getMemberCoupons(tradeDTO.getMemberId()); //获取最新优惠券 memberCouponList = memberCouponList.stream() .filter(item -> item.getStartTime().before(new Date()) && item.getEndTime().after(new Date())) .collect(Collectors.toList()); if (!memberCouponList.isEmpty()) { this.checkMemberExistCoupon(tradeDTO, memberCouponList); } else { tradeDTO.setPlatformCoupon(null); tradeDTO.setStoreCoupons(new HashMap<>()); } memberCouponList.forEach(memberCoupon -> available(tradeDTO, memberCoupon)); } /** * 检查使用中的优惠券是否存在与用户的优惠券中 * * @param tradeDTO 交易dto * @param memberCouponList 会员优惠券列表 */ private void checkMemberExistCoupon(TradeDTO tradeDTO, List memberCouponList) { if (tradeDTO.getPlatformCoupon() != null && tradeDTO.getPlatformCoupon().getMemberCoupon() != null) { boolean b = memberCouponList.stream().anyMatch(i -> i.getId().equals(tradeDTO.getPlatformCoupon().getMemberCoupon().getId())); if (!b) { tradeDTO.setPlatformCoupon(null); } } if (!tradeDTO.getStoreCoupons().isEmpty()) { for (Map.Entry entry : tradeDTO.getStoreCoupons().entrySet()) { if (entry.getValue().getMemberCoupon() != null && memberCouponList.stream().noneMatch(i -> i.getId().equals(entry.getValue().getMemberCoupon().getId()))) { tradeDTO.getStoreCoupons().remove(entry.getKey()); } } } } /** * 判定优惠券是否可用 * * @param tradeDTO 交易dto * @param memberCoupon 会员优惠券 */ private void available(TradeDTO tradeDTO, MemberCoupon memberCoupon) { if (memberCoupon == null) { return; } List filterSku = filterSkuVo(tradeDTO.getCheckedSkuList(), memberCoupon); if (filterSku == null || filterSku.isEmpty()) { tradeDTO.getCantUseCoupons().add(new MemberCouponVO(memberCoupon, "购物车中没有满足优惠券使用范围的优惠券")); return; } List priceDetailDTOS = filterSku.stream().map(CartSkuVO::getPriceDetailDTO).collect(Collectors.toList()); PriceDetailDTO totalPrice = new PriceDetailDTO(); totalPrice.accumulationPriceDTO(priceDetailDTOS); //满足条件判定 if (totalPrice.getGoodsPrice() >= memberCoupon.getConsumeThreshold()) { tradeDTO.getCanUseCoupons().add(memberCoupon); } else { tradeDTO.getCantUseCoupons().add(new MemberCouponVO(memberCoupon, "优惠券使用门槛不足,还差" + StringUtils.toFen(CurrencyUtil.sub(memberCoupon.getConsumeThreshold(), totalPrice.getGoodsPrice())) + "元")); } } /** * 过滤购物车商品信息,按照优惠券的适用范围过滤 * * @param cartSkuVOS 购物车中的产品列表 * @param memberCoupon 会员优惠券 * @return 按照优惠券的适用范围过滤的购物车商品信息 */ private List filterSkuVo(List cartSkuVOS, MemberCoupon memberCoupon) { List filterSku; //平台店铺过滤 if (Boolean.TRUE.equals(memberCoupon.getPlatformFlag())) { filterSku = cartSkuVOS; } else { filterSku = cartSkuVOS.stream().filter(cartSkuVO -> cartSkuVO.getStoreId().equals(memberCoupon.getStoreId())).collect(Collectors.toList()); } if (filterSku == null || filterSku.isEmpty()) { return Collections.emptyList(); } //优惠券类型判定 switch (PromotionsScopeTypeEnum.valueOf(memberCoupon.getScopeType())) { case ALL: return filterSku; case PORTION_GOODS: //按照商品过滤 filterSku = filterSku.stream().filter(cartSkuVO -> memberCoupon.getScopeId().contains(cartSkuVO.getGoodsSku().getId())).collect(Collectors.toList()); break; case PORTION_SHOP_CATEGORY: //按照店铺分类过滤 filterSku = this.filterPromotionShopCategory(filterSku, memberCoupon); break; case PORTION_GOODS_CATEGORY: //按照店铺分类过滤 filterSku = filterSku.stream().filter(cartSkuVO -> { //平台分类获取 String[] categoryPath = cartSkuVO.getGoodsSku().getCategoryPath().split(","); //平台三级分类 String categoryId = categoryPath[categoryPath.length - 1]; return memberCoupon.getScopeId().contains(categoryId); }).collect(Collectors.toList()); break; default: return Collections.emptyList(); } return filterSku; } /** * 优惠券按照店铺分类过滤 * * @param filterSku 过滤的购物车商品信息 * @param memberCoupon 会员优惠 * @return 优惠券按照店铺分类过滤的购物车商品信息 */ private List filterPromotionShopCategory(List filterSku, MemberCoupon memberCoupon) { return filterSku.stream().filter(cartSkuVO -> { if (CharSequenceUtil.isNotEmpty(cartSkuVO.getGoodsSku().getStoreCategoryPath())) { //获取店铺分类 String[] storeCategoryPath = cartSkuVO.getGoodsSku().getStoreCategoryPath().split(","); for (String category : storeCategoryPath) { //店铺分类只要有一项吻合,即可返回true if (memberCoupon.getScopeId().contains(category)) { return true; } } } return false; }).collect(Collectors.toList()); } /** * 渲染优惠券 * * @param tradeDTO 购物车展示信息 */ private void renderCoupon(TradeDTO tradeDTO) { MemberCouponDTO platformCoupon = tradeDTO.getPlatformCoupon(); //如果有勾选平台优惠券 if (platformCoupon != null) { renderSku(tradeDTO, platformCoupon); } //计算商家优惠券 Map map = tradeDTO.getStoreCoupons(); if (map != null && map.size() > 0) { for (MemberCouponDTO memberCouponDTO : map.values()) { renderSku(tradeDTO, memberCouponDTO); } } } /** * 渲染sku优惠信息 * * @param tradeDTO 交易DTO * @param memberCouponDTO 优惠券DTO */ private void renderSku(TradeDTO tradeDTO, MemberCouponDTO memberCouponDTO) { //计算优惠总金额 Double countPrice = 0D; Map couponMap = memberCouponDTO.getSkuDetail(); for (Double skuPrice : couponMap.values()) { countPrice = CurrencyUtil.add(countPrice, skuPrice); } //接收具体优惠券信息 MemberCoupon coupon = memberCouponDTO.getMemberCoupon(); //处理一个极端情况,如果优惠券满减金额大于订单金额 if (coupon.getCouponType().equals(CouponTypeEnum.PRICE.name()) && coupon.getPrice() > countPrice) { //将符合优惠券的金额写入,即最大扣减金额 coupon.setPrice(countPrice); } if (coupon.getCouponType().equals(CouponTypeEnum.PRICE.name())) { //减免现金,则按照商品价格计算 需要通过工具类进行优惠金额的分发,分发给每个商品 this.renderCouponPrice(couponMap, tradeDTO, coupon, memberCouponDTO); } else { //打折券 直接计算 this.renderCouponDiscount(couponMap, tradeDTO, coupon); } } /** * 减免现金,则按照商品价格计算 需要通过工具类进行优惠金额的分发,分发给每个商品 * * @param couponMap 优惠券结算信息 * @param tradeDTO 交易dto * @param coupon 优惠券信息 * @param memberCouponDTO 用于计算优惠券结算详情 */ private void renderCouponPrice(Map couponMap, TradeDTO tradeDTO, MemberCoupon coupon, MemberCouponDTO memberCouponDTO) { //分发优惠券 PromotionPriceUtil.recountPrice(tradeDTO, memberCouponDTO.getSkuDetail(), memberCouponDTO.getMemberCoupon().getPrice(), Boolean.TRUE.equals(coupon.getPlatformFlag()) ? PromotionTypeEnum.PLATFORM_COUPON : PromotionTypeEnum.COUPON, memberCouponDTO.getMemberCoupon().getCouponId()); //如果是平台券 则需要计算商家承担比例 if (Boolean.TRUE.equals(coupon.getPlatformFlag()) && coupon.getStoreCommission() > 0) { //循环所有优惠券 for (String skuId : couponMap.keySet()) { for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) { //写入平台优惠券承担比例 if (cartSkuVO.getGoodsSku().getId().equals(skuId)) { //写入店铺承担比例 cartSkuVO.getPriceDetailDTO().setSiteCouponPoint(coupon.getStoreCommission()); } } } } } /** * 打折券计算 * * @param couponMap 优惠券结算信息 * @param tradeDTO 交易dto * @param coupon 优惠券信息 */ private void renderCouponDiscount(Map couponMap, TradeDTO tradeDTO, MemberCoupon coupon) { //循环所有优惠券 for (String skuId : couponMap.keySet()) { // 循环购物车商品 for (CartSkuVO item : tradeDTO.getSkuList()) { //如果id相等,则渲染商品价格信息 if (item.getGoodsSku().getId().equals(skuId)) { PriceDetailDTO priceDetailDTO = item.getPriceDetailDTO(); // 打折金额=商品金额*折扣/10 Double discountCouponPrice = CurrencyUtil.mul(priceDetailDTO.getGoodsPrice(), CurrencyUtil.sub(1, CurrencyUtil.div(coupon.getDiscount(), 10, 3))); //平台券则写入店铺承担优惠券比例 if (Boolean.TRUE.equals(coupon.getPlatformFlag())) { priceDetailDTO.setSiteCouponPrice(discountCouponPrice); priceDetailDTO.setSiteCouponPoint(coupon.getStoreCommission()); } priceDetailDTO.setCouponPrice(CurrencyUtil.add(priceDetailDTO.getCouponPrice(), discountCouponPrice)); } } } } }