@pisell/pisellos 2.1.151 → 2.1.152

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 (201) hide show
  1. package/dist/apis/picoding.d.ts +0 -0
  2. package/dist/apis/picoding.js +1 -0
  3. package/dist/index.d.ts +0 -1
  4. package/dist/index.js +0 -1
  5. package/dist/model/strategy/adapter/promotion/evaluator.js +26 -99
  6. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +0 -2
  7. package/dist/model/strategy/adapter/walletPass/evaluator.js +8 -61
  8. package/dist/model/strategy/adapter/walletPass/locales.js +3 -12
  9. package/dist/model/strategy/engine.d.ts +5 -18
  10. package/dist/model/strategy/engine.js +45 -145
  11. package/dist/model/strategy/type.d.ts +0 -17
  12. package/dist/model/strategy/type.js +0 -4
  13. package/dist/modules/Cart/types.d.ts +0 -2
  14. package/dist/modules/Cart/utils/cartProduct.js +25 -56
  15. package/dist/modules/Discount/index.d.ts +9 -3
  16. package/dist/modules/Discount/index.js +103 -11
  17. package/dist/modules/Discount/types.d.ts +8 -19
  18. package/dist/modules/OpenData/index.d.ts +24 -0
  19. package/dist/modules/OpenData/index.js +173 -0
  20. package/dist/modules/OpenData/types.d.ts +73 -0
  21. package/dist/modules/OpenData/types.js +1 -0
  22. package/dist/modules/OpenData/utils.d.ts +2 -0
  23. package/dist/modules/OpenData/utils.js +75 -0
  24. package/dist/modules/Order/index.d.ts +66 -1
  25. package/dist/modules/Order/index.js +906 -30
  26. package/dist/modules/Order/types.d.ts +174 -12
  27. package/dist/modules/Order/types.js +2 -0
  28. package/dist/modules/Order/utils.d.ts +118 -0
  29. package/dist/modules/Order/utils.js +586 -2
  30. package/dist/modules/Payment/index.d.ts +1 -2
  31. package/dist/modules/Payment/index.js +7 -10
  32. package/dist/modules/Payment/utils.js +0 -3
  33. package/dist/modules/Payment/walletpass.d.ts +0 -23
  34. package/dist/modules/Payment/walletpass.js +95 -191
  35. package/dist/modules/Product/utils.js +2 -2
  36. package/dist/modules/ProductList/index.d.ts +1 -1
  37. package/dist/modules/ProductList/index.js +4 -3
  38. package/dist/modules/Quotation/index.d.ts +48 -0
  39. package/dist/modules/Quotation/index.js +248 -0
  40. package/dist/modules/Quotation/types.d.ts +42 -0
  41. package/dist/modules/Quotation/types.js +1 -0
  42. package/dist/modules/Rules/index.d.ts +5 -9
  43. package/dist/modules/Rules/index.js +168 -677
  44. package/dist/modules/Rules/types.d.ts +0 -2
  45. package/dist/modules/SalesSummary/index.d.ts +63 -0
  46. package/dist/modules/SalesSummary/index.js +174 -0
  47. package/dist/modules/SalesSummary/types.d.ts +60 -0
  48. package/dist/modules/SalesSummary/types.js +1 -0
  49. package/dist/modules/SalesSummary/utils.d.ts +30 -0
  50. package/dist/modules/SalesSummary/utils.js +480 -0
  51. package/dist/modules/ScanOrderLogger/index.d.ts +23 -0
  52. package/dist/modules/ScanOrderLogger/index.js +174 -0
  53. package/dist/modules/ScanOrderLogger/providers/feishu.d.ts +2 -0
  54. package/dist/modules/ScanOrderLogger/providers/feishu.js +221 -0
  55. package/dist/modules/ScanOrderLogger/providers/grafana.d.ts +2 -0
  56. package/dist/modules/ScanOrderLogger/providers/grafana.js +50 -0
  57. package/dist/modules/ScanOrderLogger/types.d.ts +53 -0
  58. package/dist/modules/ScanOrderLogger/types.js +1 -0
  59. package/dist/modules/Schedule/getDateIsInSchedule.js +11 -18
  60. package/dist/modules/Schedule/utils.d.ts +1 -1
  61. package/dist/modules/Summary/types.d.ts +0 -2
  62. package/dist/modules/Summary/utils.d.ts +3 -9
  63. package/dist/modules/Summary/utils.js +41 -52
  64. package/dist/modules/index.d.ts +4 -0
  65. package/dist/modules/index.js +5 -1
  66. package/dist/plugins/window.d.ts +0 -2
  67. package/dist/solution/BookingByStep/index.d.ts +1 -2
  68. package/dist/solution/BookingByStep/index.js +46 -43
  69. package/dist/solution/BookingByStep/types.d.ts +3 -1
  70. package/dist/solution/BookingByStep/types.js +5 -1
  71. package/dist/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  72. package/dist/solution/BookingByStep/utils/timeslots.js +19 -12
  73. package/dist/solution/Checkout/index.js +0 -2
  74. package/dist/solution/ScanOrder/index.d.ts +152 -0
  75. package/dist/solution/ScanOrder/index.js +3132 -0
  76. package/dist/solution/ScanOrder/types.d.ts +287 -0
  77. package/dist/solution/ScanOrder/types.js +35 -0
  78. package/dist/solution/ScanOrder/utils.d.ts +167 -0
  79. package/dist/solution/ScanOrder/utils.js +764 -0
  80. package/dist/solution/ShopDiscount/index.d.ts +3 -2
  81. package/dist/solution/ShopDiscount/index.js +60 -59
  82. package/dist/solution/ShopDiscount/types.d.ts +1 -1
  83. package/dist/solution/ShopDiscount/types.js +1 -2
  84. package/dist/solution/ShopDiscount/utils.js +12 -26
  85. package/dist/solution/VenueBooking/index.d.ts +200 -0
  86. package/dist/solution/VenueBooking/index.js +3459 -0
  87. package/dist/solution/VenueBooking/sales-section-4-annotated.json +343 -0
  88. package/dist/solution/VenueBooking/types.d.ts +154 -0
  89. package/dist/solution/VenueBooking/types.js +21 -0
  90. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +11 -0
  91. package/dist/solution/VenueBooking/utils/dateSummary.js +104 -0
  92. package/dist/solution/VenueBooking/utils/resource.d.ts +14 -0
  93. package/dist/solution/VenueBooking/utils/resource.js +131 -0
  94. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +38 -0
  95. package/dist/solution/VenueBooking/utils/slotMerge.js +239 -0
  96. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +32 -0
  97. package/dist/solution/VenueBooking/utils/timeSlot.js +453 -0
  98. package/dist/solution/VenueBooking/utils.d.ts +1 -0
  99. package/dist/solution/VenueBooking/utils.js +1 -0
  100. package/dist/solution/index.d.ts +2 -0
  101. package/dist/solution/index.js +3 -1
  102. package/lib/apis/picoding.d.ts +0 -0
  103. package/lib/apis/picoding.js +0 -0
  104. package/lib/index.d.ts +0 -1
  105. package/lib/index.js +1 -3
  106. package/lib/model/strategy/adapter/promotion/evaluator.js +8 -57
  107. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  108. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +0 -2
  109. package/lib/model/strategy/adapter/walletPass/evaluator.js +3 -34
  110. package/lib/model/strategy/adapter/walletPass/locales.js +3 -12
  111. package/lib/model/strategy/engine.d.ts +5 -18
  112. package/lib/model/strategy/engine.js +21 -85
  113. package/lib/model/strategy/type.d.ts +0 -17
  114. package/lib/modules/Cart/types.d.ts +0 -2
  115. package/lib/modules/Cart/utils/cartProduct.js +12 -39
  116. package/lib/modules/Discount/index.d.ts +9 -3
  117. package/lib/modules/Discount/index.js +65 -4
  118. package/lib/modules/Discount/types.d.ts +8 -19
  119. package/lib/modules/OpenData/index.d.ts +24 -0
  120. package/lib/modules/OpenData/index.js +119 -0
  121. package/lib/modules/OpenData/types.d.ts +73 -0
  122. package/lib/modules/OpenData/types.js +17 -0
  123. package/lib/modules/OpenData/utils.d.ts +2 -0
  124. package/lib/modules/OpenData/utils.js +111 -0
  125. package/lib/modules/Order/index.d.ts +66 -1
  126. package/lib/modules/Order/index.js +515 -1
  127. package/lib/modules/Order/types.d.ts +174 -12
  128. package/lib/modules/Order/utils.d.ts +118 -0
  129. package/lib/modules/Order/utils.js +483 -2
  130. package/lib/modules/Payment/index.d.ts +1 -2
  131. package/lib/modules/Payment/index.js +0 -1
  132. package/lib/modules/Payment/utils.js +0 -3
  133. package/lib/modules/Payment/walletpass.d.ts +0 -23
  134. package/lib/modules/Payment/walletpass.js +17 -94
  135. package/lib/modules/Product/utils.js +2 -2
  136. package/lib/modules/ProductList/index.d.ts +1 -1
  137. package/lib/modules/ProductList/index.js +5 -3
  138. package/lib/modules/Quotation/index.d.ts +48 -0
  139. package/lib/modules/Quotation/index.js +152 -0
  140. package/lib/modules/Quotation/types.d.ts +42 -0
  141. package/lib/modules/Quotation/types.js +17 -0
  142. package/lib/modules/Rules/index.d.ts +5 -9
  143. package/lib/modules/Rules/index.js +288 -780
  144. package/lib/modules/Rules/types.d.ts +0 -2
  145. package/lib/modules/SalesSummary/index.d.ts +63 -0
  146. package/lib/modules/SalesSummary/index.js +105 -0
  147. package/lib/modules/SalesSummary/types.d.ts +60 -0
  148. package/lib/modules/SalesSummary/types.js +17 -0
  149. package/lib/modules/SalesSummary/utils.d.ts +30 -0
  150. package/lib/modules/SalesSummary/utils.js +420 -0
  151. package/lib/modules/ScanOrderLogger/index.d.ts +23 -0
  152. package/lib/modules/ScanOrderLogger/index.js +147 -0
  153. package/lib/modules/ScanOrderLogger/providers/feishu.d.ts +2 -0
  154. package/lib/modules/ScanOrderLogger/providers/feishu.js +157 -0
  155. package/lib/modules/ScanOrderLogger/providers/grafana.d.ts +2 -0
  156. package/lib/modules/ScanOrderLogger/providers/grafana.js +52 -0
  157. package/lib/modules/ScanOrderLogger/types.d.ts +53 -0
  158. package/lib/modules/ScanOrderLogger/types.js +17 -0
  159. package/lib/modules/Schedule/getDateIsInSchedule.js +9 -11
  160. package/lib/modules/Schedule/utils.d.ts +1 -1
  161. package/lib/modules/Summary/types.d.ts +0 -2
  162. package/lib/modules/Summary/utils.d.ts +3 -9
  163. package/lib/modules/Summary/utils.js +22 -31
  164. package/lib/modules/index.d.ts +4 -0
  165. package/lib/modules/index.js +9 -1
  166. package/lib/plugins/window.d.ts +0 -2
  167. package/lib/solution/BookingByStep/index.d.ts +1 -2
  168. package/lib/solution/BookingByStep/index.js +6 -4
  169. package/lib/solution/BookingByStep/types.d.ts +3 -1
  170. package/lib/solution/BookingByStep/types.js +10 -0
  171. package/lib/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  172. package/lib/solution/BookingByStep/utils/timeslots.js +19 -11
  173. package/lib/solution/Checkout/index.js +0 -2
  174. package/lib/solution/ScanOrder/index.d.ts +152 -0
  175. package/lib/solution/ScanOrder/index.js +1901 -0
  176. package/lib/solution/ScanOrder/types.d.ts +287 -0
  177. package/lib/solution/ScanOrder/types.js +36 -0
  178. package/lib/solution/ScanOrder/utils.d.ts +167 -0
  179. package/lib/solution/ScanOrder/utils.js +635 -0
  180. package/lib/solution/ShopDiscount/index.d.ts +3 -2
  181. package/lib/solution/ShopDiscount/index.js +19 -25
  182. package/lib/solution/ShopDiscount/types.d.ts +1 -1
  183. package/lib/solution/ShopDiscount/utils.js +6 -10
  184. package/lib/solution/VenueBooking/index.d.ts +200 -0
  185. package/lib/solution/VenueBooking/index.js +1926 -0
  186. package/lib/solution/VenueBooking/sales-section-4-annotated.json +343 -0
  187. package/lib/solution/VenueBooking/types.d.ts +154 -0
  188. package/lib/solution/VenueBooking/types.js +44 -0
  189. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +11 -0
  190. package/lib/solution/VenueBooking/utils/dateSummary.js +110 -0
  191. package/lib/solution/VenueBooking/utils/resource.d.ts +14 -0
  192. package/lib/solution/VenueBooking/utils/resource.js +92 -0
  193. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +38 -0
  194. package/lib/solution/VenueBooking/utils/slotMerge.js +237 -0
  195. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +32 -0
  196. package/lib/solution/VenueBooking/utils/timeSlot.js +339 -0
  197. package/lib/solution/VenueBooking/utils.d.ts +1 -0
  198. package/lib/solution/VenueBooking/utils.js +69 -0
  199. package/lib/solution/index.d.ts +2 -0
  200. package/lib/solution/index.js +5 -1
  201. package/package.json +1 -1
@@ -8,12 +8,10 @@ export declare class WalletPassEvaluator {
8
8
  private engine;
9
9
  private strategyConfigs;
10
10
  private locale;
11
- private otherParams;
12
11
  constructor();
13
12
  setStrategyConfigs(strategyConfigs: StrategyConfig[]): void;
14
13
  getStrategyConfigs(): StrategyConfig[];
15
14
  setLocale(locale: string): void;
16
- setOtherParams(otherParams: any): void;
17
15
  getText(key: string): string;
18
16
  /**
19
17
  * 搜索券的格式
@@ -45,27 +45,10 @@ var defaultStrategyMetadataCustom = {
45
45
  maxPassesPerItem: 0,
46
46
  deductOptionPrice: false
47
47
  };
48
- var FIELD_REASON_CODE_MAP = {
49
- orderTotalAmount: "order_total_amount_not_enough",
50
- applicableProductTotalAmount: "applicable_product_total_amount_not_enough",
51
- applicableProductCount: "applicable_product_count_not_enough"
52
- };
53
- var AMOUNT_FIELDS = /* @__PURE__ */ new Set([
54
- "orderTotalAmount",
55
- "applicableProductTotalAmount"
56
- ]);
57
- function formatReason(template, value, currency = "") {
58
- if (!template)
59
- return template;
60
- const v = value === void 0 || value === null ? "" : String(value);
61
- const c = currency === void 0 || currency === null ? "" : String(currency);
62
- return template.replace(/\$\{value\}/g, () => v).replace(/\{value\}/g, () => v).replace(/\{currency\}/g, () => c);
63
- }
64
48
  var WalletPassEvaluator = class {
65
49
  constructor() {
66
50
  this.strategyConfigs = [];
67
51
  this.locale = "en";
68
- this.otherParams = {};
69
52
  this.engine = new import__.StrategyEngine({
70
53
  debug: false,
71
54
  enableTrace: false
@@ -81,9 +64,6 @@ var WalletPassEvaluator = class {
81
64
  setLocale(locale) {
82
65
  this.locale = locale;
83
66
  }
84
- setOtherParams(otherParams) {
85
- this.otherParams = otherParams;
86
- }
87
67
  getText(key) {
88
68
  var _a, _b;
89
69
  return (_b = (_a = import_locales.locales) == null ? void 0 : _a[this.locale]) == null ? void 0 : _b[key];
@@ -121,7 +101,7 @@ var WalletPassEvaluator = class {
121
101
  * 评估可用的 vouchers
122
102
  */
123
103
  evaluate(input) {
124
- var _a, _b, _c, _d, _e, _f, _g;
104
+ var _a, _b;
125
105
  const { orderTotalAmount, products, vouchers, strategyConfigs } = input;
126
106
  const productIds = products.map((p) => p.product_id);
127
107
  const results = [];
@@ -196,13 +176,7 @@ var WalletPassEvaluator = class {
196
176
  });
197
177
  } else {
198
178
  let reasonCode = "not_meet_the_required_conditions";
199
- let thresholdValue = void 0;
200
- const failedField = (_c = evaluationResult.matched) == null ? void 0 : _c.failedField;
201
- const failedRule = (_e = (_d = evaluationResult.matched) == null ? void 0 : _d.failedRules) == null ? void 0 : _e[0];
202
- if (failedField && FIELD_REASON_CODE_MAP[failedField]) {
203
- reasonCode = FIELD_REASON_CODE_MAP[failedField];
204
- thresholdValue = failedRule == null ? void 0 : failedRule.value;
205
- } else if (evaluationResult.code) {
179
+ if (evaluationResult.code) {
206
180
  const codeMapping = {
207
181
  INSUFFICIENT_AMOUNT: "not_meet_the_required_conditions",
208
182
  USAGE_LIMIT_EXCEEDED: "usage_limit_reached",
@@ -212,10 +186,6 @@ var WalletPassEvaluator = class {
212
186
  };
213
187
  reasonCode = codeMapping[evaluationResult.code] || "not_meet_the_required_conditions";
214
188
  }
215
- const rawText = this.getText(reasonCode);
216
- const currency = failedField && AMOUNT_FIELDS.has(failedField) ? ((_g = (_f = this.otherParams) == null ? void 0 : _f.getData) == null ? void 0 : _g.call(_f, "shop_symbol")) || "" : "";
217
- console.log(currency, "currency12345");
218
- const reason = thresholdValue !== void 0 ? formatReason(rawText, thresholdValue, currency) : rawText;
219
189
  results.push({
220
190
  voucher,
221
191
  isApplicable: false,
@@ -223,7 +193,7 @@ var WalletPassEvaluator = class {
223
193
  maxDeduction: 0,
224
194
  deductTaxAndFee: false,
225
195
  applicableProductIds: [],
226
- reason,
196
+ reason: this.getText(reasonCode),
227
197
  reasonCode,
228
198
  strategyResult: evaluationResult
229
199
  });
@@ -416,7 +386,6 @@ var WalletPassEvaluator = class {
416
386
  * 计算适用商品的总金额和数量
417
387
  */
418
388
  calculateApplicableProducts(products, applicableProductIds, deductTaxAndFee) {
419
- console.log(products, "products1234");
420
389
  let total = 0;
421
390
  let count = 0;
422
391
  if (applicableProductIds !== null && applicableProductIds.length === 0) {
@@ -29,10 +29,7 @@ var locales = {
29
29
  "usage_limit_reached": "已达到使用次数上限",
30
30
  "max_passes_per_item_reached": "该商品已达到卡券使用上限",
31
31
  "not_available_for_this_channel": "当前渠道不可使用",
32
- "not_valid_for_this_order_type": "当前订单类型不适用",
33
- "order_total_amount_not_enough": "满 {currency}{value} 可用",
34
- "applicable_product_total_amount_not_enough": "满 {currency}{value} 可用",
35
- "applicable_product_count_not_enough": "至少 {value} 件"
32
+ "not_valid_for_this_order_type": "当前订单类型不适用"
36
33
  },
37
34
  "en": {
38
35
  "not_meet_the_required_conditions": "Not meet the required conditions.",
@@ -40,10 +37,7 @@ var locales = {
40
37
  "usage_limit_reached": "Usage limit reached.",
41
38
  "max_passes_per_item_reached": "Max passes per item reached.",
42
39
  "not_available_for_this_channel": "Not available for this channel.",
43
- "not_valid_for_this_order_type": "Not valid for this order type.",
44
- "order_total_amount_not_enough": "Spend {currency}{value} to use",
45
- "applicable_product_total_amount_not_enough": "Spend {currency}{value} to use",
46
- "applicable_product_count_not_enough": "Min. Qty {value}"
40
+ "not_valid_for_this_order_type": "Not valid for this order type."
47
41
  },
48
42
  "zh-HK": {
49
43
  "not_meet_the_required_conditions": "未達使用條件",
@@ -51,10 +45,7 @@ var locales = {
51
45
  "usage_limit_reached": "已達使用次數上限",
52
46
  "max_passes_per_item_reached": "該商品已達卡券使用上限",
53
47
  "not_available_for_this_channel": "當前渠道不可使用",
54
- "not_valid_for_this_order_type": "當前訂單類型不適用",
55
- "order_total_amount_not_enough": "滿 {currency}{value} 可用",
56
- "applicable_product_total_amount_not_enough": "滿 {currency}{value} 可用",
57
- "applicable_product_count_not_enough": "至少 {value} 件"
48
+ "not_valid_for_this_order_type": "當前訂單類型不適用"
58
49
  }
59
50
  };
60
51
  // Annotate the CommonJS export names for ESM import in node:
@@ -27,30 +27,17 @@ export declare class StrategyEngine {
27
27
  *
28
28
  * @param group 条件组
29
29
  * @param context 运行时上下文
30
- * @returns 评估结果对象,包含条件是否满足、收集到的 actionIds、以及失败的原子规则信息
30
+ * @returns 评估结果对象,包含条件是否满足和收集到的 actionIds
31
31
  */
32
32
  private evaluateConditionGroup;
33
33
  /**
34
- * 评估条件组的逻辑运算(带失败规则收集)
35
- *
36
- * 失败规则收集策略:
37
- * - `and`:返回第一个失败的原子规则(嵌套 group 递归取其首个失败原子规则)
38
- * - `or`:所有分支失败时,聚合每个分支的失败规则
39
- * - `not`:被取反规则实际通过时,记录该规则
40
- */
41
- private evaluateGroupLogicDetailed;
42
- /**
43
- * 评估单个规则(带失败规则收集)
44
- */
45
- private evaluateRuleDetailed;
46
- /**
47
- * 评估原子规则(不收集失败信息,仅返回布尔结果)
34
+ * 评估条件组的逻辑运算
48
35
  */
49
- private evaluateAtomicRule;
36
+ private evaluateGroupLogic;
50
37
  /**
51
- * 构建失败规则信息
38
+ * 评估单个规则
52
39
  */
53
- private buildFailedRuleInfo;
40
+ private evaluateRule;
54
41
  /**
55
42
  * 评估代码模式条件
56
43
  */
@@ -42,7 +42,7 @@ var StrategyEngine = class {
42
42
  * 评估策略
43
43
  */
44
44
  evaluate(config, context) {
45
- var _a, _b;
45
+ var _a;
46
46
  const startTime = Date.now();
47
47
  const trace = {
48
48
  steps: [],
@@ -105,11 +105,7 @@ var StrategyEngine = class {
105
105
  matched: {
106
106
  conditions: applicable,
107
107
  actionIds: evaluationResult.actionIds,
108
- details: {},
109
- ...applicable ? {} : {
110
- failedField: (_a = evaluationResult.failedRules[0]) == null ? void 0 : _a.field,
111
- failedRules: evaluationResult.failedRules
112
- }
108
+ details: {}
113
109
  },
114
110
  matchedActions: sortedActions,
115
111
  outputs: {},
@@ -123,7 +119,7 @@ var StrategyEngine = class {
123
119
  } catch (error) {
124
120
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
125
121
  if (this.options.enableTrace) {
126
- (_b = trace.errors) == null ? void 0 : _b.push({
122
+ (_a = trace.errors) == null ? void 0 : _a.push({
127
123
  step: "evaluation",
128
124
  error: errorMessage,
129
125
  timestamp: Date.now()
@@ -153,15 +149,12 @@ var StrategyEngine = class {
153
149
  *
154
150
  * @param group 条件组
155
151
  * @param context 运行时上下文
156
- * @returns 评估结果对象,包含条件是否满足、收集到的 actionIds、以及失败的原子规则信息
152
+ * @returns 评估结果对象,包含条件是否满足和收集到的 actionIds
157
153
  */
158
154
  evaluateConditionGroup(group, context) {
159
155
  const collectedActionIds = [];
160
- const { satisfied, failedRules } = this.evaluateGroupLogicDetailed(
161
- group,
162
- context
163
- );
164
- if (satisfied) {
156
+ const isCurrentLayerSatisfied = this.evaluateGroupLogic(group, context);
157
+ if (isCurrentLayerSatisfied) {
165
158
  collectedActionIds.push(...group.actionIds);
166
159
  for (const rule of group.rules) {
167
160
  if (this.isConditionGroup(rule)) {
@@ -171,98 +164,41 @@ var StrategyEngine = class {
171
164
  }
172
165
  }
173
166
  return {
174
- satisfied,
175
- actionIds: collectedActionIds,
176
- failedRules
167
+ satisfied: isCurrentLayerSatisfied,
168
+ actionIds: collectedActionIds
177
169
  };
178
170
  }
179
171
  /**
180
- * 评估条件组的逻辑运算(带失败规则收集)
181
- *
182
- * 失败规则收集策略:
183
- * - `and`:返回第一个失败的原子规则(嵌套 group 递归取其首个失败原子规则)
184
- * - `or`:所有分支失败时,聚合每个分支的失败规则
185
- * - `not`:被取反规则实际通过时,记录该规则
172
+ * 评估条件组的逻辑运算
186
173
  */
187
- evaluateGroupLogicDetailed(group, context) {
174
+ evaluateGroupLogic(group, context) {
188
175
  const { operator, rules } = group;
189
176
  switch (operator) {
190
- case "and": {
191
- for (const rule of rules) {
192
- const ruleResult = this.evaluateRuleDetailed(rule, context);
193
- if (!ruleResult.satisfied) {
194
- return {
195
- satisfied: false,
196
- failedRules: ruleResult.failedRules
197
- };
198
- }
199
- }
200
- return { satisfied: true, failedRules: [] };
201
- }
202
- case "or": {
203
- const aggregated = [];
204
- for (const rule of rules) {
205
- const ruleResult = this.evaluateRuleDetailed(rule, context);
206
- if (ruleResult.satisfied) {
207
- return { satisfied: true, failedRules: [] };
208
- }
209
- aggregated.push(...ruleResult.failedRules);
210
- }
211
- return { satisfied: false, failedRules: aggregated };
212
- }
213
- case "not": {
214
- if (rules.length === 0) {
215
- return { satisfied: false, failedRules: [] };
216
- }
217
- const ruleResult = this.evaluateRuleDetailed(rules[0], context);
218
- if (ruleResult.satisfied) {
219
- const failed = this.isConditionGroup(rules[0]) ? [] : [this.buildFailedRuleInfo(rules[0], context)];
220
- return { satisfied: false, failedRules: failed };
221
- }
222
- return { satisfied: true, failedRules: [] };
223
- }
177
+ case "and":
178
+ return rules.every((rule) => this.evaluateRule(rule, context));
179
+ case "or":
180
+ return rules.some((rule) => this.evaluateRule(rule, context));
181
+ case "not":
182
+ if (rules.length === 0)
183
+ return false;
184
+ return !this.evaluateRule(rules[0], context);
224
185
  default:
225
186
  throw new Error(`Unknown operator: ${operator}`);
226
187
  }
227
188
  }
228
189
  /**
229
- * 评估单个规则(带失败规则收集)
190
+ * 评估单个规则
230
191
  */
231
- evaluateRuleDetailed(rule, context) {
192
+ evaluateRule(rule, context) {
232
193
  if (this.isConditionGroup(rule)) {
233
- return this.evaluateGroupLogicDetailed(rule, context);
194
+ return this.evaluateGroupLogic(rule, context);
234
195
  }
235
196
  const conditionRule = rule;
236
- const satisfied = this.evaluateAtomicRule(conditionRule, context);
237
- if (satisfied) {
238
- return { satisfied: true, failedRules: [] };
239
- }
240
- return {
241
- satisfied: false,
242
- failedRules: [this.buildFailedRuleInfo(conditionRule, context)]
243
- };
244
- }
245
- /**
246
- * 评估原子规则(不收集失败信息,仅返回布尔结果)
247
- */
248
- evaluateAtomicRule(conditionRule, context) {
249
197
  if (conditionRule.type === "code" && conditionRule.code) {
250
198
  return this.evaluateCodeCondition(conditionRule.code, context);
251
199
  }
252
200
  return this.evaluateOperatorCondition(conditionRule, context);
253
201
  }
254
- /**
255
- * 构建失败规则信息
256
- */
257
- buildFailedRuleInfo(conditionRule, context) {
258
- const actualValue = conditionRule.field ? this.getFieldValue(conditionRule.field, context) : void 0;
259
- return {
260
- field: conditionRule.field,
261
- operator: conditionRule.operator,
262
- value: conditionRule.value,
263
- actualValue
264
- };
265
- }
266
202
  /**
267
203
  * 评估代码模式条件
268
204
  */
@@ -165,23 +165,6 @@ export interface MatchedInfo {
165
165
  actionIds: string[];
166
166
  /** 详细匹配信息 */
167
167
  details: Record<string, any>;
168
- /** 顶层第一个失败的 field(仅在 conditions=false 时存在,便于直接消费) */
169
- failedField?: string;
170
- /** 失败的原子规则列表(仅在 conditions=false 时存在;or 全失败时可能有多条) */
171
- failedRules?: FailedRuleInfo[];
172
- }
173
- /**
174
- * 失败规则信息
175
- */
176
- export interface FailedRuleInfo {
177
- /** 字段名 */
178
- field?: string;
179
- /** 运算符 */
180
- operator?: string;
181
- /** 配置的比较值(阈值) */
182
- value?: any;
183
- /** 实际取到的字段值 */
184
- actualValue?: any;
185
168
  }
186
169
  /**
187
170
  * 执行轨迹
@@ -75,8 +75,6 @@ export interface CartItem {
75
75
  summaryTotal?: number | string;
76
76
  /** 商品原价总价,排除原始价格为0的场景 */
77
77
  origin_total?: number | string;
78
- /** 基于 origin_total 乘以 商品数量的价格 */
79
- summaryOriginTotal?: number | string;
80
78
  /** 商品数量 */
81
79
  num?: number;
82
80
  /** 商品图片 */
@@ -46,18 +46,6 @@ var import_decimal = __toESM(require("decimal.js"));
46
46
  var import_utils = require("../../Product/utils");
47
47
  var import_utils2 = require("../../../solution/ShopDiscount/utils");
48
48
  var import_utils3 = require("../../Summary/utils");
49
- var toDiscountPayload = (discountItem) => {
50
- var _a, _b;
51
- return {
52
- amount: discountItem.amount,
53
- tag: discountItem.type,
54
- par_value: (_a = discountItem.discount) == null ? void 0 : _a.percent,
55
- config: discountItem.config,
56
- metadata: {
57
- discount_card_type: (_b = discountItem == null ? void 0 : discountItem.discount) == null ? void 0 : _b.discount_card_type
58
- }
59
- };
60
- };
61
49
  var handleVariantProduct = (product) => {
62
50
  var _a;
63
51
  if (product == null ? void 0 : product.product_variant_id) {
@@ -102,14 +90,6 @@ var formatProductToCartItem = (params) => {
102
90
  num,
103
91
  discounts
104
92
  });
105
- const origin_total = getProductTotalPrice({
106
- product: cartItem._productInit || cartItem._productOrigin,
107
- bundle,
108
- options,
109
- num,
110
- discounts: []
111
- });
112
- cartItem.summaryOriginTotal = (origin_total || 0) * (num || 1);
113
93
  cartItem.image = product == null ? void 0 : product.cover;
114
94
  cartItem.like_status = "common";
115
95
  cartItem.duration = product == null ? void 0 : product.duration;
@@ -204,24 +184,17 @@ var formatProductToCartItemOrigin = (params) => {
204
184
  var getProductTotalPrice = (params) => {
205
185
  const { product, bundle, options, discounts } = params;
206
186
  let price = Number(product.price);
207
- const optionRows = (options == null ? void 0 : options.map((currentValue) => ({
208
- unit: Number(currentValue.price ?? currentValue.add_price ?? 0),
209
- num: Number(currentValue.num ?? currentValue.quantity ?? 1)
210
- }))) ?? [];
211
187
  if (discounts == null ? void 0 : discounts.length) {
212
188
  discounts.forEach((currentValue) => {
213
189
  var _a;
214
- const payload = toDiscountPayload(currentValue);
215
- price = (0, import_utils2.getDiscountAmount)(payload, price, price);
216
- if (((_a = currentValue == null ? void 0 : currentValue.config) == null ? void 0 : _a.deductOptionPrice) && optionRows.length) {
217
- for (let i = 0; i < optionRows.length; i++) {
218
- const row = optionRows[i];
219
- optionRows[i] = {
220
- ...row,
221
- unit: (0, import_utils2.getDiscountAmount)(payload, row.unit, row.unit)
222
- };
190
+ price = (0, import_utils2.getDiscountAmount)({
191
+ amount: currentValue.amount,
192
+ tag: currentValue.type,
193
+ par_value: currentValue.discount.percent,
194
+ metadata: {
195
+ discount_card_type: (_a = currentValue == null ? void 0 : currentValue.discount) == null ? void 0 : _a.discount_card_type
223
196
  }
224
- }
197
+ }, price, price);
225
198
  });
226
199
  }
227
200
  if (bundle == null ? void 0 : bundle.length) {
@@ -229,11 +202,10 @@ var getProductTotalPrice = (params) => {
229
202
  return accumulator + Number(currentValue.price) * Number(currentValue.num);
230
203
  }, price);
231
204
  }
232
- if (optionRows.length) {
233
- price = optionRows.reduce(
234
- (accumulator, row) => accumulator + row.unit * row.num,
235
- price
236
- );
205
+ if (options == null ? void 0 : options.length) {
206
+ price = options.reduce((accumulator, currentValue) => {
207
+ return accumulator + Number(currentValue.price) * Number(currentValue.num);
208
+ }, price);
237
209
  }
238
210
  return Math.max(0, price);
239
211
  };
@@ -341,6 +313,7 @@ var formatBundleToOrigin = (bundle) => {
341
313
  option: formatOptionsToOrigin(getBundleValueByKey("option")),
342
314
  discount_list: d.discount_list,
343
315
  "bundle_selling_price": d == null ? void 0 : d.price,
316
+ // "custom_price": d?.price,
344
317
  metadata: {
345
318
  custom_product_bundle_map_id: d._id,
346
319
  product_discount_difference
@@ -1,6 +1,6 @@
1
1
  import { Module, PisellCore, ModuleOptions } from '../../types';
2
2
  import { BaseModule } from '../BaseModule';
3
- import { Discount, DiscountModuleAPI } from './types';
3
+ import { Discount, DiscountModuleAPI, DiscountWithReason } from './types';
4
4
  export declare class DiscountModule extends BaseModule implements Module, DiscountModuleAPI {
5
5
  protected defaultName: string;
6
6
  protected defaultVersion: string;
@@ -17,17 +17,23 @@ export declare class DiscountModule extends BaseModule implements Module, Discou
17
17
  setOriginalDiscountList(originalDiscountList: Discount[]): Promise<void>;
18
18
  getOriginalDiscountList(): Discount[];
19
19
  loadPrepareConfig(params: {
20
- action?: 'create';
20
+ action?: 'create' | 'edit';
21
21
  with_good_pass: 0 | 1;
22
22
  with_discount_card: 0 | 1;
23
23
  customer_id: number;
24
24
  with_wallet_pass_holder: 0 | 1;
25
25
  request_timezone: string;
26
+ order_id?: number;
26
27
  }): Promise<Discount[]>;
27
- batchSearch(code: string, customerId?: number): Promise<Discount[]>;
28
+ batchSearch(code: string, options?: {
29
+ customerId?: number;
30
+ orderId?: number;
31
+ }): Promise<DiscountWithReason>;
28
32
  batchSearchByProductIds(productIds: number[]): Promise<any>;
29
33
  filterEnabledDiscountList(discountList: Discount[]): Discount[];
30
34
  private checkUsageCreditsLimit;
35
+ filterEnabledDiscountListWithReason(discountList: Discount[]): DiscountWithReason;
36
+ private checkUsageCreditsLimitWithFailKey;
31
37
  uniqueByProductId(discountList: Discount[]): Discount[];
32
38
  filterDiscountListByProductIds(discountList: Discount[], productIds: number[]): Discount[];
33
39
  calcDiscountApplicableProductTotalPrice(discount: Discount): number | undefined;
@@ -102,20 +102,23 @@ var DiscountModule = class extends import_BaseModule.BaseModule {
102
102
  ) || [];
103
103
  return goodPassList;
104
104
  }
105
- async batchSearch(code, customerId) {
105
+ async batchSearch(code, options) {
106
+ const { customerId, orderId } = options || {};
106
107
  const result = await this.request.get(`/machinecode/batch-search`, {
107
108
  code,
108
109
  translate_flag: 1,
109
110
  tags: ["good_pass", "product_discount_card"],
110
- available: 1,
111
+ // available: 1,
111
112
  relation_product: 1,
112
113
  with: ["extensionData", "customScheduleSnapshot", "holder.detail"],
113
114
  order_behavior_count: 1,
114
115
  order_behavior_count_customer_id: customerId || 1,
116
+ ...orderId ? { order_behavior_count_order_id: orderId } : {},
117
+ unified_status_info_flag: 1,
115
118
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
116
119
  });
117
- const resultDiscountList = this.filterEnabledDiscountList((result == null ? void 0 : result.data) || []) || [];
118
- return resultDiscountList;
120
+ const resultDiscountWithReason = this.filterEnabledDiscountListWithReason((result == null ? void 0 : result.data) || []) || [];
121
+ return resultDiscountWithReason;
119
122
  }
120
123
  async batchSearchByProductIds(productIds) {
121
124
  const result = await this.request.get(`/machinecode/batch-search`, {
@@ -170,6 +173,64 @@ var DiscountModule = class extends import_BaseModule.BaseModule {
170
173
  }
171
174
  return true;
172
175
  }
176
+ // 过滤启用且可用的优惠券,并返回校验失败原因
177
+ filterEnabledDiscountListWithReason(discountList) {
178
+ let lists = discountList.filter((discount) => discount.limit_status === "enable").filter((discount) => {
179
+ const remaining = new import_decimal.default((discount == null ? void 0 : discount.par_value) || 0).minus(new import_decimal.default((discount == null ? void 0 : discount.used_par_value) || 0)).greaterThan(0);
180
+ return remaining;
181
+ }).map((discount) => {
182
+ const limitFailKey = this.checkUsageCreditsLimitWithFailKey(discount);
183
+ return {
184
+ ...discount,
185
+ usageLimitFailKey: limitFailKey
186
+ };
187
+ });
188
+ const availableLists = lists.filter((item) => !item.usageLimitFailKey && item.unified_available_status !== 0);
189
+ const currentFailDiscount = lists.find((item) => item.usageLimitFailKey);
190
+ return {
191
+ discountList: availableLists,
192
+ unavailableReasonKey: currentFailDiscount == null ? void 0 : currentFailDiscount.usageLimitFailKey
193
+ };
194
+ }
195
+ // 检查使用次数限制,并返回校验失败原因
196
+ checkUsageCreditsLimitWithFailKey(discount) {
197
+ if (!discount.extension_data || discount.extension_data.length === 0) {
198
+ return null;
199
+ }
200
+ const usageCreditsData = discount.extension_data.find(
201
+ (data) => data.field_key === "usage_credits"
202
+ );
203
+ if (!usageCreditsData) {
204
+ return null;
205
+ }
206
+ const value = usageCreditsData.value;
207
+ if (value.total_credits && value.total_credits > 0) {
208
+ if ((discount.total_order_behavior_count || 0) >= value.total_credits) {
209
+ return "total_credits";
210
+ }
211
+ }
212
+ if (value.per_user_limit && value.per_user_limit > 0) {
213
+ if ((discount.customer_order_behavior_count || 0) >= value.per_user_limit) {
214
+ return "per_user_limit";
215
+ }
216
+ }
217
+ if (value.max_per_day && value.max_per_day > 0) {
218
+ if ((discount.today_order_behavior_count || 0) >= value.max_per_day) {
219
+ return "max_per_day";
220
+ }
221
+ }
222
+ if (value.max_per_week && value.max_per_week > 0) {
223
+ if ((discount.week_order_behavior_count || 0) >= value.max_per_week) {
224
+ return "max_per_week";
225
+ }
226
+ }
227
+ if (value.max_per_month && value.max_per_month > 0) {
228
+ if ((discount.month_order_behavior_count || 0) >= value.max_per_month) {
229
+ return "max_per_month";
230
+ }
231
+ }
232
+ return null;
233
+ }
173
234
  // 根据productIds去重
174
235
  uniqueByProductId(discountList) {
175
236
  return (0, import_utils.uniqueById)(discountList, "product_id");
@@ -19,7 +19,7 @@ interface PackageSubItemUsageRules {
19
19
  type: 'universal_discount' | 'package_exclusive' | 'single_item_promo' | 'custom_usage_rules';
20
20
  rules: ("original_price" | "markup_price")[];
21
21
  package_scope?: {
22
- type: 'all_packages' | 'specific_packages';
22
+ type: 'all_packages' | 'specific_packages' | 'product_all' | 'products';
23
23
  exclude_bundle_product_ids: number[];
24
24
  include_bundle_product_ids: number[];
25
25
  filter: 0 | 1;
@@ -33,8 +33,6 @@ interface Limitedrelationproductdata {
33
33
  product_ids: number[];
34
34
  product_collection_id: number[];
35
35
  package_sub_item_usage_rules?: PackageSubItemUsageRules;
36
- filter: 0 | 1;
37
- exclude_product_ids: number[];
38
36
  }
39
37
  interface ApplicableProductDetails {
40
38
  amount: string;
@@ -63,6 +61,11 @@ interface UsageCreditsValue {
63
61
  max_per_week: number;
64
62
  max_per_month: number;
65
63
  }
64
+ export type DiscountFilterRejectKey = 'total_credits' | 'per_user_limit' | 'max_per_day' | 'max_per_week' | 'max_per_month';
65
+ export interface DiscountWithReason {
66
+ discountList: Discount[];
67
+ unavailableReasonKey: DiscountFilterRejectKey | null;
68
+ }
66
69
  interface ExtensionData {
67
70
  id: number;
68
71
  shop_id: number;
@@ -91,7 +94,6 @@ export interface Discount {
91
94
  balance: string;
92
95
  format_title: Formattitle;
93
96
  metadata?: {
94
- num?: number;
95
97
  discount_card_type?: 'fixed_amount' | 'percent';
96
98
  custom_product_bundle_map_id?: string;
97
99
  validity_type?: "custom_schedule_validity" | "fixed_validity";
@@ -116,21 +118,6 @@ export interface Discount {
116
118
  isSelected?: boolean;
117
119
  isAvailable?: boolean;
118
120
  isUsed?: boolean;
119
- config?: {
120
- isAvailable?: boolean;
121
- /** 最大抵扣金额 */
122
- maxDeductionAmount?: number;
123
- /** 每单最多使用张数 */
124
- maxUsagePerOrder?: number;
125
- /** 是否抵扣税费与附加费 */
126
- deductTaxAndFee?: boolean;
127
- /** 适用粒度(多商品共用) */
128
- allowCrossProduct?: boolean;
129
- /** 可用商品数量上限 */
130
- applicableProductLimit?: number;
131
- /** 是否抵扣单规格价格 (Option Price) */
132
- deductOptionPrice?: boolean;
133
- };
134
121
  applicableProductIds?: number[];
135
122
  applicableProductDetails: ApplicableProductDetails[];
136
123
  appliedProductDetails: ApplicableProductDetails[];
@@ -149,6 +136,8 @@ export interface Discount {
149
136
  start_date?: string;
150
137
  start_time?: string;
151
138
  discount_rule_uncheck_flag?: boolean;
139
+ usageLimitFailKey?: string | null;
140
+ unified_available_status?: number | undefined | null;
152
141
  }
153
142
  export interface DiscountState {
154
143
  discountList: Discount[];