@pisell/pisellos 2.2.71 → 2.2.73

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 (47) hide show
  1. package/dist/model/strategy/adapter/index.d.ts +2 -0
  2. package/dist/model/strategy/adapter/index.js +2 -1
  3. package/dist/model/strategy/adapter/promotion/adapter.d.ts +66 -0
  4. package/dist/model/strategy/adapter/promotion/adapter.js +271 -0
  5. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +213 -0
  6. package/dist/model/strategy/adapter/promotion/evaluator.js +1210 -0
  7. package/dist/model/strategy/adapter/promotion/examples.d.ts +138 -0
  8. package/dist/model/strategy/adapter/promotion/examples.js +166 -0
  9. package/dist/model/strategy/adapter/promotion/index.d.ts +4 -0
  10. package/dist/model/strategy/adapter/promotion/index.js +0 -0
  11. package/dist/model/strategy/adapter/promotion/type.d.ts +447 -0
  12. package/dist/model/strategy/adapter/promotion/type.js +209 -0
  13. package/dist/model/strategy/adapter/walletPass/evaluator.js +4 -1
  14. package/dist/model/strategy/engine.d.ts +106 -0
  15. package/dist/model/strategy/engine.js +611 -0
  16. package/dist/model/strategy/index.d.ts +2 -93
  17. package/dist/model/strategy/index.js +6 -549
  18. package/dist/modules/BaseModule.d.ts +4 -0
  19. package/dist/modules/BaseModule.js +5 -0
  20. package/dist/modules/Product/index.d.ts +1 -1
  21. package/dist/modules/Rules/index.d.ts +1 -0
  22. package/dist/modules/Rules/index.js +52 -23
  23. package/dist/solution/BookingTicket/index.d.ts +1 -1
  24. package/lib/model/strategy/adapter/index.d.ts +2 -0
  25. package/lib/model/strategy/adapter/index.js +6 -0
  26. package/lib/model/strategy/adapter/promotion/adapter.d.ts +66 -0
  27. package/lib/model/strategy/adapter/promotion/adapter.js +217 -0
  28. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +213 -0
  29. package/lib/model/strategy/adapter/promotion/evaluator.js +846 -0
  30. package/lib/model/strategy/adapter/promotion/examples.d.ts +138 -0
  31. package/lib/model/strategy/adapter/promotion/examples.js +192 -0
  32. package/lib/model/strategy/adapter/promotion/index.d.ts +4 -0
  33. package/lib/model/strategy/adapter/promotion/index.js +0 -0
  34. package/lib/model/strategy/adapter/promotion/type.d.ts +447 -0
  35. package/lib/model/strategy/adapter/promotion/type.js +51 -0
  36. package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -1
  37. package/lib/model/strategy/engine.d.ts +106 -0
  38. package/lib/model/strategy/engine.js +450 -0
  39. package/lib/model/strategy/index.d.ts +2 -93
  40. package/lib/model/strategy/index.js +6 -381
  41. package/lib/modules/BaseModule.d.ts +4 -0
  42. package/lib/modules/BaseModule.js +3 -0
  43. package/lib/modules/Product/index.d.ts +1 -1
  44. package/lib/modules/Rules/index.d.ts +1 -0
  45. package/lib/modules/Rules/index.js +35 -19
  46. package/lib/solution/BookingTicket/index.d.ts +1 -1
  47. package/package.json +1 -1
@@ -201,6 +201,13 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
201
201
  productList: hasApplicableDiscount ? result.productList : productList
202
202
  };
203
203
  }
204
+ }, {
205
+ key: "filterDiscountListByType",
206
+ value: function filterDiscountListByType(discountList, type) {
207
+ return (discountList || []).filter(function (item) {
208
+ return item.type === type || item.tag === type;
209
+ });
210
+ }
204
211
  }, {
205
212
  key: "calcDiscount",
206
213
  value: function calcDiscount(_ref2, options) {
@@ -953,6 +960,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
953
960
  }) && (!((_product$discount_lis5 = product.discount_list) !== null && _product$discount_lis5 !== void 0 && _product$discount_lis5.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) {
954
961
  return item.type === 'product';
955
962
  })));
963
+ if (product.inPromotion) {
964
+ isManualDiscount = false;
965
+ }
956
966
  } else {
957
967
  // bundle子商品:判断父主商品是否手动折扣
958
968
  var parentProduct = flatItem.parentProduct;
@@ -1048,25 +1058,36 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1048
1058
  }),
1049
1059
  price: product.price
1050
1060
  }), {}, {
1051
- discount_list: []
1061
+ discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion')
1052
1062
  }))]);
1053
1063
  } else {
1064
+ var _ref7, _product$_promotion$f, _product12, _product$origin_total;
1065
+ var total = product.inPromotion ? (_ref7 = (_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 && _ref7 !== void 0 ? _ref7 : product.total : (_product$origin_total = product.origin_total) !== null && _product$origin_total !== void 0 ? _product$origin_total : product.total;
1066
+ var main_product_selling_price = product.price;
1067
+ if ((product.discount_list || []).some(function (item) {
1068
+ return item.type === 'promotion';
1069
+ })) {
1070
+ var _product$total, _product$main_product;
1071
+ total = (_product$total = product.total) !== null && _product$total !== void 0 ? _product$total : product.origin_total;
1072
+ 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;
1073
+ }
1054
1074
  processedProductsMap.set(product._id, [_this3.hooks.setProduct(originProduct, _objectSpread(_objectSpread({}, isManualDiscount ? {
1055
1075
  price: product.price,
1056
1076
  main_product_selling_price: product.price
1057
1077
  } : {
1058
1078
  _id: product._id.split('___')[0] + '___' + index,
1059
- total: product.origin_total || product.total,
1079
+ total: total,
1060
1080
  price: product.price,
1061
- main_product_selling_price: product.price
1081
+ main_product_selling_price: main_product_selling_price
1062
1082
  }), {}, {
1063
- discount_list: []
1083
+ discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion')
1064
1084
  }))]);
1065
1085
  }
1066
1086
  } else {
1087
+ var _flatItem$bundleItem8;
1067
1088
  // bundle子商品:保存到扁平化Map
1068
1089
  processedFlatItemsMap.set(flatItem._id, [_objectSpread(_objectSpread({}, flatItem), {}, {
1069
- discount_list: [],
1090
+ discount_list: _this3.filterDiscountListByType(((_flatItem$bundleItem8 = flatItem.bundleItem) === null || _flatItem$bundleItem8 === void 0 ? void 0 : _flatItem$bundleItem8.discount_list) || [], 'promotion'),
1070
1091
  price: isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price,
1071
1092
  processed: true
1072
1093
  })]);
@@ -1098,15 +1119,23 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1098
1119
  if (flatItem.type === 'main') {
1099
1120
  // 主商品:保持原有逻辑
1100
1121
  if (splitCount < totalQuantity && isNeedSplit) {
1122
+ var _product$origin_total2;
1123
+ var _total = (_product$origin_total2 = product.origin_total) !== null && _product$origin_total2 !== void 0 ? _product$origin_total2 : product.total;
1124
+ if ((product.discount_list || []).some(function (item) {
1125
+ return item.type === 'promotion';
1126
+ })) {
1127
+ var _product$total2;
1128
+ _total = (_product$total2 = product.total) !== null && _product$total2 !== void 0 ? _product$total2 : product.origin_total;
1129
+ }
1101
1130
  arr.push(_this3.hooks.setProduct(originProduct, {
1102
- discount_list: [],
1131
+ discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1103
1132
  quantity: totalQuantity - splitCount,
1104
1133
  _id: product._id.split('___')[0],
1105
- total: product.origin_total || product.total
1134
+ total: _total
1106
1135
  }));
1107
1136
  }
1108
1137
  for (var i = 0; i < splitCount; i++) {
1109
- var _product$discount_lis10, _originProduct, _selectedDiscount$met, _selectedDiscount$met2;
1138
+ var _originProduct, _selectedDiscount$met, _selectedDiscount$met2;
1110
1139
  // 如果用过折扣卡,也就不存在拆分的情况了,这里直接使用上面计算出来的折扣卡
1111
1140
  var _selectedDiscount = selectedDiscountCard || applicableDiscounts[i];
1112
1141
  // 标记优惠券为已使用
@@ -1123,7 +1152,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1123
1152
  // 优先从 origin_total拿,可能会拿不到(比如用户端预约在没有配置 original_price 的情况下)
1124
1153
  var productOriginTotal = product.origin_total || product.total || 0;
1125
1154
  // 如果当前 product 有 discount_list,则先从 origin_total 拿
1126
- if ((_product$discount_lis10 = product.discount_list) !== null && _product$discount_lis10 !== void 0 && _product$discount_lis10.length && product.origin_total) {
1155
+ if (_this3.filterDiscountListByType(product.discount_list, 'promotion').length && product.origin_total) {
1127
1156
  productOriginTotal = product.origin_total;
1128
1157
  }
1129
1158
  // 如果originProduct?._productInit?.original_price为 0,product.origin_total可能为空,此时取 product.total
@@ -1176,13 +1205,13 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1176
1205
  };
1177
1206
  appliedProducts.push(discountDetail);
1178
1207
  appliedDiscountProducts.set(_selectedDiscount.id, appliedProducts);
1179
- var total = targetProductTotal;
1208
+ var _total2 = targetProductTotal;
1180
1209
  if (product.options) {
1181
- total = product.options.reduce(function (accumulator, currentValue) {
1210
+ _total2 = product.options.reduce(function (accumulator, currentValue) {
1182
1211
  var currentPrice = new Decimal(currentValue.price || 0);
1183
1212
  var currentNum = new Decimal(currentValue.num || 0);
1184
1213
  return accumulator.add(currentPrice.mul(currentNum));
1185
- }, new Decimal(total)).toNumber();
1214
+ }, new Decimal(_total2)).toNumber();
1186
1215
  }
1187
1216
 
1188
1217
  // 记录应用了优惠券的商品
@@ -1201,15 +1230,15 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1201
1230
  }),
1202
1231
  variant: originProduct._productInit.variant,
1203
1232
  original_price: new Decimal(product.price || 0).toNumber(),
1204
- total: total
1233
+ total: _total2
1205
1234
  }));
1206
1235
  } else {
1207
1236
  arr.push(_this3.hooks.setProduct(originProduct, {
1208
- discount_list: [discountDetail],
1237
+ discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion').concat([discountDetail]),
1209
1238
  _id: product._id.split('___')[0] + '___' + _selectedDiscount.id + index,
1210
1239
  price: _selectedDiscount.tag === 'good_pass' ? 0 : product.price,
1211
1240
  quantity: isNeedSplit ? 1 : product.quantity,
1212
- total: total,
1241
+ total: _total2,
1213
1242
  origin_total: productOriginTotal,
1214
1243
  main_product_selling_price: targetProductTotal
1215
1244
  }));
@@ -1376,7 +1405,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1376
1405
  var getDefaultProduct = function getDefaultProduct() {
1377
1406
  if (product.isClient) {
1378
1407
  return _this3.hooks.setProduct(originProduct, {
1379
- discount_list: [],
1408
+ discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1380
1409
  price: product.price,
1381
1410
  origin_total: getProductOriginTotalPrice({
1382
1411
  product: {
@@ -1397,7 +1426,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1397
1426
  });
1398
1427
  } else {
1399
1428
  return _this3.hooks.setProduct(originProduct, {
1400
- discount_list: [],
1429
+ discount_list: _this3.filterDiscountListByType(product.discount_list, 'promotion'),
1401
1430
  total: product.total,
1402
1431
  origin_total: product.origin_total,
1403
1432
  price: product.price
@@ -1858,10 +1887,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1858
1887
  return true; // 单独购买时可用
1859
1888
  }
1860
1889
  if (isBundleItem) {
1861
- var _flatItem$bundleItem8, _flatItem$bundleItem9;
1890
+ var _flatItem$bundleItem9, _flatItem$bundleItem10;
1862
1891
  // 套餐中购买时,判断是否为原价
1863
- var priceType = (_flatItem$bundleItem8 = flatItem.bundleItem) === null || _flatItem$bundleItem8 === void 0 ? void 0 : _flatItem$bundleItem8.price_type;
1864
- var priceTypeExt = (_flatItem$bundleItem9 = flatItem.bundleItem) === null || _flatItem$bundleItem9 === void 0 ? void 0 : _flatItem$bundleItem9.price_type_ext;
1892
+ var priceType = (_flatItem$bundleItem9 = flatItem.bundleItem) === null || _flatItem$bundleItem9 === void 0 ? void 0 : _flatItem$bundleItem9.price_type;
1893
+ var priceTypeExt = (_flatItem$bundleItem10 = flatItem.bundleItem) === null || _flatItem$bundleItem10 === void 0 ? void 0 : _flatItem$bundleItem10.price_type_ext;
1865
1894
  // original_price 对应:
1866
1895
  // 1. price_type: "markup" && price_type_ext: "product_price"
1867
1896
  // markup_price 对应:
@@ -1899,10 +1928,10 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1899
1928
  return false; // 单独购买时不可用
1900
1929
  }
1901
1930
  if (isBundleItem) {
1902
- var _flatItem$bundleItem10, _flatItem$bundleItem11;
1931
+ var _flatItem$bundleItem11, _flatItem$bundleItem12;
1903
1932
  // 套餐中购买时,判断是否为原价
1904
- var _priceType = (_flatItem$bundleItem10 = flatItem.bundleItem) === null || _flatItem$bundleItem10 === void 0 ? void 0 : _flatItem$bundleItem10.price_type;
1905
- var _priceTypeExt = (_flatItem$bundleItem11 = flatItem.bundleItem) === null || _flatItem$bundleItem11 === void 0 ? void 0 : _flatItem$bundleItem11.price_type_ext;
1933
+ var _priceType = (_flatItem$bundleItem11 = flatItem.bundleItem) === null || _flatItem$bundleItem11 === void 0 ? void 0 : _flatItem$bundleItem11.price_type;
1934
+ var _priceTypeExt = (_flatItem$bundleItem12 = flatItem.bundleItem) === null || _flatItem$bundleItem12 === void 0 ? void 0 : _flatItem$bundleItem12.price_type_ext;
1906
1935
 
1907
1936
  // original_price 对应:
1908
1937
  // 1. price_type: "markup" && price_type_ext: "product_price"
@@ -123,7 +123,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
123
123
  * 获取当前的客户搜索条件
124
124
  * @returns 当前搜索条件
125
125
  */
126
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
126
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
127
127
  /**
128
128
  * 获取客户列表状态(包含滚动加载相关状态)
129
129
  * @returns 客户状态
@@ -1,3 +1,5 @@
1
1
  export * from './type';
2
2
  export { default as WalletPassAdapter } from './walletPass';
3
3
  export { WalletPassEvaluator } from './walletPass/evaluator';
4
+ export { PromotionEvaluator } from './promotion/evaluator';
5
+ export { PromotionAdapter } from './promotion/adapter';
@@ -30,6 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/model/strategy/adapter/index.ts
31
31
  var adapter_exports = {};
32
32
  __export(adapter_exports, {
33
+ PromotionAdapter: () => import_adapter.PromotionAdapter,
34
+ PromotionEvaluator: () => import_evaluator2.PromotionEvaluator,
33
35
  WalletPassAdapter: () => import_walletPass.default,
34
36
  WalletPassEvaluator: () => import_evaluator.WalletPassEvaluator
35
37
  });
@@ -37,8 +39,12 @@ module.exports = __toCommonJS(adapter_exports);
37
39
  __reExport(adapter_exports, require("./type"), module.exports);
38
40
  var import_walletPass = __toESM(require("./walletPass"));
39
41
  var import_evaluator = require("./walletPass/evaluator");
42
+ var import_evaluator2 = require("./promotion/evaluator");
43
+ var import_adapter = require("./promotion/adapter");
40
44
  // Annotate the CommonJS export names for ESM import in node:
41
45
  0 && (module.exports = {
46
+ PromotionAdapter,
47
+ PromotionEvaluator,
42
48
  WalletPassAdapter,
43
49
  WalletPassEvaluator,
44
50
  ...require("./type")
@@ -0,0 +1,66 @@
1
+ import type { EvaluationResult, RuntimeContext } from '../../type';
2
+ import type { BusinessAdapter } from '../type';
3
+ import type { PromotionBusinessData, PromotionTransformResult } from './type';
4
+ /**
5
+ * Promotion 适配器
6
+ *
7
+ * 用于将促销活动业务数据转换为策略引擎可识别的格式
8
+ * 策略引擎只负责匹配,具体的优惠计算由业务层完成
9
+ */
10
+ export declare class PromotionAdapter implements BusinessAdapter {
11
+ name: string;
12
+ version: string;
13
+ /**
14
+ * 准备运行时上下文
15
+ *
16
+ * 将业务数据转换为策略引擎可识别的 RuntimeContext
17
+ */
18
+ prepareContext(businessData: PromotionBusinessData): RuntimeContext;
19
+ /**
20
+ * 转换执行结果
21
+ *
22
+ * 将策略引擎的通用结果转换为业务层需要的格式
23
+ * 主要是整理 matchedActions,让业务层更容易使用
24
+ */
25
+ transformResult(result: EvaluationResult, businessData?: PromotionBusinessData): PromotionTransformResult;
26
+ /**
27
+ * 格式化配置
28
+ */
29
+ formatConfig(result: EvaluationResult, businessData?: PromotionBusinessData): {
30
+ result: EvaluationResult;
31
+ businessData?: PromotionBusinessData;
32
+ };
33
+ /**
34
+ * 格式化日期时间
35
+ */
36
+ private formatDateTime;
37
+ /**
38
+ * 解析 Action 详情
39
+ *
40
+ * 将 matchedAction 转换为更易用的结构
41
+ */
42
+ private parseActionDetail;
43
+ /**
44
+ * 解析 X件Y元 Action
45
+ */
46
+ private parseXItemsForYPriceAction;
47
+ /**
48
+ * 解析 买X送Y Action
49
+ */
50
+ private parseBuyXGetYFreeAction;
51
+ /**
52
+ * 获取适用的商品列表
53
+ *
54
+ * 从购物车商品中筛选出符合策略条件的商品
55
+ */
56
+ private getApplicableProducts;
57
+ /**
58
+ * 查找商品匹配规则
59
+ */
60
+ private findProductMatchRule;
61
+ /**
62
+ * 检查商品是否匹配
63
+ */
64
+ private isProductMatch;
65
+ }
66
+ export default PromotionAdapter;
@@ -0,0 +1,217 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/model/strategy/adapter/promotion/adapter.ts
20
+ var adapter_exports = {};
21
+ __export(adapter_exports, {
22
+ PromotionAdapter: () => PromotionAdapter,
23
+ default: () => adapter_default
24
+ });
25
+ module.exports = __toCommonJS(adapter_exports);
26
+ var import_type = require("./type");
27
+ var PromotionAdapter = class {
28
+ constructor() {
29
+ this.name = "PromotionAdapter";
30
+ this.version = "1.0.0";
31
+ }
32
+ /**
33
+ * 准备运行时上下文
34
+ *
35
+ * 将业务数据转换为策略引擎可识别的 RuntimeContext
36
+ */
37
+ prepareContext(businessData) {
38
+ const { products, currentProduct, channel, custom } = businessData;
39
+ const now = /* @__PURE__ */ new Date();
40
+ const currentDateTime = this.formatDateTime(now);
41
+ const evaluatingProduct = currentProduct || (products.length > 0 ? products[0] : null);
42
+ return {
43
+ entities: {
44
+ products,
45
+ currentProduct: evaluatingProduct
46
+ },
47
+ attributes: {
48
+ // 当前时间(格式化字符串,用于时间条件判断)
49
+ currentDateTime,
50
+ // 当前评估的商品信息(用于 product_match 运算符)
51
+ productIdAndVariantId: evaluatingProduct ? {
52
+ product_id: evaluatingProduct.product_id,
53
+ product_variant_id: evaluatingProduct.product_variant_id
54
+ } : null,
55
+ // 渠道
56
+ channel: channel || "",
57
+ // 商品总数量
58
+ totalQuantity: products.reduce((sum, p) => sum + p.quantity, 0),
59
+ // 商品总金额
60
+ totalAmount: products.reduce((sum, p) => sum + p.price * p.quantity, 0),
61
+ // 自定义属性
62
+ ...custom
63
+ },
64
+ metadata: {
65
+ timestamp: Date.now()
66
+ }
67
+ };
68
+ }
69
+ /**
70
+ * 转换执行结果
71
+ *
72
+ * 将策略引擎的通用结果转换为业务层需要的格式
73
+ * 主要是整理 matchedActions,让业务层更容易使用
74
+ */
75
+ transformResult(result, businessData) {
76
+ const applicableProducts = businessData ? this.getApplicableProducts(result, businessData) : [];
77
+ if (!result.applicable) {
78
+ return {
79
+ isApplicable: false,
80
+ applicableProducts: [],
81
+ reason: result.message,
82
+ reasonCode: result.code,
83
+ strategyResult: result
84
+ };
85
+ }
86
+ const matchedAction = result.matchedActions[0];
87
+ if (!matchedAction) {
88
+ return {
89
+ isApplicable: false,
90
+ applicableProducts: [],
91
+ reason: "No matched action",
92
+ reasonCode: "NO_ACTION",
93
+ strategyResult: result
94
+ };
95
+ }
96
+ const actionDetail = this.parseActionDetail(matchedAction);
97
+ return {
98
+ isApplicable: true,
99
+ actionType: matchedAction.type,
100
+ actionDetail,
101
+ applicableProducts,
102
+ strategyResult: result
103
+ };
104
+ }
105
+ /**
106
+ * 格式化配置
107
+ */
108
+ formatConfig(result, businessData) {
109
+ return { result, businessData };
110
+ }
111
+ // ============================================
112
+ // 私有辅助方法
113
+ // ============================================
114
+ /**
115
+ * 格式化日期时间
116
+ */
117
+ formatDateTime(date) {
118
+ const year = date.getFullYear();
119
+ const month = String(date.getMonth() + 1).padStart(2, "0");
120
+ const day = String(date.getDate()).padStart(2, "0");
121
+ const hours = String(date.getHours()).padStart(2, "0");
122
+ const minutes = String(date.getMinutes()).padStart(2, "0");
123
+ const seconds = String(date.getSeconds()).padStart(2, "0");
124
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
125
+ }
126
+ /**
127
+ * 解析 Action 详情
128
+ *
129
+ * 将 matchedAction 转换为更易用的结构
130
+ */
131
+ parseActionDetail(action) {
132
+ switch (action.type) {
133
+ case import_type.PROMOTION_ACTION_TYPES.X_ITEMS_FOR_Y_PRICE:
134
+ return this.parseXItemsForYPriceAction(action);
135
+ case import_type.PROMOTION_ACTION_TYPES.BUY_X_GET_Y_FREE:
136
+ return this.parseBuyXGetYFreeAction(action);
137
+ default:
138
+ return void 0;
139
+ }
140
+ }
141
+ /**
142
+ * 解析 X件Y元 Action
143
+ */
144
+ parseXItemsForYPriceAction(action) {
145
+ const value = action.value || {};
146
+ const config = action.config || {};
147
+ return {
148
+ type: import_type.PROMOTION_ACTION_TYPES.X_ITEMS_FOR_Y_PRICE,
149
+ x: value.x || 2,
150
+ price: value.price || 0,
151
+ allowCrossProduct: config.allowCrossProduct ?? true,
152
+ cumulative: config.cumulative ?? true
153
+ };
154
+ }
155
+ /**
156
+ * 解析 买X送Y Action
157
+ */
158
+ parseBuyXGetYFreeAction(action) {
159
+ const value = action.value || {};
160
+ const config = action.config || {};
161
+ return {
162
+ type: import_type.PROMOTION_ACTION_TYPES.BUY_X_GET_Y_FREE,
163
+ buyQuantity: value.buyQuantity || 1,
164
+ freeQuantity: value.freeQuantity || 1,
165
+ giftSelectionMode: config.giftSelectionMode || "user_select",
166
+ cumulative: config.cumulative ?? true,
167
+ giftProducts: config.giftProducts || []
168
+ };
169
+ }
170
+ /**
171
+ * 获取适用的商品列表
172
+ *
173
+ * 从购物车商品中筛选出符合策略条件的商品
174
+ */
175
+ getApplicableProducts(result, businessData) {
176
+ const { products } = businessData;
177
+ const productMatchRule = this.findProductMatchRule(result.config);
178
+ if (!productMatchRule) {
179
+ return products;
180
+ }
181
+ const configProducts = productMatchRule.value;
182
+ return products.filter(
183
+ (product) => this.isProductMatch(product, configProducts)
184
+ );
185
+ }
186
+ /**
187
+ * 查找商品匹配规则
188
+ */
189
+ findProductMatchRule(config) {
190
+ var _a;
191
+ if (!((_a = config == null ? void 0 : config.conditions) == null ? void 0 : _a.rules)) {
192
+ return null;
193
+ }
194
+ return config.conditions.rules.find(
195
+ (rule) => rule.field === "productIdAndVariantId" && (rule.operator === "product_match" || rule.operator === "object_in")
196
+ );
197
+ }
198
+ /**
199
+ * 检查商品是否匹配
200
+ */
201
+ isProductMatch(product, configProducts) {
202
+ return configProducts.some((config) => {
203
+ if (config.product_id !== product.product_id) {
204
+ return false;
205
+ }
206
+ if (config.product_variant_id === 0) {
207
+ return true;
208
+ }
209
+ return config.product_variant_id === product.product_variant_id;
210
+ });
211
+ }
212
+ };
213
+ var adapter_default = PromotionAdapter;
214
+ // Annotate the CommonJS export names for ESM import in node:
215
+ 0 && (module.exports = {
216
+ PromotionAdapter
217
+ });