qmj 6 дней назад
Родитель
Сommit
a0cdbad926

+ 2 - 1
ruoyi-admin/src/main/java/com/ruoyi/app/user/UserPromotionCalcController.java

@@ -24,7 +24,8 @@ import com.ruoyi.system.utils.JwtUtil;
  *
  * 【入参说明】
  * storeId   (必填) 门店ID
- * items     (必填) 购物车商品列表 [{productId, quantity}],不传价格,后端从数据库查
+ * items     (必填) 购物车商品列表 [{productId, quantity, specPrice}],不传商品价格,后端从数据库查;
+ *           specPrice(选填)规格加价,可为0或不传,实付单价=商品价格+规格价格
  * couponId  (选填) 用户要使用的优惠券ID,对应 promotion_user_coupon.id,每单只能用一张
  * forcePath (选填) 强制指定路径 "A"(折扣/第二份半价) 或 "B"(满减),不传则系统自动选最优
  *

+ 5 - 1
ruoyi-system/src/main/java/com/ruoyi/system/dto/PromotionCalcRequest.java

@@ -1,5 +1,6 @@
 package com.ruoyi.system.dto;
 
+import java.math.BigDecimal;
 import java.util.List;
 import lombok.Data;
 
@@ -8,7 +9,8 @@ import lombok.Data;
  *
  * 入参说明:
  * - storeId   (必填) 门店ID
- * - items     (必填) 购物车商品列表 [{productId, quantity}],不传价格,后端从数据库查
+ * - items     (必填) 购物车商品列表 [{productId, quantity, specPrice}],不传商品价格,后端从数据库查;
+ *               specPrice(选填)规格加价,可为0或不传,实付单价=商品价格+规格价格
  * - couponId  (选填) 用户要使用的优惠券ID,对应 promotion_user_coupon.id,每单只能用一张
  * - forcePath (选填) 强制指定路径 "A"(折扣/第二份半价) 或 "B"(满减),不传则系统自动选最优
  */
@@ -36,5 +38,7 @@ public class PromotionCalcRequest {
         private Long productId;
         /** 购买数量 */
         private Integer quantity;
+        /** 规格加价(选填, 可为0或不传) — 有规格商品时除商品价外需加上的规格价格,实付单价=商品价格+规格价格 */
+        private BigDecimal specPrice;
     }
 }

+ 20 - 5
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/PromotionCalcServiceImpl.java

@@ -85,6 +85,7 @@ public class PromotionCalcServiceImpl implements IPromotionCalcService
                 Map<String, Object> m = new LinkedHashMap<>();
                 m.put("productId", ci.getProductId());
                 m.put("quantity", ci.getQuantity());
+                m.put("specPrice", ci.getSpecPrice());
                 items.add(m);
             }
         }
@@ -112,7 +113,14 @@ public class PromotionCalcServiceImpl implements IPromotionCalcService
         {
             Long productId = toLong(item.get("productId"));
             int quantity = toInt(item.get("quantity"));
-            BigDecimal unitPrice = priceMap.getOrDefault(productId, BigDecimal.ZERO);
+            // 实付单价 = 商品价格 + 规格价格(规格价可为0/不传), 按行计算以支持同商品多规格
+            BigDecimal basePrice = priceMap.getOrDefault(productId, BigDecimal.ZERO);
+            BigDecimal specPrice = (BigDecimal) item.get("specPrice");
+            if (specPrice == null)
+            {
+                specPrice = BigDecimal.ZERO;
+            }
+            BigDecimal unitPrice = basePrice.add(specPrice);
             originalAmount = originalAmount.add(unitPrice.multiply(BigDecimal.valueOf(quantity)));
 
             Map<String, Object> ip = new LinkedHashMap<>();
@@ -768,17 +776,24 @@ public class PromotionCalcServiceImpl implements IPromotionCalcService
             if (couponRule.getProductId() != null)
             {
                 Long pid = couponRule.getProductId();
-                BigDecimal productPrice = priceMap.getOrDefault(pid, BigDecimal.ZERO);
+                // 汇总购物车内该商品的所有行(支持同商品多规格): 每行实付单价=商品价格+规格价格
                 int quantity = 0;
+                BigDecimal productPrice = priceMap.getOrDefault(pid, BigDecimal.ZERO);
+                BigDecimal totalProductPrice = BigDecimal.ZERO;
                 for (Map<String, Object> item : itemsWithPrice)
                 {
                     if (pid.equals(toLong(item.get("productId"))))
                     {
-                        quantity = toInt(item.get("quantity"));
-                        break;
+                        int qty = toInt(item.get("quantity"));
+                        BigDecimal unitPrice = (BigDecimal) item.get("unitPrice");
+                        if (quantity == 0)
+                        {
+                            productPrice = unitPrice; // 首行单价(展示用)
+                        }
+                        totalProductPrice = totalProductPrice.add(unitPrice.multiply(BigDecimal.valueOf(qty)));
+                        quantity += qty;
                     }
                 }
-                BigDecimal totalProductPrice = productPrice.multiply(BigDecimal.valueOf(quantity));
                 BigDecimal finalLineTotal = totalProductPrice;
                 if (couponRule.getDiscountRate() != null)
                 {