@pisell/pisellos 2.1.103 → 2.1.104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +1 -0
  3. package/dist/model/index.d.ts +1 -0
  4. package/dist/model/index.js +1 -0
  5. package/dist/model/strategy/adapter/index.d.ts +3 -0
  6. package/dist/model/strategy/adapter/index.js +4 -0
  7. package/dist/model/strategy/adapter/type.d.ts +28 -0
  8. package/dist/model/strategy/adapter/type.js +1 -0
  9. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +84 -0
  10. package/dist/model/strategy/adapter/walletPass/evaluator.js +498 -0
  11. package/dist/model/strategy/adapter/walletPass/example.d.ts +4 -0
  12. package/dist/model/strategy/adapter/walletPass/example.js +258 -0
  13. package/dist/model/strategy/adapter/walletPass/index.d.ts +32 -0
  14. package/dist/model/strategy/adapter/walletPass/index.js +182 -0
  15. package/dist/model/strategy/adapter/walletPass/locales.d.ts +1 -0
  16. package/dist/model/strategy/adapter/walletPass/locales.js +26 -0
  17. package/dist/model/strategy/adapter/walletPass/type.d.ts +169 -0
  18. package/dist/model/strategy/adapter/walletPass/type.js +1 -0
  19. package/dist/model/strategy/adapter/walletPass/utils.d.ts +50 -0
  20. package/dist/model/strategy/adapter/walletPass/utils.js +1064 -0
  21. package/dist/model/strategy/index.d.ts +94 -0
  22. package/dist/model/strategy/index.js +551 -0
  23. package/dist/model/strategy/strategy-example.d.ts +5 -0
  24. package/dist/model/strategy/strategy-example.js +331 -0
  25. package/dist/model/strategy/type.d.ts +228 -0
  26. package/dist/model/strategy/type.js +94 -0
  27. package/dist/modules/Cart/types.d.ts +2 -0
  28. package/dist/modules/Cart/utils/cartProduct.js +11 -0
  29. package/dist/modules/Discount/types.d.ts +16 -0
  30. package/dist/modules/Payment/index.d.ts +2 -1
  31. package/dist/modules/Payment/index.js +10 -7
  32. package/dist/modules/Payment/utils.js +3 -0
  33. package/dist/modules/Payment/walletpass.d.ts +23 -0
  34. package/dist/modules/Payment/walletpass.js +191 -95
  35. package/dist/modules/Product/index.d.ts +1 -1
  36. package/dist/modules/Rules/index.d.ts +9 -5
  37. package/dist/modules/Rules/index.js +545 -129
  38. package/dist/modules/Rules/types.d.ts +1 -0
  39. package/dist/modules/Summary/types.d.ts +2 -0
  40. package/dist/modules/Summary/utils.d.ts +6 -0
  41. package/dist/modules/Summary/utils.js +21 -0
  42. package/dist/plugins/window.d.ts +2 -0
  43. package/dist/solution/BookingByStep/index.d.ts +3 -2
  44. package/dist/solution/BookingTicket/index.d.ts +1 -1
  45. package/dist/solution/Checkout/index.js +3 -1
  46. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  47. package/dist/solution/ShopDiscount/index.js +23 -7
  48. package/dist/solution/ShopDiscount/types.d.ts +1 -0
  49. package/dist/solution/ShopDiscount/types.js +2 -1
  50. package/dist/solution/ShopDiscount/utils.js +26 -12
  51. package/lib/index.d.ts +1 -0
  52. package/lib/index.js +3 -1
  53. package/lib/model/index.d.ts +1 -0
  54. package/lib/model/index.js +23 -0
  55. package/lib/model/strategy/adapter/index.d.ts +3 -0
  56. package/lib/model/strategy/adapter/index.js +45 -0
  57. package/lib/model/strategy/adapter/type.d.ts +28 -0
  58. package/lib/model/strategy/adapter/type.js +17 -0
  59. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +84 -0
  60. package/lib/model/strategy/adapter/walletPass/evaluator.js +422 -0
  61. package/lib/model/strategy/adapter/walletPass/example.d.ts +4 -0
  62. package/lib/model/strategy/adapter/walletPass/example.js +207 -0
  63. package/lib/model/strategy/adapter/walletPass/index.d.ts +32 -0
  64. package/lib/model/strategy/adapter/walletPass/index.js +142 -0
  65. package/lib/model/strategy/adapter/walletPass/locales.d.ts +1 -0
  66. package/lib/model/strategy/adapter/walletPass/locales.js +54 -0
  67. package/lib/model/strategy/adapter/walletPass/type.d.ts +169 -0
  68. package/lib/model/strategy/adapter/walletPass/type.js +17 -0
  69. package/lib/model/strategy/adapter/walletPass/utils.d.ts +50 -0
  70. package/lib/model/strategy/adapter/walletPass/utils.js +720 -0
  71. package/lib/model/strategy/index.d.ts +94 -0
  72. package/lib/model/strategy/index.js +413 -0
  73. package/lib/model/strategy/strategy-example.d.ts +5 -0
  74. package/lib/model/strategy/strategy-example.js +318 -0
  75. package/lib/model/strategy/type.d.ts +228 -0
  76. package/lib/model/strategy/type.js +44 -0
  77. package/lib/modules/Cart/types.d.ts +2 -0
  78. package/lib/modules/Cart/utils/cartProduct.js +9 -0
  79. package/lib/modules/Discount/types.d.ts +16 -0
  80. package/lib/modules/Payment/index.d.ts +2 -1
  81. package/lib/modules/Payment/index.js +1 -0
  82. package/lib/modules/Payment/utils.js +3 -0
  83. package/lib/modules/Payment/walletpass.d.ts +23 -0
  84. package/lib/modules/Payment/walletpass.js +94 -17
  85. package/lib/modules/Product/index.d.ts +1 -1
  86. package/lib/modules/Rules/index.d.ts +9 -5
  87. package/lib/modules/Rules/index.js +671 -262
  88. package/lib/modules/Rules/types.d.ts +1 -0
  89. package/lib/modules/Summary/types.d.ts +2 -0
  90. package/lib/modules/Summary/utils.d.ts +6 -0
  91. package/lib/modules/Summary/utils.js +15 -0
  92. package/lib/plugins/window.d.ts +2 -0
  93. package/lib/solution/BookingByStep/index.d.ts +3 -2
  94. package/lib/solution/BookingTicket/index.d.ts +1 -1
  95. package/lib/solution/Checkout/index.js +3 -1
  96. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  97. package/lib/solution/ShopDiscount/index.js +22 -8
  98. package/lib/solution/ShopDiscount/types.d.ts +1 -0
  99. package/lib/solution/ShopDiscount/utils.js +10 -6
  100. package/package.json +1 -1
@@ -31,7 +31,6 @@ import { getProductOriginTotalPrice, getProductTotalPrice } from "../Cart/utils"
31
31
  import Decimal from 'decimal.js';
32
32
  import { isBoolean } from 'lodash-es';
33
33
  import dayjs from 'dayjs';
34
-
35
34
  // 临时变量
36
35
  var flatItem;
37
36
  export var RulesModule = /*#__PURE__*/function (_BaseModule) {
@@ -44,6 +43,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
44
43
  _defineProperty(_assertThisInitialized(_this), "defaultName", 'rules');
45
44
  _defineProperty(_assertThisInitialized(_this), "defaultVersion", '1.0.0');
46
45
  _defineProperty(_assertThisInitialized(_this), "store", void 0);
46
+ _defineProperty(_assertThisInitialized(_this), "window", void 0);
47
+ // WindowPlugin 实例
47
48
  _defineProperty(_assertThisInitialized(_this), "hooks", void 0);
48
49
  _this.hooks = {};
49
50
  return _this;
@@ -58,7 +59,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
58
59
  this.core = core;
59
60
  this.hooks = options === null || options === void 0 ? void 0 : options.hooks;
60
61
  this.store = options === null || options === void 0 ? void 0 : options.store;
61
- case 3:
62
+ this.window = core.getPlugin('window');
63
+ case 4:
62
64
  case "end":
63
65
  return _context.stop();
64
66
  }
@@ -113,6 +115,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
113
115
  // 最终直接匹配 holder 是否相同
114
116
  return (productHolderId || orderHolderId) === discount.holder.holder_id;
115
117
  }
118
+ }, {
119
+ key: "getWalletPassEvaluator",
120
+ value: function getWalletPassEvaluator() {
121
+ var _this$window$getWalle, _this$window;
122
+ return (_this$window$getWalle = (_this$window = this.window).getWalletPassEvaluator) === null || _this$window$getWalle === void 0 ? void 0 : _this$window$getWalle.call(_this$window);
123
+ }
116
124
 
117
125
  // 判断discountList 是否可以对当前productList生效
118
126
  }, {
@@ -122,6 +130,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
122
130
  var oldDiscountList = _ref.oldDiscountList,
123
131
  newDiscountList = _ref.newDiscountList,
124
132
  productList = _ref.productList,
133
+ orderTotalAmount = _ref.orderTotalAmount,
125
134
  holders = _ref.holders,
126
135
  isFormSubject = _ref.isFormSubject;
127
136
  // 首先检查是否有新的优惠券可应用
@@ -156,6 +165,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
156
165
  var result = this.calcDiscount({
157
166
  discountList: mergedDiscountList,
158
167
  productList: _toConsumableArray(productList),
168
+ orderTotalAmount: orderTotalAmount,
159
169
  holders: holders,
160
170
  isFormSubject: isFormSubject
161
171
  }, {
@@ -289,7 +299,15 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
289
299
  var discountList = _ref2.discountList,
290
300
  productList = _ref2.productList,
291
301
  holders = _ref2.holders,
292
- isFormSubject = _ref2.isFormSubject;
302
+ isFormSubject = _ref2.isFormSubject,
303
+ orderTotalAmount = _ref2.orderTotalAmount;
304
+ // 识别出来是不是在编辑的界面里又新增了商品
305
+ // 这种情况下,如果有可用的优惠券,也会自动勾选上
306
+ var isEditModeAddNewProduct = productList.find(function (n) {
307
+ return n.booking_id;
308
+ }) && productList.find(function (n) {
309
+ return !n.booking_id;
310
+ });
293
311
  var editModeDiscount = [];
294
312
  var addModeDiscount = [];
295
313
  discountList.forEach(function (discount) {
@@ -503,14 +521,6 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
503
521
  // 🔥 扁平化商品列表(包含主商品和bundle子商品)
504
522
  var flattenedList = flattenProductsWithBundle(productList);
505
523
 
506
- // 识别出来是不是在编辑的界面里又新增了商品
507
- // 这种情况下,如果有可用的优惠券,也会自动勾选上
508
- var isEditModeAddNewProduct = flattenedList.find(function (n) {
509
- return n.booking_id;
510
- }) && flattenedList.find(function (n) {
511
- return !n.booking_id;
512
- });
513
-
514
524
  // 对扁平化后的列表按价格降序排序(用于应用优惠券时优先选择高价商品)
515
525
  var sortedFlattenedList = flattenedList.sort(function (a, b) {
516
526
  var _ref3, _a$original_price, _ref4, _b$original_price;
@@ -538,6 +548,57 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
538
548
  return priceB.minus(priceA).toNumber();
539
549
  });
540
550
 
551
+ // 🔥 为每个折扣卡/商品券执行策略检查并附加config
552
+ var evaluator = this.getWalletPassEvaluator();
553
+ if (evaluator) {
554
+ addModeDiscount.forEach(function (discount) {
555
+ var discountType = discount.tag || discount.type;
556
+ // 只对 good_pass 和 discount_card 类型执行策略检查
557
+ if (['good_pass', 'discount_card', 'product_discount_card'].includes(discountType)) {
558
+ var _discount$limited_rel, _discount$limited_rel2;
559
+ // 转换 discount 为 Voucher 格式
560
+ var voucher = {
561
+ id: discount.id,
562
+ amount: Number(discount.par_value || 0),
563
+ balance: Number(discount.balance || 0),
564
+ type: discountType,
565
+ product_id: discount.product_id,
566
+ unified_available_status: 1,
567
+ available_product_type: (_discount$limited_rel = discount.limited_relation_product_data) === null || _discount$limited_rel === void 0 ? void 0 : _discount$limited_rel.type,
568
+ available_product_ids: (_discount$limited_rel2 = discount.limited_relation_product_data) === null || _discount$limited_rel2 === void 0 ? void 0 : _discount$limited_rel2.product_ids
569
+ };
570
+
571
+ // 转换 sortedFlattenedList 为 Product 格式
572
+ var productsForEvaluate = sortedFlattenedList.map(function (item) {
573
+ return {
574
+ product_id: item.id,
575
+ price: item.price || 0,
576
+ quantity: item.quantity || item.num || 1,
577
+ selling_price: item.price || 0
578
+ };
579
+ });
580
+
581
+ // 调用策略检查
582
+ var result = evaluator.checkVoucherAvailability({
583
+ orderTotalAmount: orderTotalAmount,
584
+ products: productsForEvaluate,
585
+ vouchers: [voucher]
586
+ });
587
+
588
+ // 将 config 附加到 discount 对象
589
+ if (result.isAvailable) {
590
+ discount.config = _objectSpread(_objectSpread({}, result.config), {}, {
591
+ isAvailable: true
592
+ });
593
+ } else {
594
+ discount.config = {
595
+ isAvailable: false
596
+ };
597
+ }
598
+ }
599
+ });
600
+ }
601
+
541
602
  /**
542
603
  // 对productList按价格降序排序(用于应用优惠券时优先选择高价商品) 价格相同时使用quantity 排序
543
604
  const sortedProductList = [...productList].sort((a, b) => {
@@ -558,6 +619,22 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
558
619
  // 标记已使用的优惠券
559
620
  var usedDiscounts = new Map();
560
621
 
622
+ // 🔥 统计每个 product_id(商品券商品id)已使用的数量,用于 maxUsagePerOrder 限制
623
+ var usedProductIdCounts = new Map();
624
+
625
+ // 🔥 统计每张折扣卡的 applicableProductLimit 已使用次数(跨商品全局计数)
626
+ var usedDiscountCardLimitCounts = new Map();
627
+
628
+ // 🔥 预先将 editModeDiscount 中的折扣卡计入 applicableProductLimit 已使用次数
629
+ editModeDiscount.forEach(function (discount) {
630
+ var discountType = discount.tag || discount.type;
631
+ if (['discount_card', 'product_discount_card'].includes(discountType)) {
632
+ var _discount$metadata4;
633
+ var currentCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
634
+ usedDiscountCardLimitCounts.set(discount.id, currentCount + (((_discount$metadata4 = discount.metadata) === null || _discount$metadata4 === void 0 ? void 0 : _discount$metadata4.num) || 1));
635
+ }
636
+ });
637
+
561
638
  // 记录每个优惠券适用的商品ID
562
639
  var discountApplicability = new Map();
563
640
 
@@ -787,7 +864,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
787
864
  originProduct = flatItem.originProduct;
788
865
  }
789
866
  addModeDiscount.forEach(function (discount) {
790
- var _product6, _product7, _product8, _product9, _flatItem$bundleItem3, _flatItem$bundleItem4;
867
+ var _product6, _product7, _product8, _product9, _flatItem$bundleItem3, _flatItem$bundleItem4, _discount$config;
791
868
  var limitedData = discount === null || discount === void 0 ? void 0 : discount.limited_relation_product_data;
792
869
  // 拿到discount配置的holder信息 product信息 product.holder 加在 isLimitedProduct
793
870
  var _tempVar = (flatItem === null || flatItem === void 0 ? void 0 : flatItem.type) === 'bundle' ? flatItem === null || flatItem === void 0 ? void 0 : flatItem.parentProduct : flatItem === null || flatItem === void 0 ? void 0 : flatItem.product;
@@ -798,7 +875,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
798
875
  var timeLimit = true;
799
876
  timeLimit = !!filterDiscountListByBookingTime([discount], (((_product6 = product) === null || _product6 === void 0 ? void 0 : _product6.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
800
877
  // 是符合折扣的商品
801
- var isLimitedProduct = (limitedData.type === 'product_all' || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
878
+ var isLimitedProduct = (limitedData.type === 'product_all' && limitedData.filter !== 1 || limitedData.type === 'product_all' && limitedData.filter === 1 && !limitedData.exclude_product_ids.includes(product.id) || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
802
879
 
803
880
  // 编辑的商品 使用了优惠券不可用
804
881
  var isAvailableProduct = flatItem.type === 'main' ? !((_product7 = product) !== null && _product7 !== void 0 && _product7.booking_id && (_product8 = product) !== null && _product8 !== void 0 && (_product8 = _product8.discount_list) !== null && _product8 !== void 0 && _product8.length && (_product9 = product) !== null && _product9 !== void 0 && (_product9 = _product9.discount_list) !== null && _product9 !== void 0 && _product9.every(function (discount) {
@@ -811,8 +888,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
811
888
  var isBundleAvailable = _this3.checkPackageSubItemUsageRules(discount, flatItem);
812
889
 
813
890
  // 判断优惠券是否适用于该商品
814
- if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable) {
815
- var _discountApplicabilit, _discount$metadata4, _discount$metadata5;
891
+ if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && (_discount$config = discount.config) !== null && _discount$config !== void 0 && _discount$config.isAvailable) {
892
+ var _discountApplicabilit, _discount$metadata5, _discount$metadata6;
816
893
  // 记录此优惠券适用的商品
817
894
  (_discountApplicabilit = discountApplicability.get(discount.id)) === null || _discountApplicabilit === void 0 || _discountApplicabilit.push(product.id);
818
895
 
@@ -828,14 +905,15 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
828
905
  type: discountType,
829
906
  tag: discountType,
830
907
  discount: {
831
- discount_card_type: discount === null || discount === void 0 || (_discount$metadata4 = discount.metadata) === null || _discount$metadata4 === void 0 ? void 0 : _discount$metadata4.discount_card_type,
908
+ discount_card_type: discount === null || discount === void 0 || (_discount$metadata5 = discount.metadata) === null || _discount$metadata5 === void 0 ? void 0 : _discount$metadata5.discount_card_type,
832
909
  fixed_amount: product.price,
833
- discount_calculation_mode: discount === null || discount === void 0 || (_discount$metadata5 = discount.metadata) === null || _discount$metadata5 === void 0 ? void 0 : _discount$metadata5.discount_calculation_mode,
910
+ discount_calculation_mode: discount === null || discount === void 0 || (_discount$metadata6 = discount.metadata) === null || _discount$metadata6 === void 0 ? void 0 : _discount$metadata6.discount_calculation_mode,
834
911
  resource_id: discount.id,
835
912
  title: discount.format_title,
836
913
  original_amount: product.price || product.origin_total,
837
914
  pre_value: discount.par_value,
838
- product_id: originProduct.id
915
+ product_id: originProduct.id,
916
+ discount_product_id: discount.product_id
839
917
  },
840
918
  metadata: {
841
919
  num: num,
@@ -854,7 +932,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
854
932
  // 然后再处理应用哪些优惠券,此时只考虑filteredDiscountList中的优惠券
855
933
  // 🔥 使用扁平化后的列表进行处理
856
934
  sortedFlattenedList.forEach(function (flatItem, index) {
857
- var _product10, _product$discount_lis2, _product11;
935
+ var _product10, _product$discount_lis2, _product11, _selectedDiscount$con;
858
936
  // 获取商品数据
859
937
  var product, originProduct;
860
938
  if (flatItem.type === 'main') {
@@ -896,6 +974,16 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
896
974
  // 找到适用于此商品的所有优惠券,仅考虑isSelected不为false的优惠券
897
975
  var applicableDiscounts = sortedDiscountList.filter(function (discount) {
898
976
  var _product$discount_lis3, _product$discount_lis4;
977
+ // 🔥 检查策略可用性(针对 good_pass 和折扣卡)
978
+ var discountType = discount.tag || discount.type;
979
+ if (['good_pass', 'discount_card', 'product_discount_card'].includes(discountType)) {
980
+ var _discount$config2;
981
+ // 如果策略检查后没有config,说明不可用
982
+ if (discount.config === undefined || !(discount !== null && discount !== void 0 && (_discount$config2 = discount.config) !== null && _discount$config2 !== void 0 && _discount$config2.isAvailable)) {
983
+ return false;
984
+ }
985
+ }
986
+
899
987
  // 如果商品价格为 0,其实不需要使用任何优惠券,直接 return true
900
988
  // 商品券时主商品价格为0不可用
901
989
  if ((Number(product.price) <= 0 || !product.price) && !((_product$discount_lis3 = product.discount_list) !== null && _product$discount_lis3 !== void 0 && _product$discount_lis3.length) && (discount.tag || discount.type) === 'good_pass') return false;
@@ -908,8 +996,37 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
908
996
  // 如果优惠券已被使用,则跳过
909
997
  var targetUsedDiscounts = usedDiscounts.get(discount.id);
910
998
  if (targetUsedDiscounts && (discount.tag || discount.type) === 'good_pass') return false;
911
- var limitedData = discount.limited_relation_product_data;
912
999
 
1000
+ // 🔥 检查 maxUsagePerOrder 限制:同一 product_id 的商品券使用数量不能超过配置值
1001
+ if ((discount.tag || discount.type) === 'good_pass') {
1002
+ var _discount$config3;
1003
+ var maxUsagePerOrder = (_discount$config3 = discount.config) === null || _discount$config3 === void 0 ? void 0 : _discount$config3.maxUsagePerOrder;
1004
+ if (maxUsagePerOrder && maxUsagePerOrder > 0) {
1005
+ var currentUsedCount = usedProductIdCounts.get(discount.product_id) || 0;
1006
+ if (currentUsedCount >= maxUsagePerOrder) {
1007
+ return false;
1008
+ }
1009
+ }
1010
+ }
1011
+
1012
+ // 🔥 检查折扣卡的 applicableProductLimit 限制:折扣卡可使用的最大次数(跨商品全局)
1013
+ var discountTypeForLimit = discount.tag || discount.type;
1014
+ if (['discount_card', 'product_discount_card'].includes(discountTypeForLimit)) {
1015
+ var _discount$config4;
1016
+ var applicableProductLimitConfig = ((_discount$config4 = discount.config) === null || _discount$config4 === void 0 ? void 0 : _discount$config4.applicableProductLimit) || 0;
1017
+ if (applicableProductLimitConfig > 0) {
1018
+ var currentUsedLimitCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
1019
+ if (currentUsedLimitCount >= applicableProductLimitConfig) {
1020
+ return false;
1021
+ }
1022
+ }
1023
+ }
1024
+ var limitedData = discount.limited_relation_product_data;
1025
+ var timeLimit = true;
1026
+ timeLimit = !!filterDiscountListByBookingTime([discount], (product.startDate || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
1027
+ if (!timeLimit) {
1028
+ return false;
1029
+ }
913
1030
  // 拿到discount配置的holder信息 product信息 product.holder 不可用return false
914
1031
  var _tempVar = (flatItem === null || flatItem === void 0 ? void 0 : flatItem.type) === 'bundle' ? flatItem === null || flatItem === void 0 ? void 0 : flatItem.parentProduct : flatItem === null || flatItem === void 0 ? void 0 : flatItem.product;
915
1032
  var isHolderMatch = _this3.checkHolderMatch(discount, {
@@ -918,14 +1035,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
918
1035
  }, holders);
919
1036
  // 如果 holder 不匹配,则不适用
920
1037
  if (!isHolderMatch) return false;
921
- var timeLimit = true;
922
- timeLimit = !!filterDiscountListByBookingTime([discount], (product.startDate || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
923
- if (!timeLimit) {
924
- return false;
925
- }
926
1038
 
927
1039
  // 判断优惠券是否适用于该商品
928
1040
  if (limitedData.type === 'product_all') {
1041
+ if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
1042
+ return false;
1043
+ }
929
1044
  // 检查 package_sub_item_usage_rules
930
1045
  if (!_this3.checkPackageSubItemUsageRules(discount, flatItem)) {
931
1046
  return false;
@@ -1058,22 +1173,23 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1058
1173
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion')
1059
1174
  }))]);
1060
1175
  } else {
1061
- var _ref8, _product$_promotion$f, _product13, _product$origin_total, _product$main_product, _product$main_product2;
1176
+ var _ref8, _product$_promotion$f, _product13, _product$origin_total, _product$price2;
1062
1177
  var total = product.inPromotion ? (_ref8 = (_product$_promotion$f = (_product13 = product) === null || _product13 === void 0 || (_product13 = _product13._promotion) === null || _product13 === void 0 ? void 0 : _product13.finalPrice) !== null && _product$_promotion$f !== void 0 ? _product$_promotion$f : product.origin_total) !== null && _ref8 !== void 0 ? _ref8 : product.total : (_product$origin_total = product.origin_total) !== null && _product$origin_total !== void 0 ? _product$origin_total : product.total;
1178
+ var main_product_selling_price = (_product$price2 = product.price) !== null && _product$price2 !== void 0 ? _product$price2 : product.main_product_selling_price;
1063
1179
  if ((product.discount_list || []).some(function (item) {
1064
1180
  return item.type === 'promotion';
1065
- })) {
1066
- var _product$total;
1181
+ }) || isBoolean(product.vouchersApplicable) && !product.vouchersApplicable) {
1182
+ var _product$total, _product$main_product;
1067
1183
  total = (_product$total = product.total) !== null && _product$total !== void 0 ? _product$total : product.origin_total;
1184
+ main_product_selling_price = (_product$main_product = product.main_product_selling_price) !== null && _product$main_product !== void 0 ? _product$main_product : main_product_selling_price;
1068
1185
  }
1069
1186
  processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {
1070
- price: product.price,
1071
- main_product_selling_price: (_product$main_product = product.main_product_selling_price) !== null && _product$main_product !== void 0 ? _product$main_product : product.price
1187
+ price: product.price
1072
1188
  } : {
1073
1189
  _id: product._id.split('___')[0] + '___' + index,
1074
1190
  total: total,
1075
1191
  price: product.price,
1076
- main_product_selling_price: (_product$main_product2 = product.main_product_selling_price) !== null && _product$main_product2 !== void 0 ? _product$main_product2 : product.price
1192
+ main_product_selling_price: main_product_selling_price
1077
1193
  }), {}, {
1078
1194
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion')
1079
1195
  }))]);
@@ -1093,15 +1209,39 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1093
1209
  return;
1094
1210
  }
1095
1211
 
1096
- // 是否需要拆分(商品券需要拆分)
1097
- var isNeedSplit = (selectedDiscount.tag || selectedDiscount.type) === 'good_pass';
1212
+ // 是否需要拆分(商品券需要拆分,折扣卡在 applicableProductLimit > 0 时也需要拆分)
1213
+ var discountType = selectedDiscount.tag || selectedDiscount.type;
1214
+ var isGoodPass = discountType === 'good_pass';
1215
+ var isDiscountCard = ['discount_card', 'product_discount_card'].includes(discountType);
1216
+ var applicableProductLimit = ((_selectedDiscount$con = selectedDiscount.config) === null || _selectedDiscount$con === void 0 ? void 0 : _selectedDiscount$con.applicableProductLimit) || 0;
1217
+
1218
+ // 商品券始终需要拆分,折扣卡在 applicableProductLimit > 0 时需要拆分
1219
+ var isNeedSplit = isGoodPass || isDiscountCard && applicableProductLimit > 0;
1098
1220
 
1099
1221
  // 需要拆分出来的数量
1100
1222
  var totalQuantity = product.quantity || product.num || 1;
1101
1223
  var availableGoodPassCount = applicableDiscounts.filter(function (item) {
1102
1224
  return (item.tag || item.type) === 'good_pass';
1103
1225
  }).length;
1104
- var splitCount = isNeedSplit ? Math.min(totalQuantity, availableGoodPassCount) : 1;
1226
+
1227
+ // 🔥 计算最大使用次数限制
1228
+ var maxUsageLimit;
1229
+ if (isGoodPass) {
1230
+ // 商品券:使用 maxUsagePerOrder 限制
1231
+ maxUsageLimit = availableGoodPassCount;
1232
+ if (selectedDiscount.config && selectedDiscount.config.maxUsagePerOrder) {
1233
+ maxUsageLimit = Math.min(availableGoodPassCount, selectedDiscount.config.maxUsagePerOrder);
1234
+ }
1235
+ } else if (isDiscountCard && applicableProductLimit > 0) {
1236
+ // 折扣卡:使用 applicableProductLimit 限制(一个商品使用一次折扣卡算1次)
1237
+ // 需要减去已使用次数(跨商品全局计数)
1238
+ var usedLimitCount = usedDiscountCardLimitCounts.get(selectedDiscount.id) || 0;
1239
+ maxUsageLimit = Math.max(0, applicableProductLimit - usedLimitCount);
1240
+ } else {
1241
+ // 其他情况不拆分
1242
+ maxUsageLimit = 1;
1243
+ }
1244
+ var splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, maxUsageLimit) : 1;
1105
1245
  var arr = [];
1106
1246
 
1107
1247
  // 🔥 主商品和bundle子商品分别处理
@@ -1111,18 +1251,31 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1111
1251
  arr.push(_this3.hooks.setProduct(originProduct, {
1112
1252
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1113
1253
  quantity: totalQuantity - splitCount,
1114
- _id: product._id.split('___')[0]
1254
+ _id: product._id.split('___')[0],
1255
+ total: product.origin_total || product.total
1115
1256
  }));
1116
1257
  }
1117
1258
  for (var i = 0; i < splitCount; i++) {
1118
- var _originProduct, _selectedDiscount$met, _selectedDiscount$met2;
1119
- // 如果用过折扣卡,也就不存在拆分的情况了,这里直接使用上面计算出来的折扣卡
1120
- var _selectedDiscount = selectedDiscountCard || applicableDiscounts[i];
1259
+ var _originProduct, _currentSelectedDisco, _currentSelectedDisco2;
1260
+ // 商品券:每个拆分商品使用不同的商品券(从 applicableDiscounts 按索引取)
1261
+ // 折扣卡:所有拆分商品使用同一张折扣卡(selectedDiscountCard applicableDiscounts[0]
1262
+ var currentSelectedDiscount = isGoodPass ? selectedDiscountCard || applicableDiscounts[i] : selectedDiscountCard || applicableDiscounts[0];
1121
1263
  // 标记优惠券为已使用
1122
- usedDiscounts.set(_selectedDiscount.id, true);
1264
+ usedDiscounts.set(currentSelectedDiscount.id, true);
1265
+ // 🔥 更新 product_id 使用计数
1266
+ if ((currentSelectedDiscount.tag || currentSelectedDiscount.type) === 'good_pass') {
1267
+ var currentCount = usedProductIdCounts.get(currentSelectedDiscount.product_id) || 0;
1268
+ usedProductIdCounts.set(currentSelectedDiscount.product_id, currentCount + 1);
1269
+ }
1270
+ // 🔥 更新折扣卡 applicableProductLimit 使用计数(跨商品全局)
1271
+ var currentDiscountTypeForCount = currentSelectedDiscount.tag || currentSelectedDiscount.type;
1272
+ if (['discount_card', 'product_discount_card'].includes(currentDiscountTypeForCount)) {
1273
+ var currentLimitCount = usedDiscountCardLimitCounts.get(currentSelectedDiscount.id) || 0;
1274
+ usedDiscountCardLimitCounts.set(currentSelectedDiscount.id, currentLimitCount + 1);
1275
+ }
1123
1276
 
1124
1277
  // 记录实际应用了优惠券的商品信息
1125
- var appliedProducts = appliedDiscountProducts.get(_selectedDiscount.id) || [];
1278
+ var appliedProducts = appliedDiscountProducts.get(currentSelectedDiscount.id) || [];
1126
1279
 
1127
1280
  // 优先从 origin_total拿,可能会拿不到(比如用户端预约在没有配置 original_price 的情况下)
1128
1281
  var productOriginTotal = product.origin_total || product.total || 0;
@@ -1137,8 +1290,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1137
1290
 
1138
1291
  // 计算使用折扣卡/商品券以后,单个商品的总 total
1139
1292
  // 🔥 检查是否是 order_level 固定金额折扣卡
1140
- var isOrderLevel = isOrderLevelFixedAmountDiscount(_selectedDiscount);
1141
- var orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(_selectedDiscount.id) : null;
1293
+ var isOrderLevel = isOrderLevelFixedAmountDiscount(selectedDiscount);
1294
+ var orderLevelAllocation = isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
1142
1295
  var productAllocation = orderLevelAllocation === null || orderLevelAllocation === void 0 ? void 0 : orderLevelAllocation.get(flatItem._id);
1143
1296
  var targetProductTotal = void 0;
1144
1297
  var amount = void 0;
@@ -1150,35 +1303,40 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1150
1303
  targetProductTotal = Math.max(new Decimal(product.price).minus(amount).toNumber(), 0);
1151
1304
  } else {
1152
1305
  // item_level 或其他类型:使用原有逻辑
1153
- targetProductTotal = getDiscountAmount(_selectedDiscount, product.price, product.price);
1306
+ targetProductTotal = getDiscountAmount(currentSelectedDiscount, product.price, product.price);
1154
1307
  amount = new Decimal(product.price).minus(new Decimal(targetProductTotal)).toNumber();
1155
1308
  }
1156
- var discountType = _selectedDiscount.tag || _selectedDiscount.type;
1157
- var isGoodPass = discountType === 'good_pass';
1309
+ var currentDiscountType = currentSelectedDiscount.tag === 'product_discount_card' ? 'discount_card' : currentSelectedDiscount.tag;
1310
+
1311
+ // 计算实际折扣金额
1312
+ var actualDiscountAmount = new Decimal(product.price).minus(new Decimal(targetProductTotal)).toNumber();
1313
+ var currentIsGoodPass = currentDiscountType === 'good_pass';
1158
1314
  var discountDetail = {
1159
- amount: amount,
1160
- type: _selectedDiscount.tag === 'product_discount_card' ? 'discount_card' : discountType,
1315
+ amount: actualDiscountAmount,
1316
+ type: currentDiscountType,
1161
1317
  discount: {
1162
- discount_card_type: _selectedDiscount === null || _selectedDiscount === void 0 || (_selectedDiscount$met = _selectedDiscount.metadata) === null || _selectedDiscount$met === void 0 ? void 0 : _selectedDiscount$met.discount_card_type,
1163
- fixed_amount: amount,
1164
- discount_calculation_mode: _selectedDiscount === null || _selectedDiscount === void 0 || (_selectedDiscount$met2 = _selectedDiscount.metadata) === null || _selectedDiscount$met2 === void 0 ? void 0 : _selectedDiscount$met2.discount_calculation_mode,
1165
- resource_id: _selectedDiscount.id,
1166
- title: _selectedDiscount.format_title,
1318
+ discount_card_type: currentSelectedDiscount === null || currentSelectedDiscount === void 0 || (_currentSelectedDisco = currentSelectedDiscount.metadata) === null || _currentSelectedDisco === void 0 ? void 0 : _currentSelectedDisco.discount_card_type,
1319
+ fixed_amount: actualDiscountAmount,
1320
+ discount_calculation_mode: currentSelectedDiscount === null || currentSelectedDiscount === void 0 || (_currentSelectedDisco2 = currentSelectedDiscount.metadata) === null || _currentSelectedDisco2 === void 0 ? void 0 : _currentSelectedDisco2.discount_calculation_mode,
1321
+ resource_id: currentSelectedDiscount.id,
1322
+ title: currentSelectedDiscount.format_title,
1167
1323
  original_amount: product.price,
1168
1324
  product_id: originProduct.id,
1169
- percent: _selectedDiscount.par_value
1325
+ percent: currentSelectedDiscount.par_value,
1326
+ discount_product_id: currentSelectedDiscount.product_id
1170
1327
  },
1171
- // 前端使用的num数量,为了计算优惠金额
1172
- _num: isGoodPass ? 1 : product.num,
1328
+ // 前端使用的num数量,为了计算优惠金额(拆分时为1)
1329
+ _num: isNeedSplit ? 1 : product.num,
1330
+ config: currentSelectedDiscount === null || currentSelectedDiscount === void 0 ? void 0 : currentSelectedDiscount.config,
1173
1331
  metadata: _objectSpread({
1174
1332
  num: 1,
1175
- discount_rule_uncheck_flag: _selectedDiscount === null || _selectedDiscount === void 0 ? void 0 : _selectedDiscount.discount_rule_uncheck_flag
1333
+ discount_rule_uncheck_flag: selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.discount_rule_uncheck_flag
1176
1334
  }, productDiscountDifference !== undefined && {
1177
1335
  product_discount_difference: productDiscountDifference
1178
1336
  })
1179
1337
  };
1180
1338
  appliedProducts.push(discountDetail);
1181
- appliedDiscountProducts.set(_selectedDiscount.id, appliedProducts);
1339
+ appliedDiscountProducts.set(currentSelectedDiscount.id, appliedProducts);
1182
1340
  var _total = targetProductTotal;
1183
1341
  if (product.options) {
1184
1342
  _total = product.options.reduce(function (accumulator, currentValue) {
@@ -1193,7 +1351,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1193
1351
  if (product.isClient) {
1194
1352
  arr.push(_this3.hooks.setProduct(originProduct, {
1195
1353
  discount_list: [discountDetail],
1196
- price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
1354
+ price: currentIsGoodPass ? product.price - discountDetail.amount : product.price,
1197
1355
  quantity: isNeedSplit ? 1 : product.quantity,
1198
1356
  origin_total: getProductOriginTotalPrice({
1199
1357
  product: {
@@ -1204,15 +1362,15 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1204
1362
  }),
1205
1363
  variant: originProduct._productInit.variant,
1206
1364
  original_price: new Decimal(product.price || 0).toNumber(),
1207
- total: _total
1365
+ total: targetProductTotal
1208
1366
  }));
1209
1367
  } else {
1210
1368
  arr.push(_this3.hooks.setProduct(originProduct, {
1211
1369
  discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion').concat([discountDetail]),
1212
- _id: product._id.split('___')[0] + "___" + _selectedDiscount.id + index,
1213
- price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
1370
+ _id: product._id.split('___')[0] + '___' + currentSelectedDiscount.id + '_' + i + '_' + index,
1371
+ price: currentIsGoodPass ? 0 : product.price,
1214
1372
  quantity: isNeedSplit ? 1 : product.quantity,
1215
- total: _total,
1373
+ total: targetProductTotal,
1216
1374
  origin_total: productOriginTotal,
1217
1375
  main_product_selling_price: targetProductTotal
1218
1376
  }));
@@ -1220,80 +1378,336 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1220
1378
  }
1221
1379
  processedProductsMap.set(product._id, arr);
1222
1380
  } else {
1223
- // 🔥 bundle子商品:支持拆分
1381
+ // 🔥 bundle子商品:支持拆分(商品券和折扣卡在 applicableProductLimit > 0 时都需要拆分)
1224
1382
  var processedItems = [];
1225
1383
  if (isNeedSplit) {
1226
- // 商品券:需要拆分数量
1384
+ // 需要拆分数量(商品券或折扣卡有 applicableProductLimit 限制)
1227
1385
  var discountNum = splitCount;
1228
1386
  var normalNum = totalQuantity - discountNum;
1229
1387
 
1230
- // 生成有折扣的商品(每张商品券对应 num: 1)
1388
+ // 生成有折扣的商品(每个拆分商品 num: 1)
1231
1389
  for (var _i = 0; _i < discountNum; _i++) {
1232
- var _selectedDiscount2$me;
1233
- var _selectedDiscount2 = applicableDiscounts[_i];
1234
- usedDiscounts.set(_selectedDiscount2.id, true);
1390
+ var _currentBundleDiscoun, _currentBundleDiscoun2;
1391
+ // 商品券:每个拆分商品使用不同的商品券
1392
+ // 折扣卡:所有拆分商品使用同一张折扣卡
1393
+ var currentBundleDiscount = isGoodPass ? selectedDiscountCard || applicableDiscounts[_i] : selectedDiscountCard || applicableDiscounts[0];
1394
+ usedDiscounts.set(currentBundleDiscount.id, true);
1395
+ // 🔥 更新 product_id 使用计数
1396
+ if ((currentBundleDiscount.tag || currentBundleDiscount.type) === 'good_pass') {
1397
+ var _currentCount = usedProductIdCounts.get(currentBundleDiscount.product_id) || 0;
1398
+ usedProductIdCounts.set(currentBundleDiscount.product_id, _currentCount + 1);
1399
+ }
1400
+ // 🔥 更新折扣卡 applicableProductLimit 使用计数(跨商品全局)
1401
+ var bundleDiscountTypeForCount = currentBundleDiscount.tag || currentBundleDiscount.type;
1402
+ if (['discount_card', 'product_discount_card'].includes(bundleDiscountTypeForCount)) {
1403
+ var currentBundleLimitCount = usedDiscountCardLimitCounts.get(currentBundleDiscount.id) || 0;
1404
+ usedDiscountCardLimitCounts.set(currentBundleDiscount.id, currentBundleLimitCount + 1);
1405
+ }
1235
1406
 
1236
1407
  // 🔥 生成唯一的 _id
1237
1408
  var uniqueId = "".concat(flatItem._id, "_split_").concat(_i);
1409
+
1410
+ // 计算折扣后的价格(使用 getDiscountAmount,内部已处理 maxDeductionAmount)
1411
+ var discountedPrice = getDiscountAmount(currentBundleDiscount, product.origin_total, product.origin_total);
1412
+ var bundleDiscountAmount = new Decimal(product.origin_total || 0).minus(discountedPrice).toNumber();
1413
+
1414
+ // 确定折扣类型
1415
+ var bundleDiscountType = currentBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : currentBundleDiscount.tag;
1238
1416
  var _discountDetail = {
1239
- amount: product.origin_total,
1240
- type: 'good_pass',
1417
+ amount: bundleDiscountAmount,
1418
+ type: bundleDiscountType,
1241
1419
  discount: {
1242
- fixed_amount: product.origin_total,
1243
- discount_calculation_mode: _selectedDiscount2 === null || _selectedDiscount2 === void 0 || (_selectedDiscount2$me = _selectedDiscount2.metadata) === null || _selectedDiscount2$me === void 0 ? void 0 : _selectedDiscount2$me.discount_calculation_mode,
1244
- resource_id: _selectedDiscount2.id,
1245
- title: _selectedDiscount2.format_title,
1420
+ discount_card_type: currentBundleDiscount === null || currentBundleDiscount === void 0 || (_currentBundleDiscoun = currentBundleDiscount.metadata) === null || _currentBundleDiscoun === void 0 ? void 0 : _currentBundleDiscoun.discount_card_type,
1421
+ discount_calculation_mode: currentBundleDiscount === null || currentBundleDiscount === void 0 || (_currentBundleDiscoun2 = currentBundleDiscount.metadata) === null || _currentBundleDiscoun2 === void 0 ? void 0 : _currentBundleDiscoun2.discount_calculation_mode,
1422
+ fixed_amount: bundleDiscountAmount,
1423
+ resource_id: currentBundleDiscount.id,
1424
+ title: currentBundleDiscount.format_title,
1246
1425
  original_amount: product.origin_total,
1247
- product_id: product.id
1426
+ product_id: product.id,
1427
+ percent: currentBundleDiscount.par_value,
1428
+ discount_product_id: currentBundleDiscount.product_id
1248
1429
  },
1249
1430
  metadata: {
1250
1431
  // 🔥 使用拆分后的唯一 _id
1251
1432
  custom_product_bundle_map_id: uniqueId,
1252
- discount_rule_uncheck_flag: _selectedDiscount2 === null || _selectedDiscount2 === void 0 ? void 0 : _selectedDiscount2.discount_rule_uncheck_flag,
1433
+ discount_rule_uncheck_flag: selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
1253
1434
  num: 1
1254
1435
  },
1255
- _num: 1
1436
+ _num: 1,
1437
+ config: currentBundleDiscount === null || currentBundleDiscount === void 0 ? void 0 : currentBundleDiscount.config
1256
1438
  };
1257
1439
 
1258
1440
  // 记录实际应用的折扣
1259
- var _appliedProducts = appliedDiscountProducts.get(_selectedDiscount2.id) || [];
1441
+ var _appliedProducts = appliedDiscountProducts.get(currentBundleDiscount.id) || [];
1260
1442
  _appliedProducts.push(_discountDetail);
1261
- appliedDiscountProducts.set(_selectedDiscount2.id, _appliedProducts);
1443
+ appliedDiscountProducts.set(currentBundleDiscount.id, _appliedProducts);
1262
1444
  processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1263
1445
  // 🔥 使用唯一的 _id
1264
1446
  _id: uniqueId,
1265
1447
  num: 1,
1266
1448
  quantity: 1,
1267
- price: 0,
1268
- // 商品券价格为0
1269
- total: 0,
1449
+ price: discountedPrice,
1450
+ // 折扣后的价格
1451
+ total: discountedPrice,
1270
1452
  discount_list: _this3.filterDiscountListByType(flatItem.discount_list, 'promotion').concat([_discountDetail]),
1271
1453
  processed: true,
1272
- _discountId: _selectedDiscount2.id
1454
+ _discountId: currentBundleDiscount.id
1273
1455
  }));
1274
1456
  }
1275
1457
 
1276
- // 生成无折扣的商品(剩余数量)
1277
- if (normalNum > 0) {
1278
- processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1279
- // 🔥 为剩余商品生成唯一的 _id
1280
- _id: "".concat(flatItem._id, "_split_rest"),
1281
- num: normalNum,
1282
- quantity: normalNum,
1283
- discount_list: _this3.filterDiscountListByType(flatItem.discount_list, 'promotion'),
1284
- processed: true
1285
- }));
1458
+ // 🔥 对拆分后的剩余商品继续匹配其他可用折扣(而不是等到下次执行才应用)
1459
+ var remainingNum = normalNum;
1460
+ var continueSplitIndex = discountNum;
1461
+ while (remainingNum > 0) {
1462
+ var _nextSelectedDiscount;
1463
+ // 重新查找适用于剩余商品的可用折扣(已使用的会被自动过滤掉)
1464
+ var nextApplicableDiscounts = sortedDiscountList.filter(function (nextDiscount) {
1465
+ var _product$discount_lis10;
1466
+ var nextDiscountType = nextDiscount.tag || nextDiscount.type;
1467
+ // 检查策略可用性
1468
+ if (['good_pass', 'discount_card', 'product_discount_card'].includes(nextDiscountType)) {
1469
+ var _nextDiscount$config;
1470
+ if (nextDiscount.config === undefined || !(nextDiscount !== null && nextDiscount !== void 0 && (_nextDiscount$config = nextDiscount.config) !== null && _nextDiscount$config !== void 0 && _nextDiscount$config.isAvailable)) {
1471
+ return false;
1472
+ }
1473
+ }
1474
+ // 折扣卡时总价为0时不可用
1475
+ if ((Number(product.total) <= 0 || !product.total) && !((_product$discount_lis10 = product.discount_list) !== null && _product$discount_lis10 !== void 0 && _product$discount_lis10.find(function (n) {
1476
+ var _n$discount2;
1477
+ return ((_n$discount2 = n.discount) === null || _n$discount2 === void 0 ? void 0 : _n$discount2.resource_id) === nextDiscount.id;
1478
+ })) && nextDiscountType !== 'good_pass') return false;
1479
+
1480
+ // 商品券已被使用则跳过
1481
+ if (usedDiscounts.get(nextDiscount.id) && nextDiscountType === 'good_pass') return false;
1482
+
1483
+ // 检查 maxUsagePerOrder 限制
1484
+ if (nextDiscountType === 'good_pass') {
1485
+ var _nextDiscount$config2;
1486
+ var maxUsagePerOrder = (_nextDiscount$config2 = nextDiscount.config) === null || _nextDiscount$config2 === void 0 ? void 0 : _nextDiscount$config2.maxUsagePerOrder;
1487
+ if (maxUsagePerOrder && maxUsagePerOrder > 0) {
1488
+ var currentUsedCount = usedProductIdCounts.get(nextDiscount.product_id) || 0;
1489
+ if (currentUsedCount >= maxUsagePerOrder) {
1490
+ return false;
1491
+ }
1492
+ }
1493
+ }
1494
+
1495
+ // 检查折扣卡的 applicableProductLimit 限制
1496
+ if (['discount_card', 'product_discount_card'].includes(nextDiscountType)) {
1497
+ var _nextDiscount$config3;
1498
+ var limitConfig = ((_nextDiscount$config3 = nextDiscount.config) === null || _nextDiscount$config3 === void 0 ? void 0 : _nextDiscount$config3.applicableProductLimit) || 0;
1499
+ if (limitConfig > 0) {
1500
+ var currentUsedLimitCount = usedDiscountCardLimitCounts.get(nextDiscount.id) || 0;
1501
+ if (currentUsedLimitCount >= limitConfig) {
1502
+ return false;
1503
+ }
1504
+ }
1505
+ }
1506
+ var limitedData = nextDiscount.limited_relation_product_data;
1507
+ if (limitedData.type === 'product_all') {
1508
+ if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
1509
+ return false;
1510
+ }
1511
+ if (!_this3.checkPackageSubItemUsageRules(nextDiscount, flatItem)) {
1512
+ return false;
1513
+ }
1514
+ return true;
1515
+ } else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
1516
+ if (!_this3.checkPackageSubItemUsageRules(nextDiscount, flatItem)) {
1517
+ return false;
1518
+ }
1519
+ return true;
1520
+ }
1521
+ return false;
1522
+ });
1523
+
1524
+ // 没有更多可用折扣,剩余商品无折扣存储
1525
+ if (nextApplicableDiscounts.length === 0) {
1526
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1527
+ _id: "".concat(flatItem._id, "_split_rest"),
1528
+ num: remainingNum,
1529
+ quantity: remainingNum,
1530
+ discount_list: [],
1531
+ processed: true
1532
+ }));
1533
+ break;
1534
+ }
1535
+
1536
+ // 选择最优折扣
1537
+ var nextSelectedDiscountCard = nextApplicableDiscounts.find(function (n) {
1538
+ return n.isScan && n.isSelected && (n.tag || n.type) !== 'good_pass';
1539
+ });
1540
+ var nextSelectedDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
1541
+
1542
+ // 判断新折扣是否需要拆分
1543
+ var nextDiscType = nextSelectedDiscount.tag || nextSelectedDiscount.type;
1544
+ var nextIsGoodPass = nextDiscType === 'good_pass';
1545
+ var nextIsDiscountCard = ['discount_card', 'product_discount_card'].includes(nextDiscType);
1546
+ var nextApplicableProductLimit = ((_nextSelectedDiscount = nextSelectedDiscount.config) === null || _nextSelectedDiscount === void 0 ? void 0 : _nextSelectedDiscount.applicableProductLimit) || 0;
1547
+ var nextIsNeedSplit = nextIsGoodPass || nextIsDiscountCard && nextApplicableProductLimit > 0;
1548
+ if (!nextIsNeedSplit) {
1549
+ var _nextBundleDiscount$m, _flatItem$parentProdu9;
1550
+ // 🔥 不需要拆分:直接应用折扣到所有剩余商品
1551
+ var nextBundleDiscount = nextSelectedDiscountCard || nextApplicableDiscounts[0];
1552
+ usedDiscounts.set(nextBundleDiscount.id, true);
1553
+ if ((nextBundleDiscount.tag || nextBundleDiscount.type) === 'good_pass') {
1554
+ var curCount = usedProductIdCounts.get(nextBundleDiscount.product_id) || 0;
1555
+ usedProductIdCounts.set(nextBundleDiscount.product_id, curCount + 1);
1556
+ }
1557
+ var nextNoSplitType = nextBundleDiscount.tag || nextBundleDiscount.type;
1558
+ if (['discount_card', 'product_discount_card'].includes(nextNoSplitType)) {
1559
+ var _curCount = usedDiscountCardLimitCounts.get(nextBundleDiscount.id) || 0;
1560
+ usedDiscountCardLimitCounts.set(nextBundleDiscount.id, _curCount + remainingNum);
1561
+ }
1562
+ var nextOriginTotal = product.original_price || product.price || 0;
1563
+ var nextTargetTotal = getDiscountAmount(nextBundleDiscount, nextOriginTotal, nextOriginTotal);
1564
+ var nextDiscountAmount = new Decimal(nextOriginTotal).minus(nextTargetTotal).toNumber();
1565
+ var nextUniqueId = "".concat(flatItem._id, "_split_").concat(continueSplitIndex);
1566
+ var nextBundleDiscType = nextBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : nextBundleDiscount.tag;
1567
+ var nextDiscountDetail = {
1568
+ amount: nextDiscountAmount * remainingNum,
1569
+ type: nextBundleDiscType,
1570
+ discount: {
1571
+ discount_card_type: nextBundleDiscount === null || nextBundleDiscount === void 0 || (_nextBundleDiscount$m = nextBundleDiscount.metadata) === null || _nextBundleDiscount$m === void 0 ? void 0 : _nextBundleDiscount$m.discount_card_type,
1572
+ fixed_amount: nextDiscountAmount,
1573
+ resource_id: nextBundleDiscount.id,
1574
+ title: nextBundleDiscount.format_title,
1575
+ original_amount: product.original_price,
1576
+ product_id: product.id,
1577
+ percent: nextBundleDiscount.par_value,
1578
+ discount_product_id: nextBundleDiscount.product_id
1579
+ },
1580
+ metadata: {
1581
+ custom_product_bundle_map_id: nextUniqueId,
1582
+ num: remainingNum
1583
+ },
1584
+ config: nextBundleDiscount === null || nextBundleDiscount === void 0 ? void 0 : nextBundleDiscount.config,
1585
+ _num: remainingNum * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu9 = flatItem.parentProduct) === null || _flatItem$parentProdu9 === void 0 ? void 0 : _flatItem$parentProdu9.num) || 1)
1586
+ };
1587
+ var nextAppliedProducts = appliedDiscountProducts.get(nextBundleDiscount.id) || [];
1588
+ nextAppliedProducts.push(nextDiscountDetail);
1589
+ appliedDiscountProducts.set(nextBundleDiscount.id, nextAppliedProducts);
1590
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1591
+ _id: nextUniqueId,
1592
+ num: remainingNum,
1593
+ quantity: remainingNum,
1594
+ total: nextTargetTotal,
1595
+ price: new Decimal(nextOriginTotal || 0).minus(nextDiscountDetail.discount.fixed_amount).toNumber(),
1596
+ discount_list: [nextDiscountDetail],
1597
+ processed: true
1598
+ }));
1599
+ remainingNum = 0;
1600
+ break;
1601
+ }
1602
+
1603
+ // 🔥 需要拆分:计算最大使用次数
1604
+ var nextMaxUsageLimit = void 0;
1605
+ if (nextIsGoodPass) {
1606
+ var _nextSelectedDiscount2;
1607
+ var nextGoodPassCount = nextApplicableDiscounts.filter(function (item) {
1608
+ return (item.tag || item.type) === 'good_pass';
1609
+ }).length;
1610
+ nextMaxUsageLimit = nextGoodPassCount;
1611
+ if ((_nextSelectedDiscount2 = nextSelectedDiscount.config) !== null && _nextSelectedDiscount2 !== void 0 && _nextSelectedDiscount2.maxUsagePerOrder) {
1612
+ var usedCount = usedProductIdCounts.get(nextSelectedDiscount.product_id) || 0;
1613
+ nextMaxUsageLimit = Math.min(nextGoodPassCount, Math.max(0, nextSelectedDiscount.config.maxUsagePerOrder - usedCount));
1614
+ }
1615
+ } else if (nextIsDiscountCard && nextApplicableProductLimit > 0) {
1616
+ var _usedLimitCount = usedDiscountCardLimitCounts.get(nextSelectedDiscount.id) || 0;
1617
+ nextMaxUsageLimit = Math.max(0, nextApplicableProductLimit - _usedLimitCount);
1618
+ } else {
1619
+ nextMaxUsageLimit = 1;
1620
+ }
1621
+ var nextSplitCount = Math.min(remainingNum, nextMaxUsageLimit);
1622
+ if (nextSplitCount === 0) {
1623
+ // 已达使用上限,剩余商品无折扣存储
1624
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1625
+ _id: "".concat(flatItem._id, "_split_rest"),
1626
+ num: remainingNum,
1627
+ quantity: remainingNum,
1628
+ discount_list: _this3.filterDiscountListByType(flatItem.discount_list, 'promotion'),
1629
+ processed: true
1630
+ }));
1631
+ break;
1632
+ }
1633
+
1634
+ // 生成有折扣的商品
1635
+ for (var j = 0; j < nextSplitCount; j++) {
1636
+ var _nextBundleDiscount$m2;
1637
+ var _nextBundleDiscount = nextIsGoodPass ? nextSelectedDiscountCard || nextApplicableDiscounts[j] : nextSelectedDiscountCard || nextApplicableDiscounts[0];
1638
+ usedDiscounts.set(_nextBundleDiscount.id, true);
1639
+ if ((_nextBundleDiscount.tag || _nextBundleDiscount.type) === 'good_pass') {
1640
+ var _curCount2 = usedProductIdCounts.get(_nextBundleDiscount.product_id) || 0;
1641
+ usedProductIdCounts.set(_nextBundleDiscount.product_id, _curCount2 + 1);
1642
+ }
1643
+ var nextBundleDiscTypeForCount = _nextBundleDiscount.tag || _nextBundleDiscount.type;
1644
+ if (['discount_card', 'product_discount_card'].includes(nextBundleDiscTypeForCount)) {
1645
+ var curLimitCount = usedDiscountCardLimitCounts.get(_nextBundleDiscount.id) || 0;
1646
+ usedDiscountCardLimitCounts.set(_nextBundleDiscount.id, curLimitCount + 1);
1647
+ }
1648
+ var _nextUniqueId = "".concat(flatItem._id, "_split_").concat(continueSplitIndex);
1649
+ var nextDiscountedPrice = getDiscountAmount(_nextBundleDiscount, product.origin_total, product.origin_total);
1650
+ var nextBundleDiscAmount = new Decimal(product.origin_total || 0).minus(nextDiscountedPrice).toNumber();
1651
+ var nextBundleDiscTypeStr = _nextBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : _nextBundleDiscount.tag;
1652
+ var _nextDiscountDetail = {
1653
+ amount: nextBundleDiscAmount,
1654
+ type: nextBundleDiscTypeStr,
1655
+ discount: {
1656
+ discount_card_type: _nextBundleDiscount === null || _nextBundleDiscount === void 0 || (_nextBundleDiscount$m2 = _nextBundleDiscount.metadata) === null || _nextBundleDiscount$m2 === void 0 ? void 0 : _nextBundleDiscount$m2.discount_card_type,
1657
+ fixed_amount: nextBundleDiscAmount,
1658
+ resource_id: _nextBundleDiscount.id,
1659
+ title: _nextBundleDiscount.format_title,
1660
+ original_amount: product.origin_total,
1661
+ product_id: product.id,
1662
+ percent: _nextBundleDiscount.par_value,
1663
+ discount_product_id: _nextBundleDiscount.product_id
1664
+ },
1665
+ metadata: {
1666
+ custom_product_bundle_map_id: _nextUniqueId,
1667
+ num: 1
1668
+ },
1669
+ _num: 1,
1670
+ config: _nextBundleDiscount === null || _nextBundleDiscount === void 0 ? void 0 : _nextBundleDiscount.config
1671
+ };
1672
+ var _nextAppliedProducts = appliedDiscountProducts.get(_nextBundleDiscount.id) || [];
1673
+ _nextAppliedProducts.push(_nextDiscountDetail);
1674
+ appliedDiscountProducts.set(_nextBundleDiscount.id, _nextAppliedProducts);
1675
+ processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1676
+ _id: _nextUniqueId,
1677
+ num: 1,
1678
+ quantity: 1,
1679
+ price: nextDiscountedPrice,
1680
+ total: nextDiscountedPrice,
1681
+ discount_list: [_nextDiscountDetail],
1682
+ processed: true,
1683
+ _discountId: _nextBundleDiscount.id
1684
+ }));
1685
+ continueSplitIndex++;
1686
+ }
1687
+ remainingNum -= nextSplitCount;
1286
1688
  }
1287
1689
  } else {
1288
- var _selectedDiscount3$me, _selectedDiscount3$me2, _flatItem$parentProdu9;
1289
- // 折扣卡:不拆分数量,直接应用
1290
- var _selectedDiscount3 = selectedDiscountCard || applicableDiscounts[0];
1291
- usedDiscounts.set(_selectedDiscount3.id, true);
1690
+ var _currentBundleDiscoun3, _currentBundleDiscoun4, _flatItem$parentProdu10;
1691
+ // 不拆分:直接应用折扣
1692
+ var _currentBundleDiscount = selectedDiscountCard || applicableDiscounts[0];
1693
+ usedDiscounts.set(_currentBundleDiscount.id, true);
1694
+ // 🔥 更新 product_id 使用计数
1695
+ if ((_currentBundleDiscount.tag || _currentBundleDiscount.type) === 'good_pass') {
1696
+ var _currentCount2 = usedProductIdCounts.get(_currentBundleDiscount.product_id) || 0;
1697
+ usedProductIdCounts.set(_currentBundleDiscount.product_id, _currentCount2 + 1);
1698
+ }
1699
+ // 🔥 更新折扣卡 applicableProductLimit 使用计数(不拆分时按商品数量计数)
1700
+ var noSplitDiscountType = _currentBundleDiscount.tag || _currentBundleDiscount.type;
1701
+ if (['discount_card', 'product_discount_card'].includes(noSplitDiscountType)) {
1702
+ var bundleQuantity = product.num || 1;
1703
+ var currentNoSplitCount = usedDiscountCardLimitCounts.get(_currentBundleDiscount.id) || 0;
1704
+ usedDiscountCardLimitCounts.set(_currentBundleDiscount.id, currentNoSplitCount + bundleQuantity);
1705
+ }
1292
1706
  var _productOriginTotal = product.original_price || product.price || 0;
1293
1707
 
1294
1708
  // 🔥 检查是否是 order_level 固定金额折扣卡
1295
- var _isOrderLevel = isOrderLevelFixedAmountDiscount(_selectedDiscount3);
1296
- var _orderLevelAllocation = _isOrderLevel ? orderLevelDiscountAllocations.get(_selectedDiscount3.id) : null;
1709
+ var _isOrderLevel = isOrderLevelFixedAmountDiscount(selectedDiscount);
1710
+ var _orderLevelAllocation = _isOrderLevel ? orderLevelDiscountAllocations.get(selectedDiscount.id) : null;
1297
1711
  var _productAllocation = _orderLevelAllocation === null || _orderLevelAllocation === void 0 ? void 0 : _orderLevelAllocation.get(flatItem._id);
1298
1712
  var _targetProductTotal;
1299
1713
  var fixedAmountPerItem;
@@ -1305,40 +1719,45 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1305
1719
  _targetProductTotal = Math.max(new Decimal(_productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
1306
1720
  } else {
1307
1721
  // item_level 或其他类型:使用原有逻辑
1308
- _targetProductTotal = getDiscountAmount(_selectedDiscount3, _productOriginTotal, _productOriginTotal);
1722
+ _targetProductTotal = getDiscountAmount(_currentBundleDiscount, _productOriginTotal, _productOriginTotal);
1309
1723
  fixedAmountPerItem = new Decimal(_productOriginTotal).minus(_targetProductTotal).toNumber();
1310
1724
  }
1311
1725
 
1726
+ // 计算实际折扣金额
1727
+ var bundleActualDiscountAmount = new Decimal(_productOriginTotal).minus(_targetProductTotal).toNumber();
1728
+
1312
1729
  // 🔥 使用当前的 _id 作为唯一标识
1313
1730
  var _uniqueId = flatItem._id;
1314
1731
  var _discountDetail2 = {
1315
- amount: fixedAmountPerItem * (product.num || 1),
1316
- type: _selectedDiscount3.tag === 'product_discount_card' ? 'discount_card' : _selectedDiscount3.tag,
1732
+ amount: bundleActualDiscountAmount * (product.num || 1),
1733
+ type: _currentBundleDiscount.tag === 'product_discount_card' ? 'discount_card' : _currentBundleDiscount.tag,
1317
1734
  discount: {
1318
- discount_card_type: _selectedDiscount3 === null || _selectedDiscount3 === void 0 || (_selectedDiscount3$me = _selectedDiscount3.metadata) === null || _selectedDiscount3$me === void 0 ? void 0 : _selectedDiscount3$me.discount_card_type,
1319
- fixed_amount: fixedAmountPerItem,
1320
- discount_calculation_mode: _selectedDiscount3 === null || _selectedDiscount3 === void 0 || (_selectedDiscount3$me2 = _selectedDiscount3.metadata) === null || _selectedDiscount3$me2 === void 0 ? void 0 : _selectedDiscount3$me2.discount_calculation_mode,
1321
- resource_id: _selectedDiscount3.id,
1322
- title: _selectedDiscount3.format_title,
1735
+ discount_card_type: _currentBundleDiscount === null || _currentBundleDiscount === void 0 || (_currentBundleDiscoun3 = _currentBundleDiscount.metadata) === null || _currentBundleDiscoun3 === void 0 ? void 0 : _currentBundleDiscoun3.discount_card_type,
1736
+ fixed_amount: bundleActualDiscountAmount,
1737
+ discount_calculation_mode: _currentBundleDiscount === null || _currentBundleDiscount === void 0 || (_currentBundleDiscoun4 = _currentBundleDiscount.metadata) === null || _currentBundleDiscoun4 === void 0 ? void 0 : _currentBundleDiscoun4.discount_calculation_mode,
1738
+ resource_id: _currentBundleDiscount.id,
1739
+ title: _currentBundleDiscount.format_title,
1323
1740
  original_amount: product.original_price,
1324
1741
  product_id: product.id,
1325
- percent: _selectedDiscount3.par_value
1742
+ percent: _currentBundleDiscount.par_value,
1743
+ discount_product_id: _currentBundleDiscount.product_id
1326
1744
  },
1327
1745
  metadata: _objectSpread({
1328
1746
  // 🔥 使用唯一的 _id
1329
1747
  custom_product_bundle_map_id: _uniqueId,
1330
- discount_rule_uncheck_flag: _selectedDiscount3 === null || _selectedDiscount3 === void 0 ? void 0 : _selectedDiscount3.discount_rule_uncheck_flag,
1748
+ discount_rule_uncheck_flag: selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.discount_rule_uncheck_flag,
1331
1749
  num: product.num || 1
1332
1750
  }, _productDiscountDifference !== undefined && {
1333
1751
  product_discount_difference: _productDiscountDifference
1334
1752
  }),
1335
- _num: (product.num || 1) * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu9 = flatItem.parentProduct) === null || _flatItem$parentProdu9 === void 0 ? void 0 : _flatItem$parentProdu9.num) || 1)
1753
+ config: _currentBundleDiscount === null || _currentBundleDiscount === void 0 ? void 0 : _currentBundleDiscount.config,
1754
+ _num: (product.num || 1) * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu10 = flatItem.parentProduct) === null || _flatItem$parentProdu10 === void 0 ? void 0 : _flatItem$parentProdu10.num) || 1)
1336
1755
  };
1337
1756
 
1338
1757
  // 记录实际应用的折扣
1339
- var _appliedProducts2 = appliedDiscountProducts.get(_selectedDiscount3.id) || [];
1758
+ var _appliedProducts2 = appliedDiscountProducts.get(_currentBundleDiscount.id) || [];
1340
1759
  _appliedProducts2.push(_discountDetail2);
1341
- appliedDiscountProducts.set(_selectedDiscount3.id, _appliedProducts2);
1760
+ appliedDiscountProducts.set(_currentBundleDiscount.id, _appliedProducts2);
1342
1761
  processedItems.push(_objectSpread(_objectSpread({}, flatItem), {}, {
1343
1762
  total: _targetProductTotal,
1344
1763
  price: new Decimal(_productOriginTotal || 0).minus(fixedAmountPerItem).toNumber(),
@@ -1463,6 +1882,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1463
1882
  product_id: bundleItem.product_id,
1464
1883
  price: item.price,
1465
1884
  num: item.num,
1885
+ quantity: item.num,
1466
1886
  discount_list: updatedDiscountList
1467
1887
  }));
1468
1888
  });
@@ -1486,6 +1906,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1486
1906
  product_id: bundleItem.product_id,
1487
1907
  price: item.price,
1488
1908
  num: item.num,
1909
+ quantity: item.num,
1489
1910
  discount_list: _updatedDiscountList
1490
1911
  }));
1491
1912
  } else {
@@ -1500,8 +1921,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1500
1921
 
1501
1922
  // 🔥 更新主商品自己的 discount_list 中的 num(quantity=1)
1502
1923
  var updatedMainDiscountList = mainProductData.discount_list.map(function (discount) {
1503
- var _discount$metadata6, _discount$metadata7;
1504
- if (discount !== null && discount !== void 0 && (_discount$metadata6 = discount.metadata) !== null && _discount$metadata6 !== void 0 && _discount$metadata6.custom_product_bundle_map_id) {
1924
+ var _discount$metadata7, _discount$metadata8;
1925
+ if (discount !== null && discount !== void 0 && (_discount$metadata7 = discount.metadata) !== null && _discount$metadata7 !== void 0 && _discount$metadata7.custom_product_bundle_map_id) {
1505
1926
  // bundle的discount_list保持不变
1506
1927
  return discount;
1507
1928
  }
@@ -1509,7 +1930,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1509
1930
  return _objectSpread(_objectSpread({}, discount), {}, {
1510
1931
  // num: 1,
1511
1932
  metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
1512
- custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata7 = discount.metadata) === null || _discount$metadata7 === void 0 ? void 0 : _discount$metadata7.custom_product_bundle_map_id,
1933
+ custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata8 = discount.metadata) === null || _discount$metadata8 === void 0 ? void 0 : _discount$metadata8.custom_product_bundle_map_id,
1513
1934
  num: 1
1514
1935
  })
1515
1936
  });
@@ -1554,8 +1975,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1554
1975
  quantity: 1,
1555
1976
  discount_list: updatedMainDiscountList,
1556
1977
  bundle: newBundleWithDiscount,
1557
- total: new Decimal(newTotalWithDiscount).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber(),
1558
- origin_total: new Decimal(newOriginTotalWithDiscount).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber()
1978
+ total: newTotalWithDiscount,
1979
+ origin_total: newOriginTotalWithDiscount
1559
1980
  })));
1560
1981
 
1561
1982
  // 第二个:包含原始bundle (qty=原quantity-1)
@@ -1574,8 +1995,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1574
1995
 
1575
1996
  // 🔥 更新主商品自己的 discount_list 中的 num(quantity=原quantity-1)
1576
1997
  var updatedMainDiscountListOriginal = mainProductData.discount_list.map(function (discount) {
1577
- var _discount$metadata8, _discount$metadata9;
1578
- if (discount !== null && discount !== void 0 && (_discount$metadata8 = discount.metadata) !== null && _discount$metadata8 !== void 0 && _discount$metadata8.custom_product_bundle_map_id) {
1998
+ var _discount$metadata9, _discount$metadata10;
1999
+ if (discount !== null && discount !== void 0 && (_discount$metadata9 = discount.metadata) !== null && _discount$metadata9 !== void 0 && _discount$metadata9.custom_product_bundle_map_id) {
1579
2000
  // bundle的discount_list保持不变
1580
2001
  return discount;
1581
2002
  }
@@ -1583,7 +2004,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1583
2004
  return _objectSpread(_objectSpread({}, discount), {}, {
1584
2005
  metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
1585
2006
  num: mainProductQuantity - 1,
1586
- custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata9 = discount.metadata) === null || _discount$metadata9 === void 0 ? void 0 : _discount$metadata9.custom_product_bundle_map_id
2007
+ custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata10 = discount.metadata) === null || _discount$metadata10 === void 0 ? void 0 : _discount$metadata10.custom_product_bundle_map_id
1587
2008
  })
1588
2009
  // num: mainProductQuantity - 1,
1589
2010
  });
@@ -1650,11 +2071,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1650
2071
  processedBundleItems.forEach(function (item) {
1651
2072
  // 🔥 更新 discount_list 中的 num,使其与拆分后的 item.num 一致
1652
2073
  var updatedDiscountList = (item.discount_list || []).map(function (discount) {
1653
- var _discount$metadata10;
2074
+ var _discount$metadata11;
1654
2075
  return _objectSpread(_objectSpread({}, discount), {}, {
1655
2076
  metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
1656
2077
  num: item.num,
1657
- custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata10 = discount.metadata) === null || _discount$metadata10 === void 0 ? void 0 : _discount$metadata10.custom_product_bundle_map_id
2078
+ custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata11 = discount.metadata) === null || _discount$metadata11 === void 0 ? void 0 : _discount$metadata11.custom_product_bundle_map_id
1658
2079
  })
1659
2080
  // num: item.num, // 使用拆分后的 num
1660
2081
  });
@@ -1664,6 +2085,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1664
2085
  product_id: bundleItem.product_id,
1665
2086
  price: item.price,
1666
2087
  num: item.num,
2088
+ quantity: item.num,
1667
2089
  discount_list: updatedDiscountList
1668
2090
  }));
1669
2091
  });
@@ -1702,13 +2124,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1702
2124
 
1703
2125
  // 累加bundle的价格(只累加一次)
1704
2126
  if (newBundle.length > 0) {
1705
- newBundle.forEach(function (item) {
1706
- newTotal += Number(item.price) * Number(item.num);
1707
- });
1708
-
1709
- // 计算原始总价(不考虑折扣)
1710
2127
  newBundle.forEach(function (item) {
1711
2128
  var _item$discount_list3;
2129
+ newTotal += Number(item.price) * Number(item.num);
1712
2130
  var originalPrice = ((_item$discount_list3 = item.discount_list) === null || _item$discount_list3 === void 0 || (_item$discount_list3 = _item$discount_list3[0]) === null || _item$discount_list3 === void 0 || (_item$discount_list3 = _item$discount_list3.discount) === null || _item$discount_list3 === void 0 ? void 0 : _item$discount_list3.original_amount) || item.price;
1713
2131
  newOriginTotal += Number(originalPrice) * Number(item.num);
1714
2132
  });
@@ -1723,8 +2141,6 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1723
2141
  return accumulator.add(currentPrice.mul(currentNum));
1724
2142
  }, new Decimal(newTotal)).toNumber();
1725
2143
  }
1726
- newTotal = new Decimal(newTotal).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
1727
- newOriginTotal = new Decimal(newOriginTotal).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
1728
2144
 
1729
2145
  // 生成最终的主商品
1730
2146
  result.push(_this3.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {