@pisell/pisellos 2.2.42 → 2.2.43

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 (99) 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 +497 -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 +23 -0
  17. package/dist/model/strategy/adapter/walletPass/type.d.ts +165 -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 +965 -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 +15 -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 +196 -95
  35. package/dist/modules/Rules/index.d.ts +8 -3
  36. package/dist/modules/Rules/index.js +143 -23
  37. package/dist/modules/Rules/types.d.ts +1 -0
  38. package/dist/modules/Schedule/index.d.ts +0 -9
  39. package/dist/modules/Schedule/index.js +2 -18
  40. package/dist/modules/Summary/types.d.ts +2 -0
  41. package/dist/modules/Summary/utils.d.ts +6 -0
  42. package/dist/modules/Summary/utils.js +21 -0
  43. package/dist/plugins/window.d.ts +2 -0
  44. package/dist/solution/BookingByStep/index.d.ts +1 -0
  45. package/dist/solution/Checkout/index.js +24 -23
  46. package/dist/solution/RegisterAndLogin/config.js +1 -339
  47. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  48. package/dist/solution/ShopDiscount/index.js +13 -3
  49. package/dist/solution/ShopDiscount/types.d.ts +1 -0
  50. package/lib/index.d.ts +1 -0
  51. package/lib/index.js +3 -1
  52. package/lib/model/index.d.ts +1 -0
  53. package/lib/model/index.js +23 -0
  54. package/lib/model/strategy/adapter/index.d.ts +3 -0
  55. package/lib/model/strategy/adapter/index.js +45 -0
  56. package/lib/model/strategy/adapter/type.d.ts +28 -0
  57. package/lib/model/strategy/adapter/type.js +17 -0
  58. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +84 -0
  59. package/lib/model/strategy/adapter/walletPass/evaluator.js +421 -0
  60. package/lib/model/strategy/adapter/walletPass/example.d.ts +4 -0
  61. package/lib/model/strategy/adapter/walletPass/example.js +207 -0
  62. package/lib/model/strategy/adapter/walletPass/index.d.ts +32 -0
  63. package/lib/model/strategy/adapter/walletPass/index.js +142 -0
  64. package/lib/model/strategy/adapter/walletPass/locales.d.ts +1 -0
  65. package/lib/model/strategy/adapter/walletPass/locales.js +51 -0
  66. package/lib/model/strategy/adapter/walletPass/type.d.ts +165 -0
  67. package/lib/model/strategy/adapter/walletPass/type.js +17 -0
  68. package/lib/model/strategy/adapter/walletPass/utils.d.ts +50 -0
  69. package/lib/model/strategy/adapter/walletPass/utils.js +660 -0
  70. package/lib/model/strategy/index.d.ts +94 -0
  71. package/lib/model/strategy/index.js +413 -0
  72. package/lib/model/strategy/strategy-example.d.ts +5 -0
  73. package/lib/model/strategy/strategy-example.js +318 -0
  74. package/lib/model/strategy/type.d.ts +228 -0
  75. package/lib/model/strategy/type.js +44 -0
  76. package/lib/modules/Cart/types.d.ts +2 -0
  77. package/lib/modules/Cart/utils/cartProduct.js +9 -0
  78. package/lib/modules/Discount/types.d.ts +15 -0
  79. package/lib/modules/Payment/index.d.ts +2 -1
  80. package/lib/modules/Payment/index.js +1 -0
  81. package/lib/modules/Payment/utils.js +3 -0
  82. package/lib/modules/Payment/walletpass.d.ts +23 -0
  83. package/lib/modules/Payment/walletpass.js +99 -17
  84. package/lib/modules/Rules/index.d.ts +8 -3
  85. package/lib/modules/Rules/index.js +352 -187
  86. package/lib/modules/Rules/types.d.ts +1 -0
  87. package/lib/modules/Schedule/index.d.ts +0 -9
  88. package/lib/modules/Schedule/index.js +0 -11
  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 +1 -0
  94. package/lib/solution/Checkout/index.js +3 -3
  95. package/lib/solution/RegisterAndLogin/config.js +1 -265
  96. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  97. package/lib/solution/ShopDiscount/index.js +8 -2
  98. package/lib/solution/ShopDiscount/types.d.ts +1 -0
  99. package/package.json +1 -1
@@ -27,13 +27,10 @@ import { BaseModule } from "../BaseModule";
27
27
  import { uniqueById, getDiscountAmount, getDiscountListAmountTotal, getDiscountListAmount, filterDiscountListByBookingTime } from "../../solution/ShopDiscount/utils";
28
28
  import { getProductOriginTotalPrice, getProductTotalPrice } from "../Cart/utils";
29
29
  import Decimal from 'decimal.js';
30
- import dayjs from 'dayjs';
31
30
  import { isBoolean } from 'lodash-es';
31
+ import dayjs from 'dayjs';
32
32
  import { isOrderLevelFixedAmountDiscount } from "../../solution/ShopDiscount/utils";
33
33
  import { calculateOrderLevelDiscountAllocation } from "../../solution/ShopDiscount/utils";
34
-
35
- // 临时变量
36
- var flatItem;
37
34
  export var RulesModule = /*#__PURE__*/function (_BaseModule) {
38
35
  _inherits(RulesModule, _BaseModule);
39
36
  var _super = _createSuper(RulesModule);
@@ -44,6 +41,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
44
41
  _defineProperty(_assertThisInitialized(_this), "defaultName", 'rules');
45
42
  _defineProperty(_assertThisInitialized(_this), "defaultVersion", '1.0.0');
46
43
  _defineProperty(_assertThisInitialized(_this), "store", void 0);
44
+ _defineProperty(_assertThisInitialized(_this), "window", void 0);
45
+ // WindowPlugin 实例
47
46
  _defineProperty(_assertThisInitialized(_this), "hooks", void 0);
48
47
  _this.hooks = {};
49
48
  return _this;
@@ -58,7 +57,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
58
57
  this.core = core;
59
58
  this.hooks = options === null || options === void 0 ? void 0 : options.hooks;
60
59
  this.store = options === null || options === void 0 ? void 0 : options.store;
61
- case 3:
60
+ this.window = core.getPlugin('window');
61
+ case 4:
62
62
  case "end":
63
63
  return _context.stop();
64
64
  }
@@ -95,6 +95,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
95
95
  value: function getRulesList() {
96
96
  return this.store.rulesList;
97
97
  }
98
+ }, {
99
+ key: "getWalletPassEvaluator",
100
+ value: function getWalletPassEvaluator() {
101
+ var _this$window$getWalle, _this$window;
102
+ return (_this$window$getWalle = (_this$window = this.window).getWalletPassEvaluator) === null || _this$window$getWalle === void 0 ? void 0 : _this$window$getWalle.call(_this$window);
103
+ }
98
104
 
99
105
  // 商品不需要holder,则不需要判断,直接返回true,商品需要holder但是还没填写,那么暂时不使用带有holder的券,直到填写才去匹配
100
106
  }, {
@@ -123,6 +129,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
123
129
  var oldDiscountList = _ref.oldDiscountList,
124
130
  newDiscountList = _ref.newDiscountList,
125
131
  productList = _ref.productList,
132
+ orderTotalAmount = _ref.orderTotalAmount,
126
133
  holders = _ref.holders,
127
134
  isFormSubject = _ref.isFormSubject;
128
135
  // 首先检查是否有新的优惠券可应用
@@ -155,6 +162,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
155
162
  var result = this.calcDiscount({
156
163
  discountList: mergedDiscountList,
157
164
  productList: _toConsumableArray(productList),
165
+ orderTotalAmount: orderTotalAmount,
158
166
  holders: holders,
159
167
  isFormSubject: isFormSubject
160
168
  }, {
@@ -200,7 +208,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
200
208
  var discountList = _ref2.discountList,
201
209
  productList = _ref2.productList,
202
210
  holders = _ref2.holders,
203
- isFormSubject = _ref2.isFormSubject;
211
+ isFormSubject = _ref2.isFormSubject,
212
+ orderTotalAmount = _ref2.orderTotalAmount;
204
213
  // 识别出来是不是在编辑的界面里又新增了商品
205
214
  // 这种情况下,如果有可用的优惠券,也会自动勾选上
206
215
  var isEditModeAddNewProduct = productList.find(function (n) {
@@ -447,6 +456,57 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
447
456
  return priceB.minus(priceA).toNumber();
448
457
  });
449
458
 
459
+ // 🔥 为每个折扣卡/商品券执行策略检查并附加config
460
+ var evaluator = this.getWalletPassEvaluator();
461
+ if (evaluator) {
462
+ addModeDiscount.forEach(function (discount) {
463
+ var discountType = discount.tag || discount.type;
464
+ // 只对 good_pass 和 discount_card 类型执行策略检查
465
+ if (['good_pass', 'discount_card', 'product_discount_card'].includes(discountType)) {
466
+ var _discount$limited_rel, _discount$limited_rel2;
467
+ // 转换 discount 为 Voucher 格式
468
+ var voucher = {
469
+ id: discount.id,
470
+ amount: Number(discount.par_value || 0),
471
+ balance: Number(discount.balance || 0),
472
+ type: discountType,
473
+ product_id: discount.product_id,
474
+ unified_available_status: 1,
475
+ available_product_type: (_discount$limited_rel = discount.limited_relation_product_data) === null || _discount$limited_rel === void 0 ? void 0 : _discount$limited_rel.type,
476
+ available_product_ids: (_discount$limited_rel2 = discount.limited_relation_product_data) === null || _discount$limited_rel2 === void 0 ? void 0 : _discount$limited_rel2.product_ids
477
+ };
478
+
479
+ // 转换 sortedFlattenedList 为 Product 格式
480
+ var productsForEvaluate = sortedFlattenedList.map(function (item) {
481
+ return {
482
+ product_id: item.id,
483
+ price: item.price || 0,
484
+ quantity: item.quantity || item.num || 1,
485
+ selling_price: item.price || 0
486
+ };
487
+ });
488
+
489
+ // 调用策略检查
490
+ var result = evaluator.checkVoucherAvailability({
491
+ orderTotalAmount: orderTotalAmount,
492
+ products: productsForEvaluate,
493
+ vouchers: [voucher]
494
+ });
495
+
496
+ // 将 config 附加到 discount 对象
497
+ if (result.isAvailable) {
498
+ discount.config = _objectSpread(_objectSpread({}, result.config), {}, {
499
+ isAvailable: true
500
+ });
501
+ } else {
502
+ discount.config = {
503
+ isAvailable: false
504
+ };
505
+ }
506
+ }
507
+ });
508
+ }
509
+
450
510
  /**
451
511
  // 对productList按价格降序排序(用于应用优惠券时优先选择高价商品) 价格相同时使用quantity 排序
452
512
  const sortedProductList = [...productList].sort((a, b) => {
@@ -467,6 +527,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
467
527
  // 标记已使用的优惠券
468
528
  var usedDiscounts = new Map();
469
529
 
530
+ // 🔥 统计每个 product_id(商品券商品id)已使用的数量,用于 maxUsagePerOrder 限制
531
+ var usedProductIdCounts = new Map();
532
+
470
533
  // 记录每个优惠券适用的商品ID
471
534
  var discountApplicability = new Map();
472
535
 
@@ -692,7 +755,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
692
755
  originProduct = flatItem.originProduct;
693
756
  }
694
757
  addModeDiscount.forEach(function (discount) {
695
- var _product5, _product6, _product7, _product8, _flatItem$bundleItem3, _flatItem$bundleItem4;
758
+ var _product5, _product6, _product7, _product8, _flatItem$bundleItem3, _flatItem$bundleItem4, _discount$config;
696
759
  var limitedData = discount === null || discount === void 0 ? void 0 : discount.limited_relation_product_data;
697
760
  // 拿到discount配置的holder信息 product信息 product.holder 加在 isLimitedProduct
698
761
  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;
@@ -703,7 +766,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
703
766
  var timeLimit = true;
704
767
  timeLimit = !!filterDiscountListByBookingTime([discount], (((_product5 = product) === null || _product5 === void 0 ? void 0 : _product5.startDate) || dayjs()).format('YYYY-MM-DD HH:mm:ss')).length;
705
768
  // 是符合折扣的商品
706
- var isLimitedProduct = (limitedData.type === 'product_all' || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
769
+ 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;
707
770
 
708
771
  // 编辑的商品 使用了优惠券不可用
709
772
  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) {
@@ -716,7 +779,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
716
779
  var isBundleAvailable = _this3.checkPackageSubItemUsageRules(discount, flatItem);
717
780
 
718
781
  // 判断优惠券是否适用于该商品
719
- if (isAvailableProduct && isLimitedProduct && isBundleAvailable && timeLimit) {
782
+ if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && (_discount$config = discount.config) !== null && _discount$config !== void 0 && _discount$config.isAvailable) {
720
783
  var _discountApplicabilit, _discount$metadata4, _discount$metadata5;
721
784
  // 记录此优惠券适用的商品
722
785
  (_discountApplicabilit = discountApplicability.get(discount.id)) === null || _discountApplicabilit === void 0 || _discountApplicabilit.push(product.id);
@@ -740,7 +803,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
740
803
  title: discount.format_title,
741
804
  original_amount: product.price || product.origin_total,
742
805
  pre_value: discount.par_value,
743
- product_id: originProduct.id
806
+ product_id: originProduct.id,
807
+ discount_product_id: discount.product_id
744
808
  },
745
809
  metadata: {
746
810
  num: num
@@ -800,6 +864,16 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
800
864
  // 找到适用于此商品的所有优惠券,仅考虑isSelected不为false的优惠券
801
865
  var applicableDiscounts = sortedDiscountList.filter(function (discount) {
802
866
  var _product$discount_lis3, _product$discount_lis4;
867
+ // 🔥 检查策略可用性(针对 good_pass 和折扣卡)
868
+ var discountType = discount.tag || discount.type;
869
+ if (['good_pass', 'discount_card', 'product_discount_card'].includes(discountType)) {
870
+ var _discount$config2;
871
+ // 如果策略检查后没有config,说明不可用
872
+ if (discount.config === undefined || !(discount !== null && discount !== void 0 && (_discount$config2 = discount.config) !== null && _discount$config2 !== void 0 && _discount$config2.isAvailable)) {
873
+ return false;
874
+ }
875
+ }
876
+
803
877
  // 如果商品价格为 0,其实不需要使用任何优惠券,直接 return true
804
878
  // 商品券时主商品价格为0不可用
805
879
  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;
@@ -812,6 +886,18 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
812
886
  // 如果优惠券已被使用,则跳过
813
887
  var targetUsedDiscounts = usedDiscounts.get(discount.id);
814
888
  if (targetUsedDiscounts && (discount.tag || discount.type) === 'good_pass') return false;
889
+
890
+ // 🔥 检查 maxUsagePerOrder 限制:同一 product_id 的商品券使用数量不能超过配置值
891
+ if ((discount.tag || discount.type) === 'good_pass') {
892
+ var _discount$config3;
893
+ var maxUsagePerOrder = (_discount$config3 = discount.config) === null || _discount$config3 === void 0 ? void 0 : _discount$config3.maxUsagePerOrder;
894
+ if (maxUsagePerOrder && maxUsagePerOrder > 0) {
895
+ var currentUsedCount = usedProductIdCounts.get(discount.product_id) || 0;
896
+ if (currentUsedCount >= maxUsagePerOrder) {
897
+ return false;
898
+ }
899
+ }
900
+ }
815
901
  var limitedData = discount.limited_relation_product_data;
816
902
 
817
903
  // 拿到discount配置的holder信息 product信息 product.holder 不可用return false
@@ -830,6 +916,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
830
916
 
831
917
  // 判断优惠券是否适用于该商品
832
918
  if (limitedData.type === 'product_all') {
919
+ if (limitedData.filter === 1 && limitedData.exclude_product_ids.includes(product.id)) {
920
+ return false;
921
+ }
833
922
  // 检查 package_sub_item_usage_rules
834
923
  if (!_this3.checkPackageSubItemUsageRules(discount, flatItem)) {
835
924
  return false;
@@ -996,7 +1085,13 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
996
1085
  var availableGoodPassCount = applicableDiscounts.filter(function (item) {
997
1086
  return (item.tag || item.type) === 'good_pass';
998
1087
  }).length;
999
- var splitCount = isNeedSplit ? Math.min(totalQuantity, availableGoodPassCount) : 1;
1088
+
1089
+ // 🔥 如果selectedDiscount有config配置,则使用config.maxUsagePerOrder限制使用次数
1090
+ var maxUsageLimit = availableGoodPassCount;
1091
+ if (selectedDiscount.config && selectedDiscount.config.maxUsagePerOrder) {
1092
+ maxUsageLimit = Math.min(availableGoodPassCount, selectedDiscount.config.maxUsagePerOrder);
1093
+ }
1094
+ var splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, maxUsageLimit) : 1;
1000
1095
  var arr = [];
1001
1096
 
1002
1097
  // 🔥 主商品和bundle子商品分别处理
@@ -1006,7 +1101,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1006
1101
  arr.push(_this3.hooks.setProduct(originProduct, {
1007
1102
  discount_list: [],
1008
1103
  quantity: totalQuantity - splitCount,
1009
- _id: product._id.split('___')[0]
1104
+ _id: product._id.split('___')[0],
1105
+ total: product.origin_total || product.total
1010
1106
  }));
1011
1107
  }
1012
1108
  for (var i = 0; i < splitCount; i++) {
@@ -1015,6 +1111,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1015
1111
  var _selectedDiscount = selectedDiscountCard || applicableDiscounts[i];
1016
1112
  // 标记优惠券为已使用
1017
1113
  usedDiscounts.set(_selectedDiscount.id, true);
1114
+ // 🔥 更新 product_id 使用计数
1115
+ if ((_selectedDiscount.tag || _selectedDiscount.type) === 'good_pass') {
1116
+ var currentCount = usedProductIdCounts.get(_selectedDiscount.product_id) || 0;
1117
+ usedProductIdCounts.set(_selectedDiscount.product_id, currentCount + 1);
1118
+ }
1018
1119
 
1019
1120
  // 记录实际应用了优惠券的商品信息
1020
1121
  var appliedProducts = appliedDiscountProducts.get(_selectedDiscount.id) || [];
@@ -1061,10 +1162,12 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1061
1162
  title: _selectedDiscount.format_title,
1062
1163
  original_amount: product.price,
1063
1164
  product_id: originProduct.id,
1064
- percent: _selectedDiscount.par_value
1165
+ percent: _selectedDiscount.par_value,
1166
+ discount_product_id: _selectedDiscount.product_id
1065
1167
  },
1066
1168
  // 前端使用的num数量,为了计算优惠金额
1067
1169
  _num: isGoodPass ? 1 : product.num,
1170
+ config: _selectedDiscount === null || _selectedDiscount === void 0 ? void 0 : _selectedDiscount.config,
1068
1171
  metadata: _objectSpread({
1069
1172
  num: 1
1070
1173
  }, productDiscountDifference !== undefined && {
@@ -1085,7 +1188,6 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1085
1188
  // 记录应用了优惠券的商品
1086
1189
  // 后续更新价格改为 getProductTotalPrice getProductOriginTotalPrice逻辑
1087
1190
  if (product.isClient) {
1088
- debugger;
1089
1191
  arr.push(_this3.hooks.setProduct(originProduct, {
1090
1192
  discount_list: [discountDetail],
1091
1193
  price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
@@ -1104,7 +1206,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1104
1206
  } else {
1105
1207
  arr.push(_this3.hooks.setProduct(originProduct, {
1106
1208
  discount_list: [discountDetail],
1107
- _id: product._id.split('___')[0] + "___" + _selectedDiscount.id + index,
1209
+ _id: product._id.split('___')[0] + '___' + _selectedDiscount.id + index,
1108
1210
  price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
1109
1211
  quantity: isNeedSplit ? 1 : product.quantity,
1110
1212
  total: total,
@@ -1127,11 +1229,20 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1127
1229
  var _selectedDiscount2$me;
1128
1230
  var _selectedDiscount2 = applicableDiscounts[_i];
1129
1231
  usedDiscounts.set(_selectedDiscount2.id, true);
1232
+ // 🔥 更新 product_id 使用计数
1233
+ if ((_selectedDiscount2.tag || _selectedDiscount2.type) === 'good_pass') {
1234
+ var _currentCount = usedProductIdCounts.get(_selectedDiscount2.product_id) || 0;
1235
+ usedProductIdCounts.set(_selectedDiscount2.product_id, _currentCount + 1);
1236
+ }
1130
1237
 
1131
1238
  // 🔥 生成唯一的 _id
1132
1239
  var uniqueId = "".concat(flatItem._id, "_split_").concat(_i);
1240
+
1241
+ // 计算折扣后的价格(使用 getDiscountAmount,内部已处理 maxDeductionAmount)
1242
+ var discountedPrice = getDiscountAmount(_selectedDiscount2, product.origin_total, product.origin_total);
1243
+ var bundleDiscountAmount = new Decimal(product.origin_total || 0).minus(discountedPrice).toNumber();
1133
1244
  var _discountDetail = {
1134
- amount: product.origin_total,
1245
+ amount: bundleDiscountAmount,
1135
1246
  type: 'good_pass',
1136
1247
  discount: {
1137
1248
  fixed_amount: product.origin_total,
@@ -1139,14 +1250,16 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1139
1250
  resource_id: _selectedDiscount2.id,
1140
1251
  title: _selectedDiscount2.format_title,
1141
1252
  original_amount: product.origin_total,
1142
- product_id: product.id
1253
+ product_id: product.id,
1254
+ discount_product_id: _selectedDiscount2.product_id
1143
1255
  },
1144
1256
  metadata: {
1145
1257
  // 🔥 使用拆分后的唯一 _id
1146
1258
  custom_product_bundle_map_id: uniqueId,
1147
1259
  num: 1
1148
1260
  },
1149
- _num: 1
1261
+ _num: 1,
1262
+ config: _selectedDiscount2 === null || _selectedDiscount2 === void 0 ? void 0 : _selectedDiscount2.config
1150
1263
  };
1151
1264
 
1152
1265
  // 记录实际应用的折扣
@@ -1158,9 +1271,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1158
1271
  _id: uniqueId,
1159
1272
  num: 1,
1160
1273
  quantity: 1,
1161
- price: 0,
1162
- // 商品券价格为0
1163
- total: 0,
1274
+ price: discountedPrice,
1275
+ // 折扣后的价格
1276
+ total: discountedPrice,
1164
1277
  discount_list: [_discountDetail],
1165
1278
  processed: true,
1166
1279
  _discountId: _selectedDiscount2.id
@@ -1183,6 +1296,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1183
1296
  // 折扣卡:不拆分数量,直接应用
1184
1297
  var _selectedDiscount3 = selectedDiscountCard || applicableDiscounts[0];
1185
1298
  usedDiscounts.set(_selectedDiscount3.id, true);
1299
+ // 🔥 更新 product_id 使用计数(虽然此处主要是折扣卡,但保持一致性)
1300
+ if ((_selectedDiscount3.tag || _selectedDiscount3.type) === 'good_pass') {
1301
+ var _currentCount2 = usedProductIdCounts.get(_selectedDiscount3.product_id) || 0;
1302
+ usedProductIdCounts.set(_selectedDiscount3.product_id, _currentCount2 + 1);
1303
+ }
1186
1304
  var _productOriginTotal = product.original_price || product.price || 0;
1187
1305
 
1188
1306
  // 🔥 检查是否是 order_level 固定金额折扣卡
@@ -1202,7 +1320,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1202
1320
  _targetProductTotal = getDiscountAmount(_selectedDiscount3, _productOriginTotal, _productOriginTotal);
1203
1321
  fixedAmountPerItem = new Decimal(_productOriginTotal).minus(_targetProductTotal).toNumber();
1204
1322
  }
1205
- debugger;
1323
+
1206
1324
  // 🔥 使用当前的 _id 作为唯一标识
1207
1325
  var _uniqueId = flatItem._id;
1208
1326
  var _discountDetail2 = {
@@ -1216,7 +1334,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1216
1334
  title: _selectedDiscount3.format_title,
1217
1335
  original_amount: product.original_price,
1218
1336
  product_id: product.id,
1219
- percent: _selectedDiscount3.par_value
1337
+ percent: _selectedDiscount3.par_value,
1338
+ discount_product_id: _selectedDiscount3.product_id
1220
1339
  },
1221
1340
  metadata: _objectSpread({
1222
1341
  // 🔥 使用唯一的 _id
@@ -1225,6 +1344,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1225
1344
  }, _productDiscountDifference !== undefined && {
1226
1345
  product_discount_difference: _productDiscountDifference
1227
1346
  }),
1347
+ config: _selectedDiscount3 === null || _selectedDiscount3 === void 0 ? void 0 : _selectedDiscount3.config,
1228
1348
  _num: (product.num || 1) * ((flatItem === null || flatItem === void 0 || (_flatItem$parentProdu8 = flatItem.parentProduct) === null || _flatItem$parentProdu8 === void 0 ? void 0 : _flatItem$parentProdu8.num) || 1)
1229
1349
  };
1230
1350
 
@@ -26,6 +26,7 @@ export interface RulesModuleAPI {
26
26
  form_record_id: number;
27
27
  }[];
28
28
  isFormSubject: boolean;
29
+ orderTotalAmount: number;
29
30
  }) => DiscountResult;
30
31
  }
31
32
  type ProductDetail = {
@@ -25,15 +25,6 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
25
25
  setOtherProductsIds(ids: number[]): void;
26
26
  getOtherProductsIds(): number[];
27
27
  storeChange(): void;
28
- /**
29
- * 传入一个时间, 判断改时间是否在schedule 内
30
- * @param param0 { date: string, schedule: any } date: 日期, schedule: schedule
31
- * @returns
32
- */
33
- isInScheduleByDate({ date, schedule, }: {
34
- date: string;
35
- schedule: any;
36
- }): boolean | undefined;
37
28
  /**
38
29
  * 传入一个时间, 判断改时间是否在schedule 内
39
30
  * @param param0 { date: string, schedule: any } date: 日期, schedule: schedule
@@ -248,28 +248,12 @@ export var ScheduleModule = /*#__PURE__*/function (_BaseModule) {
248
248
  * @param param0 { date: string, schedule: any } date: 日期, schedule: schedule
249
249
  * @returns
250
250
  */
251
- }, {
251
+ }], [{
252
252
  key: "isInScheduleByDate",
253
253
  value: function isInScheduleByDate(_ref2) {
254
+ var _schedule$repeat_rule, _schedule$repeat_rule2;
254
255
  var date = _ref2.date,
255
256
  schedule = _ref2.schedule;
256
- return ScheduleModule.isInScheduleByDate({
257
- date: date,
258
- schedule: schedule
259
- });
260
- }
261
-
262
- /**
263
- * 传入一个时间, 判断改时间是否在schedule 内
264
- * @param param0 { date: string, schedule: any } date: 日期, schedule: schedule
265
- * @returns
266
- */
267
- }], [{
268
- key: "isInScheduleByDate",
269
- value: function isInScheduleByDate(_ref3) {
270
- var _schedule$repeat_rule, _schedule$repeat_rule2;
271
- var date = _ref3.date,
272
- schedule = _ref3.schedule;
273
257
  if (schedule.start_time && schedule.end_time) {
274
258
  var isBeforeStartTime = dayjs(date).isBefore(dayjs(schedule.start_time));
275
259
  var isAfterEndTime = dayjs(date).isAfter(dayjs(schedule.end_time));
@@ -5,6 +5,8 @@ export interface ISummaryState {
5
5
  subtotal: string | number;
6
6
  /** 最终总价 */
7
7
  total: string | number;
8
+ /** 最终原始价格 不包含折扣卡商品券折扣 */
9
+ originTotal: string | number;
8
10
  /** 税率标题 */
9
11
  taxTitle?: string;
10
12
  /** 商品总费率 */
@@ -13,6 +13,12 @@ export declare const getBundleDiscountList: (bundle: any[]) => any[];
13
13
  * @returns 商品总价字符串,保留2位小数
14
14
  */
15
15
  export declare const calculateSubtotal: (items: CartItem[]) => string;
16
+ /**
17
+ * 计算商品小计(不含其他费用 不包含折扣卡商品券抵扣金额)
18
+ * @param items - 购物车商品数组
19
+ * @returns 商品总价字符串,保留2位小数
20
+ */
21
+ export declare const calculateOriginSubtotal: (items: CartItem[]) => string;
16
22
  /**
17
23
  * @title: 单个商品的税费
18
24
  * @description:
@@ -7,16 +7,21 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
7
7
  import Decimal from 'decimal.js';
8
8
  export var calculatePriceDetails = function calculatePriceDetails(shopInfo, items) {
9
9
  var subtotal = new Decimal(calculateSubtotal(items));
10
+ var subOriginTotal = new Decimal(calculateOriginSubtotal(items));
10
11
  var totalTaxFee = new Decimal(calculateTaxFee(shopInfo, items));
11
12
 
12
13
  // 计算总价
13
14
  var total = shopInfo !== null && shopInfo !== void 0 && shopInfo.is_price_include_tax ? subtotal : subtotal.plus(totalTaxFee);
14
15
 
16
+ // 计算总价 不包含折扣卡商品券折扣信息价格
17
+ var originTotal = shopInfo !== null && shopInfo !== void 0 && shopInfo.is_price_include_tax ? subOriginTotal : subOriginTotal.plus(totalTaxFee);
18
+
15
19
  // 计算定金
16
20
  var deposit = calculateDeposit(items);
17
21
  return {
18
22
  subtotal: subtotal.toFixed(2),
19
23
  total: total.toFixed(2),
24
+ originTotal: originTotal.toFixed(2),
20
25
  taxTitle: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.tax_title,
21
26
  totalTaxFee: totalTaxFee.toFixed(2),
22
27
  isPriceIncludeTax: shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.is_price_include_tax,
@@ -69,6 +74,22 @@ export var calculateSubtotal = function calculateSubtotal(items) {
69
74
  return subtotal.toFixed(2);
70
75
  };
71
76
 
77
+ /**
78
+ * 计算商品小计(不含其他费用 不包含折扣卡商品券抵扣金额)
79
+ * @param items - 购物车商品数组
80
+ * @returns 商品总价字符串,保留2位小数
81
+ */
82
+ export var calculateOriginSubtotal = function calculateOriginSubtotal(items) {
83
+ if (!(items !== null && items !== void 0 && items.length)) {
84
+ return '0.00';
85
+ }
86
+ var subtotal = items.reduce(function (sum, item) {
87
+ var cartItemTotalPrice = new Decimal(item.summaryOriginTotal || 0);
88
+ return sum.plus(cartItemTotalPrice);
89
+ }, new Decimal(0));
90
+ return subtotal.toFixed(2);
91
+ };
92
+
72
93
  /**
73
94
  * @title: 单个商品的税费
74
95
  * @description:
@@ -1,3 +1,4 @@
1
+ import { WalletPassEvaluator } from '../model';
1
2
  import { Plugin } from '../types';
2
3
  /**
3
4
  * WindowPlugin 接口定义
@@ -14,6 +15,7 @@ export interface WindowPlugin extends Plugin {
14
15
  document: Partial<Document>;
15
16
  history: History;
16
17
  interaction?: any;
18
+ getWalletPassEvaluator?: () => WalletPassEvaluator;
17
19
  }
18
20
  /**
19
21
  * 简单的 Storage 接口实现
@@ -144,6 +144,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
144
144
  getSummary(): Promise<{
145
145
  subtotal: string | number;
146
146
  total: string | number;
147
+ originTotal: string | number;
147
148
  taxTitle?: string | undefined;
148
149
  totalTaxFee?: string | number | undefined;
149
150
  isPriceIncludeTax?: 0 | 1 | undefined;
@@ -405,6 +405,7 @@ export var CheckoutImpl = /*#__PURE__*/function (_BaseModule) {
405
405
  product_id: item.product_id,
406
406
  product_variant_id: item.product_variant_id,
407
407
  quantity: item.num,
408
+ is_price_include_tax: item.is_price_include_tax,
408
409
  // 商品是否含税:1;0
409
410
  is_charge_tax: (_item$is_charge_tax = item.is_charge_tax) !== null && _item$is_charge_tax !== void 0 ? _item$is_charge_tax : 0,
410
411
  // 若商品不含税,计算得到的税费,单位(元)
@@ -429,6 +430,7 @@ export var CheckoutImpl = /*#__PURE__*/function (_BaseModule) {
429
430
  },
430
431
  product_bundle: item.product_bundle.map(function (bundle) {
431
432
  return {
433
+ is_price_include_tax: item.is_price_include_tax,
432
434
  bundle_id: bundle.bundle_id,
433
435
  bundle_product_id: bundle.bundle_product_id,
434
436
  bundle_variant_id: bundle.bundle_variant_id,
@@ -1800,7 +1802,7 @@ export var CheckoutImpl = /*#__PURE__*/function (_BaseModule) {
1800
1802
  case 6:
1801
1803
  paymentItems = _context18.sent;
1802
1804
  if (!(!voucherPaymentItems || (voucherPaymentItems === null || voucherPaymentItems === void 0 ? void 0 : voucherPaymentItems.length) === 0)) {
1803
- _context18.next = 13;
1805
+ _context18.next = 12;
1804
1806
  break;
1805
1807
  }
1806
1808
  savedVoucherPaymentItems = (paymentItems === null || paymentItems === void 0 ? void 0 : paymentItems.filter(function (item) {
@@ -1811,23 +1813,22 @@ export var CheckoutImpl = /*#__PURE__*/function (_BaseModule) {
1811
1813
  savedVoucherPaymentItems: savedVoucherPaymentItems
1812
1814
  });
1813
1815
  if (!((savedVoucherPaymentItems === null || savedVoucherPaymentItems === void 0 ? void 0 : savedVoucherPaymentItems.length) === 0)) {
1814
- _context18.next = 13;
1816
+ _context18.next = 12;
1815
1817
  break;
1816
1818
  }
1817
- this.updateStateAmountToRemaining(false);
1818
1819
  return _context18.abrupt("return");
1819
- case 13:
1820
+ case 12:
1820
1821
  allPaymentItemsSynced = paymentItems.every(function (item) {
1821
1822
  return item.isSynced;
1822
1823
  });
1823
- _context18.next = 16;
1824
+ _context18.next = 15;
1824
1825
  return this.calculateRemainingAmountAsync();
1825
- case 16:
1826
+ case 15:
1826
1827
  remainingAmount = _context18.sent;
1827
1828
  remainingValue = new Decimal(remainingAmount);
1828
1829
  isOrderSynced = this.store.isOrderSynced;
1829
1830
  if (!(remainingValue.lte(0) && isOrderSynced && voucherPaymentItems.length === 0 && allPaymentItemsSynced)) {
1830
- _context18.next = 22;
1831
+ _context18.next = 21;
1831
1832
  break;
1832
1833
  }
1833
1834
  this.logInfo('订单已同步且支付完成,跳过清空代金券操作避免重复同步:', {
@@ -1839,7 +1840,7 @@ export var CheckoutImpl = /*#__PURE__*/function (_BaseModule) {
1839
1840
  reason: 'Order synced and payment completed, skip clear vouchers to avoid duplicate sync'
1840
1841
  });
1841
1842
  return _context18.abrupt("return");
1842
- case 22:
1843
+ case 21:
1843
1844
  this.logInfo('开始批量更新代金券支付项:', {
1844
1845
  voucherPaymentItems: voucherPaymentItems
1845
1846
  });
@@ -1861,18 +1862,18 @@ export var CheckoutImpl = /*#__PURE__*/function (_BaseModule) {
1861
1862
  metadata: metadata
1862
1863
  });
1863
1864
  }); // 调用 Payment 模块的批量更新方法
1864
- _context18.next = 27;
1865
+ _context18.next = 26;
1865
1866
  return this.payment.updateVoucherPaymentItemsAsync(this.store.currentOrder.uuid, voucherPaymentItemsWithType);
1866
- case 27:
1867
+ case 26:
1867
1868
  // 🚀 清除计算缓存,确保获取最新数据
1868
1869
  this.clearCalculationCache();
1869
1870
 
1870
1871
  // 重新从Payment模块获取最新的订单数据,确保支付项同步
1871
1872
  currentOrderId = this.store.currentOrder.order_id; // 保存当前的订单ID
1872
1873
  isCurrentOrderReal = currentOrderId && !isVirtualOrderId(currentOrderId);
1873
- _context18.next = 32;
1874
+ _context18.next = 31;
1874
1875
  return this.payment.getPaymentOrderByUuidAsync(this.store.currentOrder.uuid);
1875
- case 32:
1876
+ case 31:
1876
1877
  updatedOrder = _context18.sent;
1877
1878
  if (updatedOrder) {
1878
1879
  // 如果当前订单ID是真实ID,但获取到的订单ID是虚拟ID,需要保护真实ID
@@ -1887,10 +1888,10 @@ export var CheckoutImpl = /*#__PURE__*/function (_BaseModule) {
1887
1888
  }
1888
1889
 
1889
1890
  // 更新 stateAmount 为剩余未支付金额
1890
- _context18.next = 36;
1891
+ _context18.next = 35;
1891
1892
  return this.updateStateAmountToRemaining(false);
1892
- case 36:
1893
- _context18.next = 38;
1893
+ case 35:
1894
+ _context18.next = 37;
1894
1895
  return this.core.effects.emit("".concat(this.name, ":onPaymentStarted"), {
1895
1896
  orderUuid: this.store.currentOrder.uuid,
1896
1897
  paymentMethodCode: 'VOUCHER_BATCH',
@@ -1899,23 +1900,23 @@ export var CheckoutImpl = /*#__PURE__*/function (_BaseModule) {
1899
1900
  }, 0).toFixed(2),
1900
1901
  timestamp: Date.now()
1901
1902
  });
1902
- case 38:
1903
+ case 37:
1903
1904
  this.logInfo('代金券支付项批量更新成功');
1904
- _context18.next = 47;
1905
+ _context18.next = 46;
1905
1906
  break;
1906
- case 41:
1907
- _context18.prev = 41;
1907
+ case 40:
1908
+ _context18.prev = 40;
1908
1909
  _context18.t0 = _context18["catch"](0);
1909
1910
  this.logError('[Checkout] 批量更新代金券支付项失败:', _context18.t0);
1910
- _context18.next = 46;
1911
+ _context18.next = 45;
1911
1912
  return this.handleError(_context18.t0, CheckoutErrorType.PaymentFailed);
1912
- case 46:
1913
+ case 45:
1913
1914
  throw _context18.t0;
1914
- case 47:
1915
+ case 46:
1915
1916
  case "end":
1916
1917
  return _context18.stop();
1917
1918
  }
1918
- }, _callee18, this, [[0, 41]]);
1919
+ }, _callee18, this, [[0, 40]]);
1919
1920
  }));
1920
1921
  function updateVoucherPaymentItemsAsync(_x18) {
1921
1922
  return _updateVoucherPaymentItemsAsync.apply(this, arguments);