From 211b5a717de92b9b52879280ca2285cdd0b4a54b Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期三, 10 九月 2025 19:11:25 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev

---
 framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java |  154 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 95 insertions(+), 59 deletions(-)

diff --git a/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java b/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java
index f3dedc3..ad9333d 100644
--- a/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java
+++ b/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,79 +34,111 @@
      * @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;
-        for (Double value : skuPromotionDetail.values()) {
-            totalPrice = CurrencyUtil.add(totalPrice, value);
-        }
-
-        //鏋佺鎯呭喌锛屽鏋滄墸鍑忛噾棰濆皬浜庨渶瑕佹敮浠樼殑閲戦锛屽垯鎵e噺閲戦=鏀粯閲戦锛屼笉鑳芥垚涓鸿礋鏁�
-        if (discountPrice > totalPrice) {
-            discountPrice = totalPrice;
-
-            for (String skuId : skuPromotionDetail.keySet()) {
-
-                //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
-                for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
-
-                    if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
-                        //浼樻儬鍒搁噾棰濓紝鍒欒鍏ヤ紭鎯犲埜 锛屽叾浠栧垯璁″叆鎬荤殑discount price
-                        if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
-                            cartSkuVO.getPriceDetailDTO().setCouponPrice(cartSkuVO.getPriceDetailDTO().getGoodsPrice());
-                        } else {
-                            cartSkuVO.getPriceDetailDTO().setDiscountPrice(cartSkuVO.getPriceDetailDTO().getGoodsPrice());
-                        }
-                    }
-                }
-            }
-        }
-
         //鑾峰彇璐墿杞︿俊鎭�
         List<CartSkuVO> skuVOList = tradeDTO.getSkuList();
-
-        // 鑾峰彇map鍒嗛厤sku鐨勬�绘暟锛屽鏋滄槸鏈�鍚庝竴涓晢鍝佸垎閰嶉噾棰濓紝鍒欏皢閲戦浠庣櫨鍒嗘瘮鏀逛负鎬婚噾棰濇墸鍑忥紝閬垮厤鍑虹幇灏忔暟闄や笉灏�
-        AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
 
         //宸蹭紭鎯犻噾棰�
         AtomicReference<Double> deducted = new AtomicReference<>(0D);
 
-        for (String skuId : skuPromotionDetail.keySet()) {
+        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;
-            Double finalTotalPrice = totalPrice;
-            skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuId)).findFirst().ifPresent(cartSkuVO -> {
-                //sku 浼樻儬閲戦
-                Double skuDiscountPrice;
-                count.getAndDecrement();
+                //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
+                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 (count.get() > 0) {
-                    //鍟嗗搧閲戦鍗犳瘮
-                    double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), finalTotalPrice, 4);
-                    //鍟嗗搧浼樻儬閲戦
-                    skuDiscountPrice = CurrencyUtil.mul(finalDiscountPrice, point);
-                    //绱姞宸蹭紭鎯犻噾棰�
-                    deducted.set(CurrencyUtil.add(deducted.get(), skuDiscountPrice));
+                        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);
+            }
+
+            //鏋佺鎯呭喌锛屽鏋滄墸鍑忛噾棰濆皬浜庨渶瑕佹敮浠樼殑閲戦锛屽垯鎵e噺閲戦=鏀粯閲戦锛屼笉鑳芥垚涓鸿礋鏁�
+            if (discountPrice > totalPrice) {
+                discountPrice = totalPrice;
+
+                for (String skuId : skuPromotionDetail.keySet()) {
+
+                    //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
+                    for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
+
+                        if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
+                            //浼樻儬鍒搁噾棰濓紝鍒欒鍏ヤ紭鎯犲埜 锛屽叾浠栧垯璁″叆鎬荤殑discount price
+                            if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
+                                cartSkuVO.getPriceDetailDTO().setCouponPrice(cartSkuVO.getPriceDetailDTO().getGoodsPrice());
+                            } else {
+                                cartSkuVO.getPriceDetailDTO().setDiscountPrice(cartSkuVO.getPriceDetailDTO().getGoodsPrice());
+                            }
+                        }
+                    }
                 }
-                // 濡傛灉鏄渶鍚庝竴涓晢鍝� 鍒欏噺鍘讳箣鍓嶄紭鎯犵殑閲戦鏉ヨ繘琛岃绠�
-                else {
-                    skuDiscountPrice = CurrencyUtil.sub(finalDiscountPrice, deducted.get());
-                }
+            }
 
-                calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
-            });
+            // 鑾峰彇map鍒嗛厤sku鐨勬�绘暟锛屽鏋滄槸鏈�鍚庝竴涓晢鍝佸垎閰嶉噾棰濓紝鍒欏皢閲戦浠庣櫨鍒嗘瘮鏀逛负鎬婚噾棰濇墸鍑忥紝閬垮厤鍑虹幇灏忔暟闄や笉灏�
+            AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
 
+
+            for (String skuId : skuPromotionDetail.keySet()) {
+
+                //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
+
+                Double finalDiscountPrice = discountPrice;
+                Double finalTotalPrice = totalPrice;
+                skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuId)).findFirst().ifPresent(cartSkuVO -> {
+                    //sku 浼樻儬閲戦
+                    Double skuDiscountPrice;
+                    count.getAndDecrement();
+
+                    //闈炴渶鍚庝竴涓晢鍝侊紝鍒欐寜鐓ф瘮渚嬭绠�
+                    if (count.get() > 0) {
+                        //鍟嗗搧閲戦鍗犳瘮
+                        double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), finalTotalPrice, 4);
+                        //鍟嗗搧浼樻儬閲戦
+                        skuDiscountPrice = CurrencyUtil.mul(finalDiscountPrice, point);
+                        //绱姞宸蹭紭鎯犻噾棰�
+                        deducted.set(CurrencyUtil.add(deducted.get(), skuDiscountPrice));
+                    }
+                    // 濡傛灉鏄渶鍚庝竴涓晢鍝� 鍒欏噺鍘讳箣鍓嶄紭鎯犵殑閲戦鏉ヨ繘琛岃绠�
+                    else {
+                        skuDiscountPrice = CurrencyUtil.sub(finalDiscountPrice, deducted.get());
+                    }
+
+                    calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
+                });
+
+            }
         }
-
         calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
 
     }
@@ -218,9 +252,11 @@
             // 濡傛灉杩樻湁鍓╀綑閲戦锛屽垯缁х画鍒嗘憡
             if (balance.get() > 0) {
                 skuPromotionDetailClone.remove(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);
+                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;
             }
@@ -235,9 +271,9 @@
 
 
     private static void filterEnoughSku(List<CartSkuVO> skuVOList, Map<String, Double> skuPromotionDetail,
-                                                   Double discountPrice, Double totalPrice,
-                                                   AtomicReference<Double> balance, StringBuilder lastSkuId,
-                                                   PromotionTypeEnum promotionTypeEnum, String activityId) {
+                                        Double discountPrice, Double totalPrice,
+                                        AtomicReference<Double> balance, StringBuilder lastSkuId,
+                                        PromotionTypeEnum promotionTypeEnum, String activityId) {
         AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
         AtomicReference<Double> countPrice = new AtomicReference<>(0D);
         for (String skuId : skuPromotionDetail.keySet()) {

--
Gitblit v1.8.0