Browse Source

fix(mallApp): 修正混合订单秒杀优惠计算

- 秒杀花束金额不再计入会员折扣和门店满减基数
- 门店满减件数排除秒杀花束,同时保留最低消费数量口径
- 限制秒杀剔除金额,避免优惠基数出现负数
shizhongqi 18 hours ago
parent
commit
1bfbe0defb
1 changed files with 40 additions and 5 deletions
  1. 40 5
      mallApp/src/pages/billing/affirmMix.vue

+ 40 - 5
mallApp/src/pages/billing/affirmMix.vue

@@ -725,8 +725,20 @@ export default {
 			});
 		},
 		/**
-		 * 整单互斥优惠前的应付:商品合计 + 运费/包装 - 红包。
-		 * 与后端 actionCreateMixOrder 红包后的 modifyPrice 对齐,作为会员折扣/门店满减比较基数。
+		 * 秒杀花束行合计。秒杀已是活动价,不进入会员折/门店满减基数,与后端 seckillGoodsPrice 对齐。
+		 */
+		mixSeckillGoodsPrice() {
+			let price = 0;
+			(this.list || []).forEach((item) => {
+				if (this.isBouquetItem(item) && item.activityType === "seckill") {
+					price += this.getSelectItemTotalPrice(item);
+				}
+			});
+			return Math.round(price * 100) / 100;
+		},
+		/**
+		 * 整单互斥优惠前的应付:先按商品+运费包装-红包得到应付,再剔除秒杀额。
+		 * 与后端 actionCreateMixOrder 红包后的 modifyPrice,经 capSeckillExcludePrice 后的优惠基数对齐。
 		 */
 		wholeDiscountBasePrice() {
 			let price = Number(this.mixGoodsPrice) || 0;
@@ -744,13 +756,21 @@ export default {
 			} else if ([0, 3, 4].includes(Number(this.form.sendType))) {
 				price = price + unMeetSend + packCost;
 			}
+
+			// 秒杀价不参与会员折/门店满减;剔除额不超过当前应付,避免红包已吃进秒杀时把基数打成负数
+			let seckillPrice = Number(this.mixSeckillGoodsPrice) || 0;
+			if (seckillPrice > price) seckillPrice = price;
+			if (seckillPrice > 0) {
+				price = price - seckillPrice;
+			}
+			if (price < 0) price = 0;
 			return parseFloat(price.toFixed(2));
 		},
 		/**
 		 * 会员折扣与门店满减互斥结果:type=member|shop|none,amount 为优惠额。
 		 */
 		wholeDiscountPick() {
-			return this.pickWholeOrderDiscount(this.wholeDiscountBasePrice, this.mixOrderBigNum);
+			return this.pickWholeOrderDiscount(this.wholeDiscountBasePrice, this.mixMeetCutBigNum);
 		},
 		/** 确认页费用行左侧:会员折扣 / 门店满减优惠 */
 		wholeDiscountLabel() {
@@ -792,7 +812,7 @@ export default {
 			});
 			return bigLength;
 		},
-		/** 最低消费数量用:花材扎数 + 花束份数(1 份花束计 1) */
+		/** 最低消费数量用:花材扎数 + 花束份数(1 份花束计 1,含秒杀) */
 		mixOrderBigNum() {
 			let bouquetNum = 0;
 			(this.list || []).forEach((item) => {
@@ -802,6 +822,21 @@ export default {
 			});
 			return (Number(this.mixItemBigNum) || 0) + bouquetNum;
 		},
+		/** 秒杀花束份数,与后端 seckillGoodsNum 对齐,不计入门店满减件数门槛 */
+		mixSeckillGoodsNum() {
+			let num = 0;
+			(this.list || []).forEach((item) => {
+				if (this.isBouquetItem(item) && item.activityType === "seckill") {
+					num += Number(item.bigCount) || 0;
+				}
+			});
+			return num;
+		},
+		/** 门店满减件数:整单扎/份去掉秒杀份数 */
+		mixMeetCutBigNum() {
+			const num = (Number(this.mixOrderBigNum) || 0) - (Number(this.mixSeckillGoodsNum) || 0);
+			return num > 0 ? num : 0;
+		},
 		/** 未达最低消费提示(来自批量预览缓存,与下单 calcFee 同源) */
 		unMeetWarningText() {
 			return (this.unMeetFeePreview && this.unMeetFeePreview.tip) || "";
@@ -1053,7 +1088,7 @@ export default {
 		/**
 		 * 会员折扣与门店满减互斥取大,口径对齐后端 WholeOrderDiscountClass。
 		 * @param {number} basePrice 商品+运费包装-红包
-		 * @param {number} bigNum 花材扎数+花束份数
+		 * @param {number} bigNum 满减件数(花材扎数+花束份数,不含秒杀)
 		 * @returns {{ type: string, amount: number }}
 		 */
 		pickWholeOrderDiscount(basePrice, bigNum) {