@pisell/pisellos 2.2.268 → 2.2.269

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 (120) hide show
  1. package/dist/core/index.d.ts +2 -0
  2. package/dist/core/index.js +7 -0
  3. package/dist/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  4. package/dist/model/strategy/adapter/promotion/adapter.js +23 -0
  5. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  6. package/dist/model/strategy/adapter/promotion/evaluator.js +279 -6
  7. package/dist/model/strategy/adapter/promotion/examples.d.ts +86 -0
  8. package/dist/model/strategy/adapter/promotion/examples.js +99 -0
  9. package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
  10. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  11. package/dist/model/strategy/adapter/promotion/type.d.ts +90 -2
  12. package/dist/model/strategy/adapter/promotion/type.js +45 -0
  13. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +12 -10
  14. package/dist/modules/OpenData/index.d.ts +2 -0
  15. package/dist/modules/OpenData/index.js +8 -0
  16. package/dist/modules/Order/index.d.ts +28 -8
  17. package/dist/modules/Order/index.js +813 -498
  18. package/dist/modules/Order/payment-utils.d.ts +26 -0
  19. package/dist/modules/Order/payment-utils.js +225 -0
  20. package/dist/modules/Order/types.d.ts +35 -1
  21. package/dist/modules/Order/utils/orderCollectionIdentity.js +7 -2
  22. package/dist/modules/Order/utils.js +10 -6
  23. package/dist/modules/Payment/index.d.ts +2 -0
  24. package/dist/modules/Payment/index.js +78 -49
  25. package/dist/modules/Payment/types.d.ts +104 -25
  26. package/dist/modules/Payment/types.js +17 -0
  27. package/dist/modules/Payment/walletpass.d.ts +38 -1
  28. package/dist/modules/Payment/walletpass.js +917 -114
  29. package/dist/modules/Rules/index.d.ts +3 -0
  30. package/dist/modules/Rules/index.js +146 -106
  31. package/dist/modules/SalesSummary/utils.js +7 -1
  32. package/dist/server/index.d.ts +16 -0
  33. package/dist/server/index.js +1940 -1043
  34. package/dist/server/modules/index.d.ts +1 -1
  35. package/dist/server/modules/order/index.d.ts +70 -4
  36. package/dist/server/modules/order/index.js +1816 -728
  37. package/dist/server/modules/order/types.d.ts +25 -3
  38. package/dist/server/modules/order/types.js +7 -1
  39. package/dist/solution/BaseSales/index.d.ts +115 -6
  40. package/dist/solution/BaseSales/index.js +1847 -478
  41. package/dist/solution/BaseSales/types.d.ts +55 -1
  42. package/dist/solution/BaseSales/types.js +2 -1
  43. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  44. package/dist/solution/BaseSales/utils/cartPromotion.js +90 -31
  45. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  46. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  47. package/dist/solution/BookingByStep/index.d.ts +1 -1
  48. package/dist/solution/BookingTicket/index.d.ts +9 -17
  49. package/dist/solution/BookingTicket/index.js +138 -52
  50. package/dist/solution/BookingTicket/types.d.ts +1 -0
  51. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  52. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +173 -83
  53. package/dist/solution/Sales/index.d.ts +2 -0
  54. package/dist/solution/Sales/index.js +26 -4
  55. package/dist/solution/ScanOrder/index.js +31 -20
  56. package/dist/solution/VenueBooking/index.d.ts +1 -0
  57. package/dist/solution/VenueBooking/index.js +30 -19
  58. package/dist/types/index.d.ts +1 -0
  59. package/dist/utils/payment-number.d.ts +9 -0
  60. package/dist/utils/payment-number.js +69 -0
  61. package/lib/core/index.d.ts +2 -0
  62. package/lib/core/index.js +4 -0
  63. package/lib/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  64. package/lib/model/strategy/adapter/promotion/adapter.js +20 -0
  65. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  66. package/lib/model/strategy/adapter/promotion/evaluator.js +235 -0
  67. package/lib/model/strategy/adapter/promotion/examples.d.ts +86 -0
  68. package/lib/model/strategy/adapter/promotion/examples.js +91 -0
  69. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  70. package/lib/model/strategy/adapter/promotion/type.d.ts +90 -2
  71. package/lib/model/strategy/adapter/promotion/type.js +2 -0
  72. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -1
  73. package/lib/modules/OpenData/index.d.ts +2 -0
  74. package/lib/modules/OpenData/index.js +5 -0
  75. package/lib/modules/Order/index.d.ts +28 -8
  76. package/lib/modules/Order/index.js +236 -71
  77. package/lib/modules/Order/payment-utils.d.ts +26 -0
  78. package/lib/modules/Order/payment-utils.js +224 -0
  79. package/lib/modules/Order/types.d.ts +35 -1
  80. package/lib/modules/Order/utils/orderCollectionIdentity.js +3 -0
  81. package/lib/modules/Order/utils.js +11 -4
  82. package/lib/modules/Payment/index.d.ts +2 -0
  83. package/lib/modules/Payment/index.js +33 -12
  84. package/lib/modules/Payment/types.d.ts +104 -25
  85. package/lib/modules/Payment/types.js +1 -0
  86. package/lib/modules/Payment/walletpass.d.ts +38 -1
  87. package/lib/modules/Payment/walletpass.js +730 -21
  88. package/lib/modules/Rules/index.d.ts +3 -0
  89. package/lib/modules/Rules/index.js +54 -21
  90. package/lib/modules/SalesSummary/utils.js +5 -1
  91. package/lib/server/index.d.ts +16 -0
  92. package/lib/server/index.js +670 -18
  93. package/lib/server/modules/index.d.ts +1 -1
  94. package/lib/server/modules/order/index.d.ts +70 -4
  95. package/lib/server/modules/order/index.js +818 -69
  96. package/lib/server/modules/order/types.d.ts +25 -3
  97. package/lib/server/modules/order/types.js +1 -0
  98. package/lib/solution/BaseSales/index.d.ts +115 -6
  99. package/lib/solution/BaseSales/index.js +896 -32
  100. package/lib/solution/BaseSales/types.d.ts +55 -1
  101. package/lib/solution/BaseSales/types.js +2 -1
  102. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  103. package/lib/solution/BaseSales/utils/cartPromotion.js +63 -12
  104. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  105. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  106. package/lib/solution/BookingByStep/index.d.ts +1 -1
  107. package/lib/solution/BookingTicket/index.d.ts +9 -17
  108. package/lib/solution/BookingTicket/index.js +63 -9
  109. package/lib/solution/BookingTicket/types.d.ts +1 -0
  110. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  111. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +37 -5
  112. package/lib/solution/Sales/index.d.ts +2 -0
  113. package/lib/solution/Sales/index.js +20 -6
  114. package/lib/solution/ScanOrder/index.js +8 -0
  115. package/lib/solution/VenueBooking/index.d.ts +1 -0
  116. package/lib/solution/VenueBooking/index.js +8 -0
  117. package/lib/types/index.d.ts +1 -0
  118. package/lib/utils/payment-number.d.ts +9 -0
  119. package/lib/utils/payment-number.js +64 -0
  120. package/package.json +1 -1
@@ -150,7 +150,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
150
150
  }
151
151
 
152
152
  // 编辑商品已有商品券
153
- if (productList.every(function (item) {
153
+ if (productList.length > 0 && productList.every(function (item) {
154
154
  var _product$discount_lis;
155
155
  var product = _this2.hooks.getProduct(item);
156
156
  return product.booking_id && (((_product$discount_lis = product.discount_list) === null || _product$discount_lis === void 0 ? void 0 : _product$discount_lis.length) || product.total == 0);
@@ -214,6 +214,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
214
214
  return {
215
215
  isAvailable: hasApplicableDiscount,
216
216
  discountList: hasApplicableDiscount ? result.discountList : oldDiscountList,
217
+ evaluatedDiscountList: result.discountList,
217
218
  productList: hasApplicableDiscount ? result.productList : productList,
218
219
  unavailableReason: unavailableReason
219
220
  };
@@ -241,23 +242,37 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
241
242
  value: function resolveDiscountListForManualOverride(discountList) {
242
243
  return this.excludeDiscountListByType(discountList, 'promotion');
243
244
  }
245
+ }, {
246
+ key: "isItemRewardProductDiscount",
247
+ value: function isItemRewardProductDiscount(product) {
248
+ var _product$_promotion;
249
+ var discountList = Array.isArray(product === null || product === void 0 ? void 0 : product.discount_list) ? product.discount_list : [];
250
+ return (product === null || product === void 0 || (_product$_promotion = product._promotion) === null || _product$_promotion === void 0 ? void 0 : _product$_promotion.actionType) === 'ITEM_REWARD' && discountList.some(function (item) {
251
+ var _item$metadata, _item$metadata2;
252
+ return (item === null || item === void 0 ? void 0 : item.type) === 'product' && (item === null || item === void 0 || (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata.source) === 'promotion' && (item === null || item === void 0 || (_item$metadata2 = item.metadata) === null || _item$metadata2 === void 0 ? void 0 : _item$metadata2.actionType) === 'ITEM_REWARD';
253
+ });
254
+ }
255
+
244
256
  // 获取券不可用的原因
245
257
  }, {
246
258
  key: "getUnavailableReason",
247
259
  value: function getUnavailableReason(discountList, productList) {
260
+ var _this3 = this;
248
261
  // 检查时间限制
249
262
  var _iterator = _createForOfIteratorHelper(discountList),
250
263
  _step;
251
264
  try {
252
265
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
253
266
  var discount = _step.value;
254
- var _iterator3 = _createForOfIteratorHelper(productList),
267
+ var bookingTimes = productList.length ? productList.map(function (item) {
268
+ var product = _this3.hooks.getProduct(item);
269
+ return ((product === null || product === void 0 ? void 0 : product.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss');
270
+ }) : [dayjs().format('YYYY-MM-DD HH:mm:ss')];
271
+ var _iterator3 = _createForOfIteratorHelper(bookingTimes),
255
272
  _step3;
256
273
  try {
257
274
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
258
- var item = _step3.value;
259
- var product = this.hooks.getProduct(item);
260
- var bookingTime = ((product === null || product === void 0 ? void 0 : product.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss');
275
+ var bookingTime = _step3.value;
261
276
  var filteredList = filterDiscountListByBookingTime([discount], bookingTime);
262
277
  if (filteredList.length === 0) {
263
278
  return UnavailableReason.TimeLimit;
@@ -288,12 +303,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
288
303
  try {
289
304
  for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
290
305
  var _limitedData$product_;
291
- var _item = _step4.value;
292
- var _product = this.hooks.getProduct(_item);
306
+ var item = _step4.value;
307
+ var product = this.hooks.getProduct(item);
293
308
  if (limitedData.type === 'product_all') {
294
309
  hasApplicableProduct = true;
295
310
  break;
296
- } else if ((_limitedData$product_ = limitedData.product_ids) !== null && _limitedData$product_ !== void 0 && _limitedData$product_.includes(_product.id)) {
311
+ } else if ((_limitedData$product_ = limitedData.product_ids) !== null && _limitedData$product_ !== void 0 && _limitedData$product_.includes(product.id)) {
297
312
  hasApplicableProduct = true;
298
313
  break;
299
314
  }
@@ -318,7 +333,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
318
333
  key: "calcDiscount",
319
334
  value: function calcDiscount(_ref2, options) {
320
335
  var _options$selectedList,
321
- _this3 = this;
336
+ _this4 = this;
322
337
  var discountList = _ref2.discountList,
323
338
  productList = _ref2.productList,
324
339
  holders = _ref2.holders,
@@ -351,7 +366,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
351
366
  var discountType = selectedDiscount.tag || selectedDiscount.type;
352
367
  return selectedDiscount.isEditMode === true && selectedDiscount.isSelected === true && ['good_pass', 'discount_card', 'product_discount_card'].includes(discountType);
353
368
  };
354
- var resolveReapplyEditModeDiscountPercent = function resolveReapplyEditModeDiscountPercent(originProduct, selectedDiscount) {
369
+ var resolveReapplyBookingDiscountPercent = function resolveReapplyBookingDiscountPercent(originProduct, selectedDiscount) {
355
370
  var _discount2;
356
371
  if (!shouldReapplyBookingDiscount(originProduct, selectedDiscount)) return undefined;
357
372
  var discountType = (selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.tag) || (selectedDiscount === null || selectedDiscount === void 0 ? void 0 : selectedDiscount.type);
@@ -411,7 +426,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
411
426
  var flattenProductsWithBundle = function flattenProductsWithBundle(productList) {
412
427
  var flattened = [];
413
428
  productList.forEach(function (originProduct) {
414
- var product = _this3.hooks.getProduct(originProduct);
429
+ var product = _this4.hooks.getProduct(originProduct);
415
430
 
416
431
  // 1. 添加主商品
417
432
  flattened.push({
@@ -429,6 +444,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
429
444
  // 2. 展开 bundle 子商品
430
445
  if (product.bundle && Array.isArray(product.bundle) && product.bundle.length > 0) {
431
446
  product.bundle.forEach(function (bundleItem, bundleIndex) {
447
+ var _ref3, _bundleItem$bundle_pr;
432
448
  flattened.push({
433
449
  type: 'bundle',
434
450
  originProduct: originProduct,
@@ -437,8 +453,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
437
453
  bundleIndex: bundleIndex,
438
454
  // 虚拟商品属性
439
455
  price: Number(bundleItem.price || 0),
440
- id: bundleItem._bundle_product_id,
441
- // 🔥 使用 _bundle_product_id
456
+ // 新增商品运行态通常带 _bundle_product_id;订单 hydrate 后只有
457
+ // bundle_product_id。Change time 必须兼容两种结构,否则 bundle
458
+ // 子项无法命中折扣卡的 limited_relation_product_data.product_ids。
459
+ id: (_ref3 = (_bundleItem$bundle_pr = bundleItem.bundle_product_id) !== null && _bundleItem$bundle_pr !== void 0 ? _bundleItem$bundle_pr : bundleItem._bundle_product_id) !== null && _ref3 !== void 0 ? _ref3 : bundleItem.product_id,
442
460
  _id: "".concat(product._id, "_bundle_").concat(bundleIndex),
443
461
  parentId: product._id,
444
462
  num: bundleItem.num || 1,
@@ -587,10 +605,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
587
605
 
588
606
  // 对扁平化后的列表按价格降序排序(用于应用优惠券时优先选择高价商品)
589
607
  var sortedFlattenedList = flattenedList.sort(function (a, b) {
590
- var _ref3, _a$original_price, _ref4, _b$original_price;
608
+ var _ref4, _a$original_price, _ref5, _b$original_price;
591
609
  // 子商品优先使用 original_price,主商品使用 price
592
- var priceA = new Decimal(a.type === 'bundle' ? (_ref3 = (_a$original_price = a.original_price) !== null && _a$original_price !== void 0 ? _a$original_price : a.price) !== null && _ref3 !== void 0 ? _ref3 : '0' : a.price || '0');
593
- var priceB = new Decimal(b.type === 'bundle' ? (_ref4 = (_b$original_price = b.original_price) !== null && _b$original_price !== void 0 ? _b$original_price : b.price) !== null && _ref4 !== void 0 ? _ref4 : '0' : b.price || '0');
610
+ var priceA = new Decimal(a.type === 'bundle' ? (_ref4 = (_a$original_price = a.original_price) !== null && _a$original_price !== void 0 ? _a$original_price : a.price) !== null && _ref4 !== void 0 ? _ref4 : '0' : a.price || '0');
611
+ var priceB = new Decimal(b.type === 'bundle' ? (_ref5 = (_b$original_price = b.original_price) !== null && _b$original_price !== void 0 ? _b$original_price : b.price) !== null && _ref5 !== void 0 ? _ref5 : '0' : b.price || '0');
594
612
  if (priceA.equals(priceB)) {
595
613
  // 价格相同时,主商品优先
596
614
  if (a.type !== b.type) {
@@ -712,7 +730,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
712
730
 
713
731
  // 辅助函数:检查商品是否对某个折扣卡可用
714
732
  var checkItemApplicableForDiscount = function checkItemApplicableForDiscount(flatItem, discount) {
715
- var _product2, _product3, _product4, _flatItem$bundleItem, _flatItem$bundleItem2, _product5;
733
+ var _product, _product2, _product3, _flatItem$bundleItem, _flatItem$bundleItem2, _product4;
716
734
  var product;
717
735
  if (flatItem.type === 'main') {
718
736
  product = flatItem.product;
@@ -729,9 +747,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
729
747
  startDate: (_flatItem$parentProdu = flatItem.parentProduct) === null || _flatItem$parentProdu === void 0 ? void 0 : _flatItem$parentProdu.startDate
730
748
  };
731
749
  }
750
+ if (_this4.isItemRewardProductDiscount(product)) {
751
+ return false;
752
+ }
732
753
 
733
754
  // 编辑的商品使用了优惠券不可用
734
- var isAvailableProduct = flatItem.type === 'main' ? !((_product2 = product) !== null && _product2 !== void 0 && _product2.booking_id && (_product3 = product) !== null && _product3 !== void 0 && (_product3 = _product3.discount_list) !== null && _product3 !== void 0 && _product3.length && (_product4 = product) !== null && _product4 !== void 0 && (_product4 = _product4.discount_list) !== null && _product4 !== void 0 && _product4.every(function (d) {
755
+ var isAvailableProduct = flatItem.type === 'main' ? !((_product = product) !== null && _product !== void 0 && _product.booking_id && (_product2 = product) !== null && _product2 !== void 0 && (_product2 = _product2.discount_list) !== null && _product2 !== void 0 && _product2.length && (_product3 = product) !== null && _product3 !== void 0 && (_product3 = _product3.discount_list) !== null && _product3 !== void 0 && _product3.every(function (d) {
735
756
  return d.id && ['good_pass', 'discount_card', 'product_discount_card'].includes(d.tag || d.type);
736
757
  })) : !(flatItem !== null && flatItem !== void 0 && flatItem.booking_id && !!(flatItem !== null && flatItem !== void 0 && (_flatItem$bundleItem = flatItem.bundleItem) !== null && _flatItem$bundleItem !== void 0 && (_flatItem$bundleItem = _flatItem$bundleItem.discount_list) !== null && _flatItem$bundleItem !== void 0 && _flatItem$bundleItem.length) && flatItem !== null && flatItem !== void 0 && (_flatItem$bundleItem2 = flatItem.bundleItem) !== null && _flatItem$bundleItem2 !== void 0 && (_flatItem$bundleItem2 = _flatItem$bundleItem2.discount_list) !== null && _flatItem$bundleItem2 !== void 0 && _flatItem$bundleItem2.every(function (d) {
737
758
  return d.id;
@@ -752,7 +773,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
752
773
  var limitedData = discount.limited_relation_product_data;
753
774
 
754
775
  // 时间限制检查
755
- var timeLimit = !!filterDiscountListByBookingTime([discount], (((_product5 = product) === null || _product5 === void 0 ? void 0 : _product5.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
776
+ var timeLimit = !!filterDiscountListByBookingTime([discount], (((_product4 = product) === null || _product4 === void 0 ? void 0 : _product4.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
756
777
  if (!timeLimit) {
757
778
  return false;
758
779
  }
@@ -772,7 +793,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
772
793
  }
773
794
 
774
795
  // 套餐规则检查
775
- var isBundleAvailable = _this3.checkPackageSubItemUsageRules(discount, flatItem);
796
+ var isBundleAvailable = _this4.checkPackageSubItemUsageRules(discount, flatItem);
776
797
  return isLimitedProduct && isBundleAvailable;
777
798
  };
778
799
 
@@ -832,7 +853,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
832
853
  // 收集该折扣卡适用的商品(排除被其他专属折扣卡占用的商品)
833
854
  var applicableProducts = [];
834
855
  sortedFlattenedList.forEach(function (flatItem) {
835
- var _flatItem$parentProdu2, _flatItem$parentProdu3, _product$price, _ref5, _flatItem$original_pr;
856
+ var _flatItem$parentProdu2, _flatItem$parentProdu3, _product$price, _ref6, _flatItem$original_pr;
836
857
  // 🔥 检查该商品是否被其他专属折扣卡占用
837
858
  var occupyingDiscountId = occupiedItems.get(flatItem._id);
838
859
  if (occupyingDiscountId !== undefined && occupyingDiscountId !== discount.id) {
@@ -860,7 +881,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
860
881
 
861
882
  // 对于主商品:使用 price
862
883
  // 对于子商品:优先使用 flatItem.original_price,否则使用 flatItem.price
863
- var originalAmount = flatItem.type === 'main' ? Number((_product$price = product.price) !== null && _product$price !== void 0 ? _product$price : 0) : Number((_ref5 = (_flatItem$original_pr = flatItem.original_price) !== null && _flatItem$original_pr !== void 0 ? _flatItem$original_pr : flatItem.price) !== null && _ref5 !== void 0 ? _ref5 : 0);
884
+ var originalAmount = flatItem.type === 'main' ? Number((_product$price = product.price) !== null && _product$price !== void 0 ? _product$price : 0) : Number((_ref6 = (_flatItem$original_pr = flatItem.original_price) !== null && _flatItem$original_pr !== void 0 ? _flatItem$original_pr : flatItem.price) !== null && _ref6 !== void 0 ? _ref6 : 0);
864
885
 
865
886
  // 传递 parentQuantity 用于差值处理时判断是否是真正的"数量为1"
866
887
  var productData = {
@@ -915,32 +936,33 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
915
936
  };
916
937
  originProduct = flatItem.originProduct;
917
938
  }
939
+ var isItemRewardProductDiscount = _this4.isItemRewardProductDiscount(product);
918
940
  addModeDiscount.forEach(function (discount) {
919
- var _product6, _product7, _product8, _product9, _flatItem$bundleItem3, _flatItem$bundleItem4, _discount$config;
941
+ var _product5, _product6, _product7, _product8, _flatItem$bundleItem3, _flatItem$bundleItem4, _discount$config;
920
942
  var limitedData = discount === null || discount === void 0 ? void 0 : discount.limited_relation_product_data;
921
943
  // 拿到discount配置的holder信息 product信息 product.holder 加在 isLimitedProduct
922
944
  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;
923
- var isHolderMatch = _this3.checkHolderMatch(discount, {
945
+ var isHolderMatch = _this4.checkHolderMatch(discount, {
924
946
  isNeedHolder: resolveIsFormSubject(_tempVar) && !(_tempVar !== null && _tempVar !== void 0 && _tempVar.isNormalProduct),
925
947
  holder_id: (_tempVar === null || _tempVar === void 0 ? void 0 : _tempVar.holder_id) || product.holder_id
926
948
  }, holders);
927
949
  var timeLimit = true;
928
- timeLimit = !!filterDiscountListByBookingTime([discount], (((_product6 = product) === null || _product6 === void 0 ? void 0 : _product6.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
950
+ timeLimit = !!filterDiscountListByBookingTime([discount], (((_product5 = product) === null || _product5 === void 0 ? void 0 : _product5.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
929
951
  // 是符合折扣的商品
930
952
  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;
931
953
 
932
954
  // 编辑的商品 使用了优惠券不可用
933
- 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) {
955
+ var isAvailableProduct = flatItem.type === 'main' ? !((_product6 = product) !== null && _product6 !== void 0 && _product6.booking_id && (_product7 = product) !== null && _product7 !== void 0 && (_product7 = _product7.discount_list) !== null && _product7 !== void 0 && _product7.length && (_product8 = product) !== null && _product8 !== void 0 && (_product8 = _product8.discount_list) !== null && _product8 !== void 0 && _product8.every(function (discount) {
934
956
  return discount.id && ['good_pass', 'discount_card', 'product_discount_card'].includes(discount.tag || discount.type);
935
957
  })) : !(flatItem !== null && flatItem !== void 0 && flatItem.booking_id && !!(flatItem !== null && flatItem !== void 0 && (_flatItem$bundleItem3 = flatItem.bundleItem) !== null && _flatItem$bundleItem3 !== void 0 && (_flatItem$bundleItem3 = _flatItem$bundleItem3.discount_list) !== null && _flatItem$bundleItem3 !== void 0 && _flatItem$bundleItem3.length) && flatItem !== null && flatItem !== void 0 && (_flatItem$bundleItem4 = flatItem.bundleItem) !== null && _flatItem$bundleItem4 !== void 0 && (_flatItem$bundleItem4 = _flatItem$bundleItem4.discount_list) !== null && _flatItem$bundleItem4 !== void 0 && _flatItem$bundleItem4.every(function (discount) {
936
958
  return discount.id;
937
959
  }));
938
960
 
939
961
  // 套餐是否可用判断
940
- var isBundleAvailable = _this3.checkPackageSubItemUsageRules(discount, flatItem);
962
+ var isBundleAvailable = _this4.checkPackageSubItemUsageRules(discount, flatItem);
941
963
 
942
964
  // 判断优惠券是否适用于该商品
943
- if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && (_discount$config = discount.config) !== null && _discount$config !== void 0 && _discount$config.isAvailable) {
965
+ if (isAvailableProduct && !isItemRewardProductDiscount && isLimitedProduct && timeLimit && isBundleAvailable && (_discount$config = discount.config) !== null && _discount$config !== void 0 && _discount$config.isAvailable) {
944
966
  var _discountApplicabilit, _discount$metadata4, _discount$metadata5;
945
967
  // 记录此优惠券适用的商品
946
968
  (_discountApplicabilit = discountApplicability.get(discount.id)) === null || _discountApplicabilit === void 0 || _discountApplicabilit.push(product.id);
@@ -988,13 +1010,13 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
988
1010
  };
989
1011
  var optionDiscountAmount = 0;
990
1012
  var discountedOptions = options.map(function (option) {
991
- var _ref6, _ref7, _option$_original_pri, _ref8, _option$num, _rest$price, _option$_original_pri2;
1013
+ var _ref7, _ref8, _option$_original_pri, _ref9, _option$num, _rest$price, _option$_original_pri2;
992
1014
  // 折前单价:优先 price,缺失再 add_price;已写回折后价时用 _original_price(或旧字段 _original_add_price)
993
- var rawUnit = (_ref6 = (_ref7 = (_option$_original_pri = option._original_price) !== null && _option$_original_pri !== void 0 ? _option$_original_pri : option._original_add_price) !== null && _ref7 !== void 0 ? _ref7 : option.price) !== null && _ref6 !== void 0 ? _ref6 : option.add_price;
1015
+ var rawUnit = (_ref7 = (_ref8 = (_option$_original_pri = option._original_price) !== null && _option$_original_pri !== void 0 ? _option$_original_pri : option._original_add_price) !== null && _ref8 !== void 0 ? _ref8 : option.price) !== null && _ref7 !== void 0 ? _ref7 : option.add_price;
994
1016
  var baseUnitNum = Number(rawUnit !== null && rawUnit !== void 0 ? rawUnit : 0);
995
1017
  if (baseUnitNum <= 0) return option;
996
1018
  var discountedPrice = getDiscountAmount(discount, baseUnitNum, baseUnitNum);
997
- var optQty = Number((_ref8 = (_option$num = option.num) !== null && _option$num !== void 0 ? _option$num : option.quantity) !== null && _ref8 !== void 0 ? _ref8 : 1);
1019
+ var optQty = Number((_ref9 = (_option$num = option.num) !== null && _option$num !== void 0 ? _option$num : option.quantity) !== null && _ref9 !== void 0 ? _ref9 : 1);
998
1020
  optionDiscountAmount = new Decimal(optionDiscountAmount).plus(new Decimal(baseUnitNum).minus(discountedPrice).mul(optQty)).toNumber();
999
1021
  var _original_add_price = option._original_add_price,
1000
1022
  rest = _objectWithoutProperties(option, _excluded);
@@ -1028,9 +1050,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1028
1050
  var getOptionTotal = function getOptionTotal(options) {
1029
1051
  if (!(options !== null && options !== void 0 && options.length)) return 0;
1030
1052
  return options.reduce(function (sum, opt) {
1031
- var _ref9, _opt$price, _ref10, _opt$num;
1032
- var unit = Number((_ref9 = (_opt$price = opt.price) !== null && _opt$price !== void 0 ? _opt$price : opt.add_price) !== null && _ref9 !== void 0 ? _ref9 : 0);
1033
- var n = Number((_ref10 = (_opt$num = opt.num) !== null && _opt$num !== void 0 ? _opt$num : opt.quantity) !== null && _ref10 !== void 0 ? _ref10 : 1);
1053
+ var _ref10, _opt$price, _ref11, _opt$num;
1054
+ var unit = Number((_ref10 = (_opt$price = opt.price) !== null && _opt$price !== void 0 ? _opt$price : opt.add_price) !== null && _ref10 !== void 0 ? _ref10 : 0);
1055
+ var n = Number((_ref11 = (_opt$num = opt.num) !== null && _opt$num !== void 0 ? _opt$num : opt.quantity) !== null && _ref11 !== void 0 ? _ref11 : 1);
1034
1056
  return new Decimal(sum).plus(new Decimal(unit).mul(n)).toNumber();
1035
1057
  }, 0);
1036
1058
  };
@@ -1038,7 +1060,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1038
1060
  // 然后再处理应用哪些优惠券,此时只考虑filteredDiscountList中的优惠券
1039
1061
  // 🔥 使用扁平化后的列表进行处理
1040
1062
  sortedFlattenedList.forEach(function (flatItem, index) {
1041
- var _product10, _originProduct, _originProduct2, _originProduct3, _product$discount_lis2, _product11;
1063
+ var _product9, _originProduct, _originProduct2, _originProduct3, _product$discount_lis2, _product10;
1042
1064
  // 获取商品数据
1043
1065
  var product, originProduct;
1044
1066
  if (flatItem.type === 'main') {
@@ -1062,8 +1084,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1062
1084
  };
1063
1085
  originProduct = flatItem.originProduct;
1064
1086
  }
1065
- var isPersistedProduct = ((_product10 = product) === null || _product10 === void 0 ? void 0 : _product10.booking_id) || ((_originProduct = originProduct) === null || _originProduct === void 0 ? void 0 : _originProduct.order_detail_id) || ((_originProduct2 = originProduct) === null || _originProduct2 === void 0 ? void 0 : _originProduct2.orderDetailId) || ((_originProduct3 = originProduct) === null || _originProduct3 === void 0 ? void 0 : _originProduct3.booking_id);
1066
- var hasExistingWalletDiscount = ((_product$discount_lis2 = product.discount_list) === null || _product$discount_lis2 === void 0 ? void 0 : _product$discount_lis2.length) && ((_product11 = product) === null || _product11 === void 0 || (_product11 = _product11.discount_list) === null || _product11 === void 0 ? void 0 : _product11.every(function (discount) {
1087
+ var isPersistedProduct = ((_product9 = product) === null || _product9 === void 0 ? void 0 : _product9.booking_id) || ((_originProduct = originProduct) === null || _originProduct === void 0 ? void 0 : _originProduct.order_detail_id) || ((_originProduct2 = originProduct) === null || _originProduct2 === void 0 ? void 0 : _originProduct2.orderDetailId) || ((_originProduct3 = originProduct) === null || _originProduct3 === void 0 ? void 0 : _originProduct3.booking_id);
1088
+ var hasExistingWalletDiscount = ((_product$discount_lis2 = product.discount_list) === null || _product$discount_lis2 === void 0 ? void 0 : _product$discount_lis2.length) && ((_product10 = product) === null || _product10 === void 0 || (_product10 = _product10.discount_list) === null || _product10 === void 0 ? void 0 : _product10.every(function (discount) {
1067
1089
  var _discount$id, _discount$discount4;
1068
1090
  var discountIdentity = (_discount$id = discount.id) !== null && _discount$id !== void 0 ? _discount$id : (_discount$discount4 = discount.discount) === null || _discount$discount4 === void 0 ? void 0 : _discount$discount4.resource_id;
1069
1091
  var discountType = discount.tag || discount.type;
@@ -1074,17 +1096,17 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1074
1096
  if (isPersistedProduct && hasExistingWalletDiscount) {
1075
1097
  if (flatItem.type === 'main') {
1076
1098
  processedProductsMap.set(product._id, [originProduct]);
1077
- } else {
1078
- processedFlatItemsMap.set(flatItem._id, [_objectSpread(_objectSpread({}, flatItem), {}, {
1079
- processed: true
1080
- })]);
1081
1099
  }
1100
+ // bundle 虚拟项没有携带完整的历史价格字段。这里不写入 processed map,
1101
+ // 重组阶段会直接保留原始 bundleItem,避免把 bundle_selling_price
1102
+ // 覆盖为未折扣的 price,导致已支付金额再次进入应付。
1082
1103
  return;
1083
1104
  }
1084
1105
 
1085
1106
  // 找到适用于此商品的所有优惠券,仅考虑isSelected不为false的优惠券
1086
1107
  var applicableDiscounts = sortedDiscountList.filter(function (discount) {
1087
1108
  var _product$discount_lis3, _product$discount_lis4;
1109
+ if (_this4.isItemRewardProductDiscount(product)) return false;
1088
1110
  // 🔥 检查策略可用性(针对 good_pass 和折扣卡)
1089
1111
  var discountType = discount.tag || discount.type;
1090
1112
  var currentOriginUid = getOriginProductUid(originProduct);
@@ -1130,7 +1152,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1130
1152
 
1131
1153
  // 拿到discount配置的holder信息 product信息 product.holder 不可用return false
1132
1154
  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;
1133
- var isHolderMatch = _this3.checkHolderMatch(discount, {
1155
+ var isHolderMatch = _this4.checkHolderMatch(discount, {
1134
1156
  isNeedHolder: resolveIsFormSubject(_tempVar) && !(_tempVar !== null && _tempVar !== void 0 && _tempVar.isNormalProduct),
1135
1157
  holder_id: (_tempVar === null || _tempVar === void 0 ? void 0 : _tempVar.holder_id) || product.holder_id
1136
1158
  }, holders);
@@ -1148,13 +1170,13 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1148
1170
  return false;
1149
1171
  }
1150
1172
  // 检查 package_sub_item_usage_rules
1151
- if (!_this3.checkPackageSubItemUsageRules(discount, flatItem)) {
1173
+ if (!_this4.checkPackageSubItemUsageRules(discount, flatItem)) {
1152
1174
  return false;
1153
1175
  }
1154
1176
  return true;
1155
1177
  } else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
1156
1178
  // 检查 package_sub_item_usage_rules
1157
- if (!_this3.checkPackageSubItemUsageRules(discount, flatItem)) {
1179
+ if (!_this4.checkPackageSubItemUsageRules(discount, flatItem)) {
1158
1180
  return false;
1159
1181
  }
1160
1182
  return true;
@@ -1162,28 +1184,36 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1162
1184
  return false;
1163
1185
  });
1164
1186
 
1165
- // 选择第一个适用的优惠券(已经按过期时间排序)
1166
- // 如果有 isScan isSelected 的折扣卡,则优先选中,否则再选择第一个
1167
- // 用于处理:先手动扫描了一张折扣卡,扫描完以后带入客户信息,但是之前那张折扣卡不是最优惠的情况
1168
- var selectedDiscountCard = applicableDiscounts.find(function (n) {
1187
+ // 用户显式点击某张折扣卡时,本次选择优先于自动排序和扫码默认选择。
1188
+ // 目标仍必须在当前商品的 applicableDiscounts 中,因此不会绕过 Holder、时间或商品范围校验。
1189
+ var explicitlySelectedDiscountCard = (options === null || options === void 0 ? void 0 : options.isSelected) === true && options.discountId !== undefined ? applicableDiscounts.find(function (discount) {
1190
+ var discountType = discount.tag || discount.type;
1191
+ return String(discount.id) === String(options.discountId) && ['discount_card', 'product_discount_card'].includes(discountType);
1192
+ }) : undefined;
1193
+
1194
+ // 没有显式选择时保持现有行为:扫码且已选中的折扣卡优先,否则使用自动排序第一项。
1195
+ var scannedSelectedDiscountCard = applicableDiscounts.find(function (n) {
1169
1196
  return n.isScan && n.isSelected && (n.tag || n.type) !== 'good_pass';
1170
1197
  });
1198
+ var selectedDiscountCard = explicitlySelectedDiscountCard || scannedSelectedDiscountCard;
1171
1199
  var selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
1172
1200
 
1173
1201
  // 如果是手动折扣,则不适用优惠券
1174
1202
  var isManualDiscount = false;
1203
+ var isItemRewardProductDiscount = false;
1175
1204
  if (flatItem.type === 'main') {
1176
- var _product$discount_lis5, _product$discount_lis6, _product12, _product12$every;
1205
+ var _product$discount_lis5, _product$discount_lis6, _product11, _product11$every;
1177
1206
  // 主商品:判断自身是否手动折扣
1178
1207
  isManualDiscount = typeof product.isManualDiscount === 'boolean' ? product.isManualDiscount : ((_product$discount_lis5 = product.discount_list) === null || _product$discount_lis5 === void 0 ? void 0 : _product$discount_lis5.some(function (item) {
1179
1208
  return item.type === 'product';
1180
1209
  })) || product.total != product.origin_total && (product.bundle || []).every(function (item) {
1181
- var _ref11;
1182
- return !((_ref11 = item.discount_list || []) !== null && _ref11 !== void 0 && _ref11.length);
1183
- }) && (!((_product$discount_lis6 = product.discount_list) !== null && _product$discount_lis6 !== void 0 && _product$discount_lis6.length) || ((_product12 = product) === null || _product12 === void 0 || (_product12 = _product12.discount_list) === null || _product12 === void 0 || (_product12$every = _product12.every) === null || _product12$every === void 0 ? void 0 : _product12$every.call(_product12, function (item) {
1210
+ var _ref12;
1211
+ return !((_ref12 = item.discount_list || []) !== null && _ref12 !== void 0 && _ref12.length);
1212
+ }) && (!((_product$discount_lis6 = product.discount_list) !== null && _product$discount_lis6 !== void 0 && _product$discount_lis6.length) || ((_product11 = product) === null || _product11 === void 0 || (_product11 = _product11.discount_list) === null || _product11 === void 0 || (_product11$every = _product11.every) === null || _product11$every === void 0 ? void 0 : _product11$every.call(_product11, function (item) {
1184
1213
  return item.type === 'product';
1185
1214
  })));
1186
- if (product.inPromotion) {
1215
+ isItemRewardProductDiscount = _this4.isItemRewardProductDiscount(product);
1216
+ if (product.inPromotion && !isItemRewardProductDiscount) {
1187
1217
  isManualDiscount = false;
1188
1218
  }
1189
1219
  } else {
@@ -1194,8 +1224,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1194
1224
  isManualDiscount = typeof parentProduct.isManualDiscount === 'boolean' ? parentProduct.isManualDiscount : ((_parentProduct$discou = parentProduct.discount_list) === null || _parentProduct$discou === void 0 ? void 0 : _parentProduct$discou.some(function (item) {
1195
1225
  return item.type === 'product';
1196
1226
  })) || parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every(function (item) {
1197
- var _ref12;
1198
- return !((_ref12 = item.discount_list || []) !== null && _ref12 !== void 0 && _ref12.length);
1227
+ var _ref13;
1228
+ return !((_ref13 = item.discount_list || []) !== null && _ref13 !== void 0 && _ref13.length);
1199
1229
  }) && (!((_parentProduct$discou2 = parentProduct.discount_list) !== null && _parentProduct$discou2 !== void 0 && _parentProduct$discou2.length) || (parentProduct === null || parentProduct === void 0 || (_parentProduct$discou3 = parentProduct.discount_list) === null || _parentProduct$discou3 === void 0 || (_parentProduct$discou4 = _parentProduct$discou3.every) === null || _parentProduct$discou4 === void 0 ? void 0 : _parentProduct$discou4.call(_parentProduct$discou3, function (item) {
1200
1230
  return item.type === 'product';
1201
1231
  })));
@@ -1265,7 +1295,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1265
1295
  // 主商品:保持原有逻辑,还原 option 价格
1266
1296
  var restoredOptions = restoreOptionPrices(product.options);
1267
1297
  if (product.isClient) {
1268
- processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {} : {
1298
+ processedProductsMap.set(product._id, [_this4.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {} : {
1269
1299
  origin_total: getProductOriginTotalPrice({
1270
1300
  product: {
1271
1301
  original_price: product.original_price
@@ -1285,37 +1315,39 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1285
1315
  price: product.price,
1286
1316
  options: restoredOptions
1287
1317
  }), {}, {
1288
- discount_list: isManualDiscount ? _this3.resolveDiscountListForManualOverride(product.discount_list) : _this3.filterDiscountListByType(product.discount_list, 'promotion')
1318
+ discount_list: isManualDiscount ? _this4.resolveDiscountListForManualOverride(product.discount_list) : _this4.filterDiscountListByType(product.discount_list, 'promotion')
1289
1319
  }))]);
1290
1320
  } else {
1291
- var _ref13, _product$_promotion$f, _product13, _product$origin_total;
1292
- var total = product.inPromotion ? (_ref13 = (_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 && _ref13 !== void 0 ? _ref13 : product.total : (_product$origin_total = product.origin_total) !== null && _product$origin_total !== void 0 ? _product$origin_total : product.total;
1321
+ var _ref14, _product$_promotion$f, _product12, _product$origin_total;
1322
+ var total = product.inPromotion ? (_ref14 = (_product$_promotion$f = (_product12 = product) === null || _product12 === void 0 || (_product12 = _product12._promotion) === null || _product12 === void 0 ? void 0 : _product12.finalPrice) !== null && _product$_promotion$f !== void 0 ? _product$_promotion$f : product.origin_total) !== null && _ref14 !== void 0 ? _ref14 : product.total : (_product$origin_total = product.origin_total) !== null && _product$origin_total !== void 0 ? _product$origin_total : product.total;
1293
1323
  var main_product_selling_price = product.price;
1294
1324
  if ((product.discount_list || []).some(function (item) {
1295
1325
  return item.type === 'promotion';
1296
- }) || isBoolean(product.vouchersApplicable) && !product.vouchersApplicable) {
1326
+ }) || isItemRewardProductDiscount || isBoolean(product.vouchersApplicable) && !product.vouchersApplicable) {
1297
1327
  var _product$total, _product$main_product;
1298
1328
  total = (_product$total = product.total) !== null && _product$total !== void 0 ? _product$total : product.origin_total;
1299
1329
  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;
1300
1330
  }
1301
- processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {
1331
+ processedProductsMap.set(product._id, [_this4.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? _objectSpread({
1302
1332
  price: product.price,
1303
- main_product_selling_price: product.price
1304
- } : {
1333
+ main_product_selling_price: isItemRewardProductDiscount ? main_product_selling_price : product.price
1334
+ }, isItemRewardProductDiscount ? {
1335
+ total: total
1336
+ } : {}) : {
1305
1337
  _id: product._id.split('___')[0] + '___' + index,
1306
1338
  total: total,
1307
1339
  price: product.price,
1308
1340
  main_product_selling_price: main_product_selling_price,
1309
1341
  options: restoredOptions
1310
1342
  }), {}, {
1311
- discount_list: isManualDiscount ? _this3.resolveDiscountListForManualOverride(product.discount_list) : _this3.filterDiscountListByType(product.discount_list, 'promotion')
1343
+ discount_list: isManualDiscount ? _this4.resolveDiscountListForManualOverride(product.discount_list) : _this4.filterDiscountListByType(product.discount_list, 'promotion')
1312
1344
  }))]);
1313
1345
  }
1314
1346
  } else {
1315
1347
  var _flatItem$bundleItem8, _flatItem$bundleItem9;
1316
1348
  // bundle子商品:保存到扁平化Map
1317
1349
  processedFlatItemsMap.set(flatItem._id, [_objectSpread(_objectSpread({}, flatItem), {}, {
1318
- discount_list: isManualDiscount ? _this3.resolveDiscountListForManualOverride(((_flatItem$bundleItem8 = flatItem.bundleItem) === null || _flatItem$bundleItem8 === void 0 ? void 0 : _flatItem$bundleItem8.discount_list) || []) : _this3.filterDiscountListByType(((_flatItem$bundleItem9 = flatItem.bundleItem) === null || _flatItem$bundleItem9 === void 0 ? void 0 : _flatItem$bundleItem9.discount_list) || [], 'promotion'),
1350
+ discount_list: isManualDiscount ? _this4.resolveDiscountListForManualOverride(((_flatItem$bundleItem8 = flatItem.bundleItem) === null || _flatItem$bundleItem8 === void 0 ? void 0 : _flatItem$bundleItem8.discount_list) || []) : _this4.filterDiscountListByType(((_flatItem$bundleItem9 = flatItem.bundleItem) === null || _flatItem$bundleItem9 === void 0 ? void 0 : _flatItem$bundleItem9.discount_list) || [], 'promotion'),
1319
1351
  price: isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price,
1320
1352
  processed: true
1321
1353
  })]);
@@ -1356,8 +1388,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1356
1388
  var _product$total2;
1357
1389
  _total = (_product$total2 = product.total) !== null && _product$total2 !== void 0 ? _product$total2 : product.origin_total;
1358
1390
  }
1359
- arr.push(_this3.hooks.setProduct(originProduct, {
1360
- discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1391
+ arr.push(_this4.hooks.setProduct(originProduct, {
1392
+ discount_list: _this4.filterDiscountListByType(product.discount_list, 'promotion'),
1361
1393
  quantity: totalQuantity - splitCount,
1362
1394
  _id: product._id.split('___')[0],
1363
1395
  total: _total
@@ -1381,7 +1413,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1381
1413
  // 优先从 origin_total拿,可能会拿不到(比如用户端预约在没有配置 original_price 的情况下)
1382
1414
  var productOriginTotal = product.origin_total || product.total || 0;
1383
1415
  // 如果当前 product 有 discount_list,则先从 origin_total 拿
1384
- if (_this3.filterDiscountListByType(product.discount_list, 'promotion').length && product.origin_total) {
1416
+ if (_this4.filterDiscountListByType(product.discount_list, 'promotion').length && product.origin_total) {
1385
1417
  productOriginTotal = product.origin_total;
1386
1418
  }
1387
1419
  // 如果originProduct?._productInit?.original_price为 0,product.origin_total可能为空,此时取 product.total
@@ -1408,9 +1440,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1408
1440
  amount = productAllocation.discountAmount;
1409
1441
  productDiscountDifference = productAllocation.difference;
1410
1442
  mainProductSellingPrice = Math.max(new Decimal(product.price).minus(amount).toNumber(), 0);
1411
- } else if (resolveReapplyEditModeDiscountPercent(originProduct, _selectedDiscount) !== undefined) {
1443
+ } else if (resolveReapplyBookingDiscountPercent(originProduct, _selectedDiscount) !== undefined) {
1412
1444
  // Change time 重套编辑态折扣卡时,历史 par_value 不是运行时折扣口径,优先使用后端快照里的 percent。
1413
- var percent = resolveReapplyEditModeDiscountPercent(originProduct, _selectedDiscount);
1445
+ var percent = resolveReapplyBookingDiscountPercent(originProduct, _selectedDiscount);
1414
1446
  reapplyDiscountPercent = new Decimal(percent).toFixed(2);
1415
1447
  mainProductSellingPrice = new Decimal(product.price || 0).mul(new Decimal(100).minus(percent)).div(100).toDecimalPlaces(2).toNumber();
1416
1448
  amount = new Decimal(product.price).minus(mainProductSellingPrice).toNumber();
@@ -1468,7 +1500,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1468
1500
  // 记录应用了优惠券的商品
1469
1501
  // 后续更新价格改为 getProductTotalPrice getProductOriginTotalPrice逻辑
1470
1502
  if (product.isClient) {
1471
- arr.push(_this3.hooks.setProduct(originProduct, {
1503
+ arr.push(_this4.hooks.setProduct(originProduct, {
1472
1504
  discount_list: [discountDetail],
1473
1505
  // good_pass:主商品价以折后价为准;勿用 product.price - amount(amount 含 option 优惠时会算错)
1474
1506
  price: isGoodPass ? mainProductSellingPrice : product.price,
@@ -1486,8 +1518,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1486
1518
  options: discountedOptions
1487
1519
  }));
1488
1520
  } else {
1489
- arr.push(_this3.hooks.setProduct(originProduct, {
1490
- discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion').concat([discountDetail]),
1521
+ arr.push(_this4.hooks.setProduct(originProduct, {
1522
+ discount_list: _this4.filterDiscountListByType(product.discount_list, 'promotion').concat([discountDetail]),
1491
1523
  _id: product._id.split('___')[0] + '___' + _selectedDiscount.id + index,
1492
1524
  price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
1493
1525
  quantity: isNeedSplit ? 1 : product.quantity,
@@ -1576,7 +1608,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1576
1608
  }));
1577
1609
  }
1578
1610
  } else {
1579
- var _selectedDiscount3$me, _selectedDiscount3$me2, _flatItem$parentProdu9;
1611
+ var _selectedDiscount3$me, _selectedDiscount3$me2, _reapplyDiscountPerce2, _flatItem$parentProdu9;
1580
1612
  // 折扣卡:不拆分数量,直接应用
1581
1613
  var _selectedDiscount3 = selectedDiscountCard || applicableDiscounts[0];
1582
1614
  usedDiscounts.set(_selectedDiscount3.id, true);
@@ -1594,11 +1626,19 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1594
1626
  var targetProductTotal;
1595
1627
  var fixedAmountPerItem;
1596
1628
  var _productDiscountDifference;
1629
+ var _reapplyDiscountPercent;
1597
1630
  if (_isOrderLevel && _productAllocation) {
1598
1631
  // order_level:使用预计算的单价折扣金额(已经是单价,无需再除以数量)
1599
1632
  fixedAmountPerItem = _productAllocation.discountAmount;
1600
1633
  _productDiscountDifference = _productAllocation.difference;
1601
1634
  targetProductTotal = Math.max(new Decimal(_productOriginTotal).minus(fixedAmountPerItem).toNumber(), 0);
1635
+ } else if (resolveReapplyBookingDiscountPercent(originProduct, _selectedDiscount3) !== undefined) {
1636
+ // hydrate 后 par_value 可能是余额/原值(例如 3500),百分比口径以
1637
+ // 后端折扣快照 discount.percent 为准,与主商品重套逻辑保持一致。
1638
+ var _percent = resolveReapplyBookingDiscountPercent(originProduct, _selectedDiscount3);
1639
+ _reapplyDiscountPercent = new Decimal(_percent).toFixed(2);
1640
+ targetProductTotal = new Decimal(_productOriginTotal).mul(new Decimal(100).minus(_percent)).div(100).toDecimalPlaces(2).toNumber();
1641
+ fixedAmountPerItem = new Decimal(_productOriginTotal).minus(targetProductTotal).toNumber();
1602
1642
  } else {
1603
1643
  // item_level 或其他类型:使用原有逻辑
1604
1644
  targetProductTotal = getDiscountAmount(_selectedDiscount3, _productOriginTotal, _productOriginTotal);
@@ -1619,7 +1659,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1619
1659
  title: _selectedDiscount3.format_title,
1620
1660
  original_amount: product.original_price,
1621
1661
  product_id: product.id || product.product_id,
1622
- percent: _selectedDiscount3.par_value,
1662
+ percent: (_reapplyDiscountPerce2 = _reapplyDiscountPercent) !== null && _reapplyDiscountPerce2 !== void 0 ? _reapplyDiscountPerce2 : _selectedDiscount3.par_value,
1623
1663
  discount_product_id: _selectedDiscount3.product_id
1624
1664
  },
1625
1665
  metadata: _objectSpread({
@@ -1652,7 +1692,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1652
1692
  var reconstructProductsWithBundle = function reconstructProductsWithBundle(processedProductsMap, processedFlatItemsMap, originalProductList) {
1653
1693
  var result = [];
1654
1694
  originalProductList.forEach(function (originProduct) {
1655
- var product = _this3.hooks.getProduct(originProduct);
1695
+ var product = _this4.hooks.getProduct(originProduct);
1656
1696
 
1657
1697
  // 获取主商品处理结果
1658
1698
  var mainProductArr = processedProductsMap.get(product._id);
@@ -1661,8 +1701,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1661
1701
  var getDefaultProduct = function getDefaultProduct() {
1662
1702
  var restoredOptions = restoreOptionPrices(product.options);
1663
1703
  if (product.isClient) {
1664
- return _this3.hooks.setProduct(originProduct, {
1665
- discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1704
+ return _this4.hooks.setProduct(originProduct, {
1705
+ discount_list: _this4.filterDiscountListByType(product.discount_list, 'promotion'),
1666
1706
  price: product.price,
1667
1707
  origin_total: getProductOriginTotalPrice({
1668
1708
  product: {
@@ -1683,8 +1723,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1683
1723
  options: restoredOptions
1684
1724
  });
1685
1725
  } else {
1686
- return _this3.hooks.setProduct(originProduct, {
1687
- discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1726
+ return _this4.hooks.setProduct(originProduct, {
1727
+ discount_list: _this4.filterDiscountListByType(product.discount_list, 'promotion'),
1688
1728
  total: product.total,
1689
1729
  origin_total: product.origin_total,
1690
1730
  price: product.price,
@@ -1732,10 +1772,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1732
1772
  }
1733
1773
 
1734
1774
  // 🔥 2. 如果有子商品应用了商品券,且主商品数量大于1,需要拆分主商品
1735
- var mainProductQuantity = mainProductArr[0] ? _this3.hooks.getProduct(mainProductArr[0]).quantity : 1;
1775
+ var mainProductQuantity = mainProductArr[0] ? _this4.hooks.getProduct(mainProductArr[0]).quantity : 1;
1736
1776
  if (hasGoodPassApplied && mainProductArr.length === 1 && mainProductQuantity > 1) {
1737
1777
  var mainProduct = mainProductArr[0];
1738
- var mainProductData = _this3.hooks.getProduct(mainProduct);
1778
+ var mainProductData = _this4.hooks.getProduct(mainProduct);
1739
1779
 
1740
1780
  // 🔥 方案:拆分成2个主商品
1741
1781
  // 1. 一个主商品(qty=1)包含拆分后的bundle
@@ -1750,11 +1790,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1750
1790
  processedItems.forEach(function (item) {
1751
1791
  // 🔥 更新 discount_list 中的 num,使其与拆分后的 item.num 一致
1752
1792
  var updatedDiscountList = (item.discount_list || []).map(function (discount) {
1753
- var _item$metadata;
1793
+ var _item$metadata3;
1754
1794
  return _objectSpread(_objectSpread({}, discount), {}, {
1755
1795
  metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
1756
1796
  num: item.num,
1757
- custom_product_bundle_map_id: (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata.custom_product_bundle_map_id
1797
+ custom_product_bundle_map_id: (_item$metadata3 = item.metadata) === null || _item$metadata3 === void 0 ? void 0 : _item$metadata3.custom_product_bundle_map_id
1758
1798
  })
1759
1799
  // num: item.num, // 使用拆分后的 num
1760
1800
  });
@@ -1773,11 +1813,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1773
1813
  if (item.processed) {
1774
1814
  // 🔥 同样需要更新 discount_list 中的 num
1775
1815
  var _updatedDiscountList = (item.discount_list || []).map(function (discount) {
1776
- var _item$metadata2;
1816
+ var _item$metadata4;
1777
1817
  return _objectSpread(_objectSpread({}, discount), {}, {
1778
1818
  metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
1779
1819
  num: item.num,
1780
- custom_product_bundle_map_id: (_item$metadata2 = item.metadata) === null || _item$metadata2 === void 0 ? void 0 : _item$metadata2.custom_product_bundle_map_id
1820
+ custom_product_bundle_map_id: (_item$metadata4 = item.metadata) === null || _item$metadata4 === void 0 ? void 0 : _item$metadata4.custom_product_bundle_map_id
1781
1821
  })
1782
1822
  // num: item.num, // 使用当前的 num
1783
1823
  });
@@ -1818,8 +1858,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1818
1858
 
1819
1859
  // 🔥 使用更新后的列表计算折扣金额
1820
1860
  var mainDiscountList = updatedMainDiscountList.filter(function (item) {
1821
- var _item$metadata3;
1822
- return !(item !== null && item !== void 0 && (_item$metadata3 = item.metadata) !== null && _item$metadata3 !== void 0 && _item$metadata3.custom_product_bundle_map_id);
1861
+ var _item$metadata5;
1862
+ return !(item !== null && item !== void 0 && (_item$metadata5 = item.metadata) !== null && _item$metadata5 !== void 0 && _item$metadata5.custom_product_bundle_map_id);
1823
1863
  });
1824
1864
  if (mainDiscountList && mainDiscountList.length > 0) {
1825
1865
  var _Decimal$minus$toNumb, _mainProductData$orig;
@@ -1850,7 +1890,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1850
1890
  }
1851
1891
 
1852
1892
  // 添加第一个主商品:qty=1,包含拆分后的bundle
1853
- result.push(_this3.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
1893
+ result.push(_this4.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
1854
1894
  _id: "".concat(mainProductData._id.split('___')[0], "___split_discount"),
1855
1895
  quantity: 1,
1856
1896
  discount_list: updatedMainDiscountList,
@@ -1892,8 +1932,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1892
1932
 
1893
1933
  // 🔥 使用更新后的列表计算折扣金额
1894
1934
  var mainDiscountListOriginal = updatedMainDiscountListOriginal.filter(function (item) {
1895
- var _item$metadata4;
1896
- return !(item !== null && item !== void 0 && (_item$metadata4 = item.metadata) !== null && _item$metadata4 !== void 0 && _item$metadata4.custom_product_bundle_map_id);
1935
+ var _item$metadata6;
1936
+ return !(item !== null && item !== void 0 && (_item$metadata6 = item.metadata) !== null && _item$metadata6 !== void 0 && _item$metadata6.custom_product_bundle_map_id);
1897
1937
  });
1898
1938
  if (mainDiscountListOriginal && mainDiscountListOriginal.length > 0) {
1899
1939
  var _Decimal$minus$toNumb2, _mainProductData$orig2;
@@ -1922,7 +1962,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1922
1962
  newOriginTotalOriginal = new Decimal(newOriginTotalOriginal).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
1923
1963
 
1924
1964
  // 添加第二个主商品:qty=原quantity-1,包含原始bundle
1925
- result.push(_this3.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
1965
+ result.push(_this4.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
1926
1966
  _id: "".concat(mainProductData._id.split('___')[0], "___split_normal"),
1927
1967
  quantity: mainProductQuantity - 1,
1928
1968
  discount_list: updatedMainDiscountListOriginal,
@@ -1934,8 +1974,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1934
1974
  } else {
1935
1975
  // 🔥 没有子商品被拆分,使用原有逻辑
1936
1976
  mainProductArr.forEach(function (mainProduct) {
1937
- var _ref15, _mainProductData$main, _mainProductData$disc, _mainProductData$disc2, _mainProductData$disc3;
1938
- var mainProductData = _this3.hooks.getProduct(mainProduct);
1977
+ var _ref16, _mainProductData$main, _mainProductData$disc, _mainProductData$disc2, _mainProductData$disc3;
1978
+ var mainProductData = _this4.hooks.getProduct(mainProduct);
1939
1979
 
1940
1980
  // 重组bundle
1941
1981
  var newBundle = [];
@@ -1949,9 +1989,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1949
1989
  } else {
1950
1990
  // 🔥 关键:拆分后的bundle item
1951
1991
  processedBundleItems.forEach(function (item) {
1952
- var _item$price, _ref14, _item$bundle_selling_;
1992
+ var _item$price, _ref15, _item$bundle_selling_;
1953
1993
  var nextBundlePrice = (_item$price = item.price) !== null && _item$price !== void 0 ? _item$price : bundleItem.price;
1954
- var nextBundleSellingPrice = (_ref14 = (_item$bundle_selling_ = item.bundle_selling_price) !== null && _item$bundle_selling_ !== void 0 ? _item$bundle_selling_ : item.price) !== null && _ref14 !== void 0 ? _ref14 : bundleItem.bundle_selling_price;
1994
+ var nextBundleSellingPrice = (_ref15 = (_item$bundle_selling_ = item.bundle_selling_price) !== null && _item$bundle_selling_ !== void 0 ? _item$bundle_selling_ : item.price) !== null && _ref15 !== void 0 ? _ref15 : bundleItem.bundle_selling_price;
1955
1995
  // 🔥 更新 discount_list 中的 num,使其与拆分后的 item.num 一致
1956
1996
  var updatedDiscountList = (item.discount_list || []).map(function (discount) {
1957
1997
  var _discount$metadata10;
@@ -1978,7 +2018,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1978
2018
 
1979
2019
  // 主商品已经在前面的 setProduct 中应用过折扣;这里只替换 bundle,
1980
2020
  // 避免把主商品 discount_list 再扣一次。
1981
- var mainSellingPrice = (_ref15 = (_mainProductData$main = mainProductData.main_product_selling_price) !== null && _mainProductData$main !== void 0 ? _mainProductData$main : mainProductData.price) !== null && _ref15 !== void 0 ? _ref15 : 0;
2021
+ var mainSellingPrice = (_ref16 = (_mainProductData$main = mainProductData.main_product_selling_price) !== null && _mainProductData$main !== void 0 ? _mainProductData$main : mainProductData.price) !== null && _ref16 !== void 0 ? _ref16 : 0;
1982
2022
  var newTotal = Number(mainSellingPrice || 0);
1983
2023
  var newOriginTotal = Number(mainProductData.original_price || mainProductData.price || 0);
1984
2024
 
@@ -2022,7 +2062,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
2022
2062
  newOriginTotal = new Decimal(newOriginTotal).toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber();
2023
2063
 
2024
2064
  // 生成最终的主商品
2025
- result.push(_this3.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
2065
+ result.push(_this4.hooks.setProduct(mainProduct, _objectSpread(_objectSpread({}, mainProductData), {}, {
2026
2066
  bundle: newBundle,
2027
2067
  total: newTotal,
2028
2068
  origin_total: newOriginTotal
@@ -2126,14 +2166,14 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
2126
2166
  var ruleType = usageRules.type;
2127
2167
  // 套餐适用范围配置
2128
2168
  var packageScope = usageRules === null || usageRules === void 0 ? void 0 : usageRules.package_scope;
2129
- var _ref16 = packageScope || {},
2130
- scopeType = _ref16.type,
2131
- _ref16$exclude_bundle = _ref16.exclude_bundle_product_ids,
2132
- exclude_bundle_product_ids = _ref16$exclude_bundle === void 0 ? [] : _ref16$exclude_bundle,
2133
- _ref16$include_bundle = _ref16.include_bundle_product_ids,
2134
- include_bundle_product_ids = _ref16$include_bundle === void 0 ? [] : _ref16$include_bundle,
2135
- _ref16$filter = _ref16.filter,
2136
- filter = _ref16$filter === void 0 ? 0 : _ref16$filter;
2169
+ var _ref17 = packageScope || {},
2170
+ scopeType = _ref17.type,
2171
+ _ref17$exclude_bundle = _ref17.exclude_bundle_product_ids,
2172
+ exclude_bundle_product_ids = _ref17$exclude_bundle === void 0 ? [] : _ref17$exclude_bundle,
2173
+ _ref17$include_bundle = _ref17.include_bundle_product_ids,
2174
+ include_bundle_product_ids = _ref17$include_bundle === void 0 ? [] : _ref17$include_bundle,
2175
+ _ref17$filter = _ref17.filter,
2176
+ filter = _ref17$filter === void 0 ? 0 : _ref17$filter;
2137
2177
  var isMainProduct = flatItem.type === 'main'; // 单独购买
2138
2178
  var isBundleItem = flatItem.type === 'bundle'; // 套餐中购买
2139
2179