framework/src/main/java/cn/lili/modules/order/cart/entity/dto/SkuMapDTO.java
New file @@ -0,0 +1,12 @@ package cn.lili.modules.order.cart.entity.dto; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class SkuMapDTO { private String skuId; private Double price; } framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java
@@ -5,6 +5,7 @@ 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.SkuMapDTO; 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; @@ -240,8 +241,13 @@ //接收具体优惠券信息 MemberCoupon coupon = memberCouponDTO.getMemberCoupon(); Integer goodsNum = tradeDTO.getSkuList().stream().map(CartSkuVO::getNum).reduce(Integer::sum).get(); //处理一个极端情况,如果优惠券满减金额大于订单金额 if (coupon.getCouponType().equals(CouponTypeEnum.PRICE.name()) && coupon.getPrice() > countPrice) { if (coupon.getCouponType().equals(CouponTypeEnum.PRICE.name()) && coupon.getPrice() > countPrice && coupon.getGoodsUseLimitNum() >= goodsNum) { //将符合优惠券的金额写入,即最大扣减金额 coupon.setPrice(countPrice); } @@ -264,21 +270,42 @@ * @param memberCouponDTO 用于计算优惠券结算详情 */ private void renderCouponPrice(Map<String, Double> couponMap, TradeDTO tradeDTO, MemberCoupon coupon, MemberCouponDTO memberCouponDTO) { List<SkuMapDTO> skuMapDTOList = new ArrayList<>(); for (String skuId : couponMap.keySet()) { skuMapDTOList.add(new SkuMapDTO(skuId, couponMap.get(skuId))); } skuMapDTOList.sort((o1, o2) -> o2.getPrice().compareTo(o1.getPrice())); //分发优惠券 PromotionPriceUtil.recountPrice(tradeDTO, memberCouponDTO.getSkuDetail(), memberCouponDTO.getMemberCoupon().getPrice(), Boolean.TRUE.equals(coupon.getPlatformFlag()) ? PromotionTypeEnum.PLATFORM_COUPON : PromotionTypeEnum.COUPON, memberCouponDTO.getMemberCoupon().getCouponId()); PromotionPriceUtil.recountPrice(tradeDTO, memberCouponDTO.getSkuDetail(), memberCouponDTO.getMemberCoupon().getPrice(), Boolean.TRUE.equals(coupon.getPlatformFlag()) ? PromotionTypeEnum.PLATFORM_COUPON : PromotionTypeEnum.COUPON, memberCouponDTO.getMemberCoupon().getCouponId(), memberCouponDTO.getMemberCoupon().getGoodsUseLimitNum()); //如果是平台券 则需要计算商家承担比例 if (Boolean.TRUE.equals(coupon.getPlatformFlag()) && coupon.getStoreCommission() > 0) { Integer i = coupon.getGoodsUseLimitNum(); //循环所有优惠券 for (String skuId : couponMap.keySet()) { for (SkuMapDTO skuMapDTO : skuMapDTOList) { for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) { //写入平台优惠券承担比例 if (cartSkuVO.getGoodsSku().getId().equals(skuId)) { //写入店铺承担比例 if (cartSkuVO.getGoodsSku().getId().equals(skuMapDTO.getSkuId())) { if (i == null) { cartSkuVO.getPriceDetailDTO().setSiteCouponPoint(coupon.getStoreCommission()); } else { if (i > 0) { //写入店铺承担比例 if (i >= cartSkuVO.getNum()) { cartSkuVO.getPriceDetailDTO().setSiteCouponPoint(coupon.getStoreCommission()); } else { cartSkuVO.getPriceDetailDTO().setSiteCouponPoint(coupon.getStoreCommission() * i / cartSkuVO.getNum()); } i = i - cartSkuVO.getNum(); } else { return; } } } } } @@ -294,6 +321,7 @@ * @param coupon 优惠券信息 */ private void renderCouponDiscount(Map<String, Double> couponMap, TradeDTO tradeDTO, MemberCoupon coupon) { //循环所有优惠券 for (String skuId : couponMap.keySet()) { @@ -315,9 +343,10 @@ } priceDetailDTO.setCouponPrice(CurrencyUtil.add(priceDetailDTO.getCouponPrice(), discountCouponPrice)); } else { return; } } } } } framework/src/main/java/cn/lili/modules/order/cart/render/impl/FullDiscountRender.java
@@ -86,7 +86,7 @@ if (isFull(countPrice, cart)) { //如果减现金 if (Boolean.TRUE.equals(fullDiscount.getFullMinusFlag())) { PromotionPriceUtil.recountPrice(tradeDTO, skuPriceDetail, fullDiscount.getFullMinus(), PromotionTypeEnum.FULL_DISCOUNT, fullDiscountVO.getId()); PromotionPriceUtil.recountPrice(tradeDTO, skuPriceDetail, fullDiscount.getFullMinus(), PromotionTypeEnum.FULL_DISCOUNT, fullDiscountVO.getId(), 0); } //打折 else if (Boolean.TRUE.equals(fullDiscount.getFullRateFlag())) { framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java
@@ -3,11 +3,13 @@ import cn.hutool.core.map.MapUtil; import cn.lili.common.enums.PromotionTypeEnum; import cn.lili.common.utils.CurrencyUtil; import cn.lili.modules.order.cart.entity.dto.SkuMapDTO; import cn.lili.modules.order.cart.entity.dto.TradeDTO; import cn.lili.modules.order.cart.entity.vo.CartSkuVO; import cn.lili.modules.order.order.entity.dto.DiscountPriceItem; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @@ -32,15 +34,52 @@ * @param promotionTypeEnum 促销类型 */ public static void recountPrice(TradeDTO tradeDTO, Map<String, Double> skuPromotionDetail, Double discountPrice, PromotionTypeEnum promotionTypeEnum, String activityId) { PromotionTypeEnum promotionTypeEnum, String activityId, Integer goodsUseLimitNum) { // sku 促销信息非空判定 if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) { return; } //计算总金额 Double totalPrice = 0D; //获取购物车信息 List<CartSkuVO> skuVOList = tradeDTO.getSkuList(); //已优惠金额 AtomicReference<Double> deducted = new AtomicReference<>(0D); if (goodsUseLimitNum > 0) { // 处理限制商品数量逻辑,只处理一个商品 List<SkuMapDTO> skuMapDTOList = new ArrayList<>(); for (String skuId : skuPromotionDetail.keySet()) { skuMapDTOList.add(new SkuMapDTO(skuId, skuPromotionDetail.get(skuId))); } skuMapDTOList.sort((o1, o2) -> o2.getPrice().compareTo(o1.getPrice())); final int[] i = {0}; for (SkuMapDTO skuMap : skuMapDTOList) { //获取对应商品进行计算 Double finalDiscountPrice = discountPrice; skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuMap.getSkuId())).findFirst().ifPresent(cartSkuVO -> { //sku 优惠金额 Double skuDiscountPrice = 0D; if (i[0] < 1) { if (cartSkuVO.getUtilPrice() > finalDiscountPrice) { skuDiscountPrice = cartSkuVO.getUtilPrice() - finalDiscountPrice; } else { skuDiscountPrice = cartSkuVO.getUtilPrice(); } //累加已优惠金额 deducted.set(CurrencyUtil.add(deducted.get(), skuDiscountPrice)); i[0] = i[0] + 1; } calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId); }); discountPrice = deducted.get(); } } else { for (Double value : skuPromotionDetail.values()) { totalPrice = CurrencyUtil.add(totalPrice, value); } @@ -66,14 +105,9 @@ } } //获取购物车信息 List<CartSkuVO> skuVOList = tradeDTO.getSkuList(); // 获取map分配sku的总数,如果是最后一个商品分配金额,则将金额从百分比改为总金额扣减,避免出现小数除不尽 AtomicInteger count = new AtomicInteger(skuPromotionDetail.size()); //已优惠金额 AtomicReference<Double> deducted = new AtomicReference<>(0D); for (String skuId : skuPromotionDetail.keySet()) { @@ -104,7 +138,7 @@ }); } } calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId); } @@ -218,9 +252,11 @@ // 如果还有剩余金额,则继续分摊 if (balance.get() > 0) { skuPromotionDetailClone.remove(lastSkuId.toString()); if (skuPromotionDetail.containsKey(lastSkuId.toString())) { double lastDiscountPrice = CurrencyUtil.sub(discountPrice, skuPromotionDetail.get(lastSkuId.toString())); double lastTotalPrice = CurrencyUtil.sub(totalPrice, skuPromotionDetail.get(lastSkuId.toString())); filterEnoughSku(skuVOList, skuPromotionDetailClone, lastDiscountPrice, lastTotalPrice, balance, lastSkuId, promotionTypeEnum, activityId); } } else { break; } framework/src/main/java/cn/lili/modules/promotion/entity/dos/Coupon.java
@@ -82,6 +82,9 @@ @ApiModelProperty(value = "有效期") private Integer effectiveDays; @ApiModelProperty(value = "商品使用限制") private Integer goodsUseLimitNum; public Coupon(CouponVO couponVO) { BeanUtils.copyProperties(couponVO, this); } framework/src/main/java/cn/lili/modules/promotion/entity/dos/MemberCoupon.java
@@ -107,6 +107,8 @@ @ApiModelProperty(value = "会员优惠券状态") private String memberCouponStatus; @ApiModelProperty(value = "商品使用限制") private Integer goodsUseLimitNum; public MemberCoupon() { } @@ -120,6 +122,7 @@ setScopeType(coupon.getScopeType()); setScopeId(coupon.getScopeId()); setCouponType(coupon.getCouponType()); setGoodsUseLimitNum(coupon.getGoodsUseLimitNum()); setStartTime(coupon.getStartTime() == null ? new Date() : coupon.getStartTime()); setGetType(coupon.getGetType()); framework/src/main/resources/mapper/lmk/VideoMapper.xml
@@ -300,7 +300,7 @@ LV.delete_flag = 0 AND LV.STATUS = '1' AND LV.video_type = #{query.videoType} AND lm.id IS NOT NULL AND LM.id IS NOT NULL UNION ALL SELECT LV.author_id, @@ -334,7 +334,7 @@ LV.delete_flag = 0 AND LV.STATUS = '1' AND LV.video_type = #{query.videoType} AND lm.id IS NOT NULL AND LM.id IS NOT NULL ORDER BY create_time DESC </select>