@pisell/pisellos 1.0.142 → 1.0.143

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 (72) hide show
  1. package/dist/model/strategy/adapter/index.d.ts +4 -0
  2. package/dist/model/strategy/adapter/index.js +4 -1
  3. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +67 -0
  4. package/dist/model/strategy/adapter/itemRule/adapter.js +483 -0
  5. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +43 -0
  6. package/dist/model/strategy/adapter/itemRule/evaluator.js +169 -0
  7. package/dist/model/strategy/adapter/itemRule/examples.d.ts +79 -0
  8. package/dist/model/strategy/adapter/itemRule/examples.js +382 -0
  9. package/dist/model/strategy/adapter/itemRule/index.d.ts +5 -0
  10. package/dist/model/strategy/adapter/itemRule/index.js +5 -0
  11. package/dist/model/strategy/adapter/itemRule/type.d.ts +225 -0
  12. package/dist/model/strategy/adapter/itemRule/type.js +101 -0
  13. package/dist/model/strategy/adapter/promotion/adapter.d.ts +66 -0
  14. package/dist/model/strategy/adapter/promotion/adapter.js +271 -0
  15. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +213 -0
  16. package/dist/model/strategy/adapter/promotion/evaluator.js +1279 -0
  17. package/dist/model/strategy/adapter/promotion/examples.d.ts +138 -0
  18. package/dist/model/strategy/adapter/promotion/examples.js +166 -0
  19. package/dist/model/strategy/adapter/promotion/index.d.ts +4 -0
  20. package/dist/model/strategy/adapter/promotion/index.js +0 -0
  21. package/dist/model/strategy/adapter/promotion/type.d.ts +447 -0
  22. package/dist/model/strategy/adapter/promotion/type.js +209 -0
  23. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  24. package/dist/model/strategy/adapter/walletPass/evaluator.js +67 -10
  25. package/dist/model/strategy/adapter/walletPass/locales.js +12 -3
  26. package/dist/model/strategy/adapter/walletPass/type.d.ts +20 -2
  27. package/dist/model/strategy/adapter/walletPass/utils.d.ts +6 -6
  28. package/dist/model/strategy/adapter/walletPass/utils.js +143 -103
  29. package/dist/model/strategy/engine.d.ts +119 -0
  30. package/dist/model/strategy/engine.js +711 -0
  31. package/dist/model/strategy/index.d.ts +2 -93
  32. package/dist/model/strategy/index.js +6 -549
  33. package/dist/model/strategy/type.d.ts +17 -0
  34. package/dist/model/strategy/type.js +4 -0
  35. package/dist/solution/BookingByStep/index.d.ts +1 -1
  36. package/dist/solution/BookingTicket/index.d.ts +1 -1
  37. package/lib/model/strategy/adapter/index.d.ts +4 -0
  38. package/lib/model/strategy/adapter/index.js +12 -0
  39. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +67 -0
  40. package/lib/model/strategy/adapter/itemRule/adapter.js +377 -0
  41. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +43 -0
  42. package/lib/model/strategy/adapter/itemRule/evaluator.js +124 -0
  43. package/lib/model/strategy/adapter/itemRule/examples.d.ts +79 -0
  44. package/lib/model/strategy/adapter/itemRule/examples.js +316 -0
  45. package/lib/model/strategy/adapter/itemRule/index.d.ts +5 -0
  46. package/lib/model/strategy/adapter/itemRule/index.js +60 -0
  47. package/lib/model/strategy/adapter/itemRule/type.d.ts +225 -0
  48. package/lib/model/strategy/adapter/itemRule/type.js +46 -0
  49. package/lib/model/strategy/adapter/promotion/adapter.d.ts +66 -0
  50. package/lib/model/strategy/adapter/promotion/adapter.js +217 -0
  51. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +213 -0
  52. package/lib/model/strategy/adapter/promotion/evaluator.js +893 -0
  53. package/lib/model/strategy/adapter/promotion/examples.d.ts +138 -0
  54. package/lib/model/strategy/adapter/promotion/examples.js +192 -0
  55. package/lib/model/strategy/adapter/promotion/index.d.ts +4 -0
  56. package/lib/model/strategy/adapter/promotion/index.js +0 -0
  57. package/lib/model/strategy/adapter/promotion/type.d.ts +447 -0
  58. package/lib/model/strategy/adapter/promotion/type.js +51 -0
  59. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  60. package/lib/model/strategy/adapter/walletPass/evaluator.js +38 -5
  61. package/lib/model/strategy/adapter/walletPass/locales.js +12 -3
  62. package/lib/model/strategy/adapter/walletPass/type.d.ts +20 -2
  63. package/lib/model/strategy/adapter/walletPass/utils.d.ts +6 -6
  64. package/lib/model/strategy/adapter/walletPass/utils.js +153 -82
  65. package/lib/model/strategy/engine.d.ts +119 -0
  66. package/lib/model/strategy/engine.js +514 -0
  67. package/lib/model/strategy/index.d.ts +2 -93
  68. package/lib/model/strategy/index.js +6 -381
  69. package/lib/model/strategy/type.d.ts +17 -0
  70. package/lib/solution/BookingByStep/index.d.ts +1 -1
  71. package/lib/solution/BookingTicket/index.d.ts +1 -1
  72. package/package.json +1 -1
@@ -20,9 +20,47 @@ var defaultStrategyMetadataCustom = {
20
20
  allowCrossProduct: true,
21
21
  applicableProductLimit: 0,
22
22
  deductTaxAndFee: true,
23
- maxPassesPerItem: 0
23
+ maxPassesPerItem: 0,
24
+ deductOptionPrice: false
24
25
  };
25
26
 
27
+ /**
28
+ * 条件 field → reasonCode 映射
29
+ * 用于将策略引擎返回的 failedField 转换为本地化文案 key
30
+ */
31
+ var FIELD_REASON_CODE_MAP = {
32
+ orderTotalAmount: 'order_total_amount_not_enough',
33
+ applicableProductTotalAmount: 'applicable_product_total_amount_not_enough',
34
+ applicableProductCount: 'applicable_product_count_not_enough'
35
+ };
36
+
37
+ /**
38
+ * 金额类型 field 集合(需要在文案前拼货币符号)
39
+ */
40
+ var AMOUNT_FIELDS = new Set(['orderTotalAmount', 'applicableProductTotalAmount']);
41
+
42
+ /**
43
+ * 用阈值与货币符号替换文案中的占位符
44
+ * 支持占位符:{value} / ${value} / {currency}
45
+ */
46
+ function formatReason(template, value) {
47
+ var currency = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
48
+ if (!template) return template;
49
+ var v = value === undefined || value === null ? '' : String(value);
50
+ var c = currency === undefined || currency === null ? '' : String(currency);
51
+ // 注意:必须先替换 value,再替换 currency
52
+ // 否则 currency 注入的 "$" 会被后续的 /\$\{value\}/ 正则误吞
53
+ // 使用函数作为替换参数,避免替换串中的 "$" 被 String.prototype.replace
54
+ // 当作特殊序列(如 $$ -> $、$& 等)处理
55
+ return template.replace(/\$\{value\}/g, function () {
56
+ return v;
57
+ }).replace(/\{value\}/g, function () {
58
+ return v;
59
+ }).replace(/\{currency\}/g, function () {
60
+ return c;
61
+ });
62
+ }
63
+
26
64
  /**
27
65
  * Wallet Pass 评估器
28
66
  * 用于评估哪些 voucher 可以在当前订单中使用
@@ -33,6 +71,7 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
33
71
  _defineProperty(this, "engine", void 0);
34
72
  _defineProperty(this, "strategyConfigs", []);
35
73
  _defineProperty(this, "locale", 'en');
74
+ _defineProperty(this, "otherParams", {});
36
75
  this.engine = new StrategyEngine({
37
76
  debug: false,
38
77
  enableTrace: false
@@ -41,7 +80,10 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
41
80
  _createClass(WalletPassEvaluator, [{
42
81
  key: "setStrategyConfigs",
43
82
  value: function setStrategyConfigs(strategyConfigs) {
44
- this.strategyConfigs = strategyConfigs;
83
+ var newStrategyConfigs = strategyConfigs.filter(function (item) {
84
+ return item.metadata.type === 'wallet_pass';
85
+ });
86
+ this.strategyConfigs = newStrategyConfigs;
45
87
  }
46
88
  }, {
47
89
  key: "getStrategyConfigs",
@@ -53,6 +95,11 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
53
95
  value: function setLocale(locale) {
54
96
  this.locale = locale;
55
97
  }
98
+ }, {
99
+ key: "setOtherParams",
100
+ value: function setOtherParams(otherParams) {
101
+ this.otherParams = otherParams;
102
+ }
56
103
  }, {
57
104
  key: "getText",
58
105
  value: function getText(key) {
@@ -187,13 +234,17 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
187
234
  strategyResult: evaluationResult
188
235
  });
189
236
  } else {
190
- // 根据策略评估结果的 code 映射到 locales 中的原因
191
- var reasonCode = 'not_meet_the_required_conditions'; // 默认原因
192
-
193
- // 根据策略引擎返回的 code 映射到本地化的 reasonCode
194
- if (evaluationResult.code) {
195
- // 可以根据具体的 code 映射到不同的原因
196
- // 例如:如果是金额不足、使用次数限制等
237
+ var _evaluationResult$mat, _evaluationResult$mat2, _this$otherParams, _this$otherParams$get, _this$otherParams2;
238
+ // 优先根据失败的 field 映射到具体的 reasonCode(更精确的失败原因)
239
+ var reasonCode = 'not_meet_the_required_conditions';
240
+ var thresholdValue = undefined;
241
+ var failedField = (_evaluationResult$mat = evaluationResult.matched) === null || _evaluationResult$mat === void 0 ? void 0 : _evaluationResult$mat.failedField;
242
+ var failedRule = (_evaluationResult$mat2 = evaluationResult.matched) === null || _evaluationResult$mat2 === void 0 || (_evaluationResult$mat2 = _evaluationResult$mat2.failedRules) === null || _evaluationResult$mat2 === void 0 ? void 0 : _evaluationResult$mat2[0];
243
+ if (failedField && FIELD_REASON_CODE_MAP[failedField]) {
244
+ reasonCode = FIELD_REASON_CODE_MAP[failedField];
245
+ thresholdValue = failedRule === null || failedRule === void 0 ? void 0 : failedRule.value;
246
+ } else if (evaluationResult.code) {
247
+ // 兜底:保留原有 code → reasonCode 映射
197
248
  var codeMapping = {
198
249
  INSUFFICIENT_AMOUNT: 'not_meet_the_required_conditions',
199
250
  USAGE_LIMIT_EXCEEDED: 'usage_limit_reached',
@@ -203,6 +254,11 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
203
254
  };
204
255
  reasonCode = codeMapping[evaluationResult.code] || 'not_meet_the_required_conditions';
205
256
  }
257
+ var rawText = this.getText(reasonCode);
258
+ // 金额类型字段:从 otherParams.getData 取货币符号;非金额或取不到则留空
259
+ var currency = failedField && AMOUNT_FIELDS.has(failedField) ? ((_this$otherParams = this.otherParams) === null || _this$otherParams === void 0 || (_this$otherParams$get = (_this$otherParams2 = _this$otherParams).getData) === null || _this$otherParams$get === void 0 ? void 0 : _this$otherParams$get.call(_this$otherParams2, 'shop_symbol')) || '' : '';
260
+ console.log(currency, 'currency12345');
261
+ var reason = thresholdValue !== undefined ? formatReason(rawText, thresholdValue, currency) : rawText;
206
262
  results.push({
207
263
  voucher: voucher,
208
264
  isApplicable: false,
@@ -210,7 +266,7 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
210
266
  maxDeduction: 0,
211
267
  deductTaxAndFee: false,
212
268
  applicableProductIds: [],
213
- reason: this.getText(reasonCode),
269
+ reason: reason,
214
270
  reasonCode: reasonCode,
215
271
  strategyResult: evaluationResult
216
272
  });
@@ -450,6 +506,7 @@ export var WalletPassEvaluator = /*#__PURE__*/function () {
450
506
  }, {
451
507
  key: "calculateApplicableProducts",
452
508
  value: function calculateApplicableProducts(products, applicableProductIds, deductTaxAndFee) {
509
+ console.log(products, 'products1234');
453
510
  var total = 0;
454
511
  var count = 0;
455
512
 
@@ -5,7 +5,10 @@ export var locales = {
5
5
  'usage_limit_reached': '已达到使用次数上限',
6
6
  'max_passes_per_item_reached': '该商品已达到卡券使用上限',
7
7
  'not_available_for_this_channel': '当前渠道不可使用',
8
- 'not_valid_for_this_order_type': '当前订单类型不适用'
8
+ 'not_valid_for_this_order_type': '当前订单类型不适用',
9
+ 'order_total_amount_not_enough': '满 {currency}{value} 可用',
10
+ 'applicable_product_total_amount_not_enough': '满 {currency}{value} 可用',
11
+ 'applicable_product_count_not_enough': '至少 {value} 件'
9
12
  },
10
13
  'en': {
11
14
  'not_meet_the_required_conditions': 'Not meet the required conditions.',
@@ -13,7 +16,10 @@ export var locales = {
13
16
  'usage_limit_reached': 'Usage limit reached.',
14
17
  'max_passes_per_item_reached': 'Max passes per item reached.',
15
18
  'not_available_for_this_channel': 'Not available for this channel.',
16
- 'not_valid_for_this_order_type': 'Not valid for this order type.'
19
+ 'not_valid_for_this_order_type': 'Not valid for this order type.',
20
+ 'order_total_amount_not_enough': 'Spend {currency}{value} to use',
21
+ 'applicable_product_total_amount_not_enough': 'Spend {currency}{value} to use',
22
+ 'applicable_product_count_not_enough': 'Min. Qty {value}'
17
23
  },
18
24
  'zh-HK': {
19
25
  'not_meet_the_required_conditions': '未達使用條件',
@@ -21,6 +27,9 @@ export var locales = {
21
27
  'usage_limit_reached': '已達使用次數上限',
22
28
  'max_passes_per_item_reached': '該商品已達卡券使用上限',
23
29
  'not_available_for_this_channel': '當前渠道不可使用',
24
- 'not_valid_for_this_order_type': '當前訂單類型不適用'
30
+ 'not_valid_for_this_order_type': '當前訂單類型不適用',
31
+ 'order_total_amount_not_enough': '滿 {currency}{value} 可用',
32
+ 'applicable_product_total_amount_not_enough': '滿 {currency}{value} 可用',
33
+ 'applicable_product_count_not_enough': '至少 {value} 件'
25
34
  }
26
35
  };
@@ -41,8 +41,10 @@ export interface Voucher {
41
41
  allowCrossProduct: boolean;
42
42
  /** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
43
43
  applicableProductLimit: number;
44
- /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品行最多抵扣次数)。默认为 0,表示不限制。 */
44
+ /** 单订单行每单位可用同一 Wallet Pass 券次数;该行总券次上限 = maxPassesPerItem × 该行 quantity(按行唯一键区分)。0 表示不限制。 */
45
45
  maxPassesPerItem: number;
46
+ /** 是否抵扣单规格价格 (Option Price),默认 false。开启后折扣范围包含 option 的 add_price */
47
+ deductOptionPrice: boolean;
46
48
  };
47
49
  }
48
50
  /**
@@ -50,6 +52,10 @@ export interface Voucher {
50
52
  */
51
53
  export interface Product {
52
54
  product_id: number;
55
+ /** 订单明细 id,参与行唯一键兜底解析 */
56
+ id?: number;
57
+ /** 行级唯一串,参与行唯一键解析 */
58
+ product_unique_string?: string;
53
59
  price: number;
54
60
  quantity: number;
55
61
  name?: string;
@@ -58,9 +64,19 @@ export interface Product {
58
64
  main_product_original_price?: number;
59
65
  /** 主商品折扣后金额,不包含套餐子商品 */
60
66
  main_product_selling_price?: number;
67
+ /** 单规格(Option)列表 */
68
+ product_options?: {
69
+ id: number;
70
+ add_price: number | string;
71
+ num: number;
72
+ [key: string]: any;
73
+ }[];
61
74
  /** 主商品税费 */
62
75
  tax_fee: number;
63
76
  metadata: {
77
+ /** 行唯一标识,优先用于 Wallet Pass 按行配额 */
78
+ product_unique?: string;
79
+ unique_identification_number?: string;
64
80
  main_product_attached_bundle_tax_fee?: number;
65
81
  main_product_attached_bundle_surcharge_fee?: number;
66
82
  surcharge_rounding_remainder?: number;
@@ -132,8 +148,10 @@ export interface EvaluatorInput {
132
148
  allowCrossProduct: boolean;
133
149
  /** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
134
150
  applicableProductLimit: number;
135
- /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品行最多抵扣次数)。默认为 0,表示不限制。 */
151
+ /** 单订单行每单位可用同一 Wallet Pass 券次数;行总上限 = maxPassesPerItem × 该行 quantity(按行唯一键计)。0 表示不限制。 */
136
152
  maxPassesPerItem: number;
153
+ /** 是否抵扣单规格价格 (Option Price),默认 false */
154
+ deductOptionPrice: boolean;
137
155
  }>[];
138
156
  }
139
157
  /**
@@ -1,4 +1,10 @@
1
1
  import { Product, Voucher } from './type';
2
+ /** 订单商品数量 */
3
+ export declare const getProductQuantity: (product: any) => any;
4
+ /**
5
+ * 订单商品行唯一键,用于 maxPassesPerItem 按行、按件配额(同 SPU 不同规格视为不同行)。
6
+ */
7
+ export declare function resolveWalletPassLineKey(product: any, indexInOrder: number): string;
2
8
  export declare const getApplicableProductIds: (voucher: Voucher) => number[] | null;
3
9
  /**
4
10
  * 优惠券处理函数
@@ -64,12 +70,6 @@ export declare const getBundleItemDiscountDifference: (bundleItem: any) => numbe
64
70
  * @returns 子商品总价格(不含舍入余数)
65
71
  */
66
72
  export declare const getBundleItemPrice: (bundleItem: any, parentQuantity: number, isDeductTaxAndFee: boolean) => number;
67
- /**
68
- * 获取商品数量
69
- * @param product 商品
70
- * @returns 商品数量
71
- */
72
- export declare const getProductQuantity: (product: any) => any;
73
73
  export declare const getBundleItemIsOriginalPrice: (item: any) => boolean;
74
74
  export declare const getBundleItemIsMarkupPrice: (item: any) => boolean;
75
75
  export declare const getBundleItemIsDiscountPrice: (item: any) => boolean;