@pisell/pisellos 2.3.30 → 2.3.31

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 (69) hide show
  1. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
  2. package/dist/model/strategy/adapter/dataVariant/adapter.js +167 -0
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
  4. package/dist/model/strategy/adapter/dataVariant/evaluator.js +780 -0
  5. package/dist/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  6. package/dist/model/strategy/adapter/dataVariant/examples.js +277 -0
  7. package/dist/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  8. package/dist/model/strategy/adapter/dataVariant/index.js +4 -0
  9. package/dist/model/strategy/adapter/dataVariant/type.d.ts +148 -0
  10. package/dist/model/strategy/adapter/dataVariant/type.js +54 -0
  11. package/dist/model/strategy/adapter/index.d.ts +4 -0
  12. package/dist/model/strategy/adapter/index.js +5 -1
  13. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  14. package/dist/modules/Discount/index.d.ts +5 -2
  15. package/dist/modules/Discount/index.js +30 -7
  16. package/dist/modules/Discount/types.d.ts +4 -0
  17. package/dist/modules/Order/index.d.ts +2 -1
  18. package/dist/modules/Order/index.js +25 -11
  19. package/dist/modules/Order/types.d.ts +2 -0
  20. package/dist/modules/Product/index.d.ts +1 -1
  21. package/dist/modules/Product/types.d.ts +22 -0
  22. package/dist/modules/ProductList/index.d.ts +1 -1
  23. package/dist/modules/ProductList/index.js +4 -2
  24. package/dist/modules/ProductList/types.d.ts +2 -0
  25. package/dist/server/index.d.ts +50 -0
  26. package/dist/server/index.js +1095 -849
  27. package/dist/server/modules/products/index.d.ts +26 -7
  28. package/dist/server/modules/products/index.js +167 -76
  29. package/dist/server/modules/products/types.d.ts +14 -0
  30. package/dist/solution/BaseSales/index.d.ts +2 -0
  31. package/dist/solution/BaseSales/index.js +23 -13
  32. package/dist/solution/BookingByStep/index.d.ts +1 -1
  33. package/dist/solution/BookingTicket/types.d.ts +2 -0
  34. package/dist/solution/ShopDiscount/index.js +15 -14
  35. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
  36. package/lib/model/strategy/adapter/dataVariant/adapter.js +149 -0
  37. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
  38. package/lib/model/strategy/adapter/dataVariant/evaluator.js +583 -0
  39. package/lib/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  40. package/lib/model/strategy/adapter/dataVariant/examples.js +293 -0
  41. package/lib/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  42. package/lib/model/strategy/adapter/dataVariant/index.js +38 -0
  43. package/lib/model/strategy/adapter/dataVariant/type.d.ts +148 -0
  44. package/lib/model/strategy/adapter/dataVariant/type.js +31 -0
  45. package/lib/model/strategy/adapter/index.d.ts +4 -0
  46. package/lib/model/strategy/adapter/index.js +13 -2
  47. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  48. package/lib/modules/Discount/index.d.ts +5 -2
  49. package/lib/modules/Discount/index.js +23 -3
  50. package/lib/modules/Discount/types.d.ts +4 -0
  51. package/lib/modules/Order/index.d.ts +2 -1
  52. package/lib/modules/Order/index.js +13 -1
  53. package/lib/modules/Order/types.d.ts +2 -0
  54. package/lib/modules/Product/index.d.ts +1 -1
  55. package/lib/modules/Product/types.d.ts +22 -0
  56. package/lib/modules/ProductList/index.d.ts +1 -1
  57. package/lib/modules/ProductList/index.js +4 -2
  58. package/lib/modules/ProductList/types.d.ts +2 -0
  59. package/lib/server/index.d.ts +50 -0
  60. package/lib/server/index.js +206 -29
  61. package/lib/server/modules/products/index.d.ts +26 -7
  62. package/lib/server/modules/products/index.js +114 -35
  63. package/lib/server/modules/products/types.d.ts +14 -0
  64. package/lib/solution/BaseSales/index.d.ts +2 -0
  65. package/lib/solution/BaseSales/index.js +12 -3
  66. package/lib/solution/BookingByStep/index.d.ts +1 -1
  67. package/lib/solution/BookingTicket/types.d.ts +2 -0
  68. package/lib/solution/ShopDiscount/index.js +2 -1
  69. package/package.json +1 -1
@@ -0,0 +1,780 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
5
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
6
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
7
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
8
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
9
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
13
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
14
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
15
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
17
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
18
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
20
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
21
+ import { StrategyEngine } from "../../engine";
22
+ import { getDateIsInSchedule } from "../../../../modules/Schedule/getDateIsInSchedule";
23
+ import { DataVariantAdapter } from "./adapter";
24
+ /**
25
+ * Data Variant 评估器。
26
+ *
27
+ * 当前阶段只提供策略模型能力和示例验证,不接入 ProductList 业务链路。
28
+ */
29
+ export var DataVariantEvaluator = /*#__PURE__*/function () {
30
+ function DataVariantEvaluator() {
31
+ _classCallCheck(this, DataVariantEvaluator);
32
+ _defineProperty(this, "adapter", void 0);
33
+ _defineProperty(this, "strategyConfigs", []);
34
+ this.adapter = new DataVariantAdapter();
35
+ }
36
+
37
+ /**
38
+ * 设置策略配置列表,仅保留 metadata.type === 'data_variant' 的策略。
39
+ */
40
+ _createClass(DataVariantEvaluator, [{
41
+ key: "setStrategyConfigs",
42
+ value: function setStrategyConfigs(configs) {
43
+ this.strategyConfigs = this.normalizeStrategyConfigs(configs);
44
+ }
45
+ }, {
46
+ key: "getStrategyConfigs",
47
+ value: function getStrategyConfigs() {
48
+ return this.strategyConfigs;
49
+ }
50
+
51
+ /**
52
+ * 批量解析商品 Data Variant。
53
+ *
54
+ * 先执行全局预计算,再只针对商品自身 data_variants 引用到的规则做商品级判断。
55
+ */
56
+ }, {
57
+ key: "resolveProducts",
58
+ value: function resolveProducts(businessData) {
59
+ var _this = this;
60
+ var strategyConfigs = businessData.strategyConfigs ? this.normalizeStrategyConfigs(businessData.strategyConfigs) : this.strategyConfigs;
61
+ var menuScopeMap = this.buildMenuScopeMap(businessData.menuList || []);
62
+ var scheduleTimePoints = this.buildScheduleTimePoints(strategyConfigs, businessData.scheduleList || []);
63
+ var _this$buildGlobalEffe = this.buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap),
64
+ globalEffectiveRuleMap = _this$buildGlobalEffe.globalEffectiveRuleMap,
65
+ rawResults = _this$buildGlobalEffe.rawResults;
66
+ var products = businessData.products.map(function (product) {
67
+ var resolvedProduct = _this.resolveProduct(product, businessData, globalEffectiveRuleMap, menuScopeMap);
68
+ // 套餐子商品也可能携带 data_variants,需在同一策略上下文内继续评估并写回 bundle_item。
69
+ return _this.resolveProductBundleItems(resolvedProduct, businessData, globalEffectiveRuleMap, menuScopeMap);
70
+ });
71
+ return {
72
+ products: products,
73
+ globalEffectiveRuleMap: globalEffectiveRuleMap,
74
+ menuScopeMap: menuScopeMap,
75
+ scheduleTimePoints: scheduleTimePoints,
76
+ rawResults: rawResults
77
+ };
78
+ }
79
+
80
+ /**
81
+ * 根据 operator/field 判断条件是否依赖当前商品。
82
+ */
83
+ }, {
84
+ key: "getConditionScope",
85
+ value: function getConditionScope(rule) {
86
+ if (rule.operator === 'schedule_match') return 'global';
87
+ if (rule.operator === 'menu_match') return 'product';
88
+ if (rule.operator === 'product_match') return 'product';
89
+ if (rule.field === 'product' || rule.field === 'productIdAndVariantId') {
90
+ return 'product';
91
+ }
92
+ return 'global';
93
+ }
94
+
95
+ /**
96
+ * 将餐牌 partyroom_package 预构建为 Map/Set 索引。
97
+ */
98
+ }, {
99
+ key: "buildMenuScopeMap",
100
+ value: function buildMenuScopeMap(menuList) {
101
+ var map = new Map();
102
+ var _iterator = _createForOfIteratorHelper(menuList),
103
+ _step;
104
+ try {
105
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
106
+ var menu = _step.value;
107
+ if (menu !== null && menu !== void 0 && menu.status && menu.status !== 'valid') continue;
108
+ var menuId = this.toNumber(menu === null || menu === void 0 ? void 0 : menu.form_record_id);
109
+ if (!menuId) continue;
110
+ var scope = {
111
+ isAllProducts: false,
112
+ collectionIds: new Set(),
113
+ productKeys: new Set(),
114
+ productAllVariantIds: new Set()
115
+ };
116
+ var packageConfig = menu.partyroom_package;
117
+ var products = Array.isArray(packageConfig === null || packageConfig === void 0 ? void 0 : packageConfig.products) ? packageConfig.products : [];
118
+ if ((packageConfig === null || packageConfig === void 0 ? void 0 : packageConfig.type) === 'product_all') {
119
+ scope.isAllProducts = true;
120
+ } else if ((packageConfig === null || packageConfig === void 0 ? void 0 : packageConfig.type) === 'product_collection') {
121
+ var _iterator2 = _createForOfIteratorHelper(products),
122
+ _step2;
123
+ try {
124
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
125
+ var item = _step2.value;
126
+ var collectionId = this.toNumber(item.product_collection_id);
127
+ if (collectionId) {
128
+ scope.collectionIds.add(collectionId);
129
+ }
130
+ }
131
+ } catch (err) {
132
+ _iterator2.e(err);
133
+ } finally {
134
+ _iterator2.f();
135
+ }
136
+ } else if ((packageConfig === null || packageConfig === void 0 ? void 0 : packageConfig.type) === 'products') {
137
+ var _iterator3 = _createForOfIteratorHelper(products),
138
+ _step3;
139
+ try {
140
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
141
+ var _item = _step3.value;
142
+ var productId = this.toNumber(_item.product_id);
143
+ var variantId = this.toNumber(_item.product_variant_id);
144
+ if (!productId) continue;
145
+ if (variantId === 0) {
146
+ scope.productAllVariantIds.add(productId);
147
+ } else {
148
+ scope.productKeys.add(this.buildProductKey(productId, variantId));
149
+ }
150
+ }
151
+ } catch (err) {
152
+ _iterator3.e(err);
153
+ } finally {
154
+ _iterator3.f();
155
+ }
156
+ }
157
+ map.set(menuId, scope);
158
+ }
159
+ } catch (err) {
160
+ _iterator.e(err);
161
+ } finally {
162
+ _iterator.f();
163
+ }
164
+ return map;
165
+ }
166
+
167
+ /**
168
+ * 从当前策略中所有 schedule_match.value 绑定的 schedule_id 提取时间点。
169
+ *
170
+ * 这里不依赖餐牌,只读取策略配置和调用方传入的 scheduleList。
171
+ */
172
+ }, {
173
+ key: "buildScheduleTimePoints",
174
+ value: function buildScheduleTimePoints(strategyConfigs, scheduleList) {
175
+ var scheduleIds = this.collectScheduleIdsFromStrategies(strategyConfigs);
176
+ if (!scheduleIds.length || !scheduleList.length) return [];
177
+ var scheduleIdSet = new Set(scheduleIds);
178
+ var matchedSchedules = scheduleList.filter(function (schedule) {
179
+ return scheduleIdSet.has(Number(schedule.id));
180
+ });
181
+ return this.extractTimePointsFromSchedules(matchedSchedules);
182
+ }
183
+ }, {
184
+ key: "buildGlobalEffectiveRuleMap",
185
+ value: function buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap) {
186
+ var globalEffectiveRuleMap = new Map();
187
+ var rawResults = [];
188
+ var engine = this.createEngine(businessData, menuScopeMap);
189
+ var context = this.adapter.prepareGlobalContext(businessData);
190
+ var _iterator4 = _createForOfIteratorHelper(strategyConfigs),
191
+ _step4;
192
+ try {
193
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
194
+ var config = _step4.value;
195
+ if (!this.isStrategyActive(config)) continue;
196
+ var _this$splitStrategyCo = this.splitStrategyConfig(config),
197
+ globalConfig = _this$splitStrategyCo.globalConfig,
198
+ productRules = _this$splitStrategyCo.productRules;
199
+ var result = engine.evaluate(globalConfig, context);
200
+ rawResults.push(result);
201
+ if (!result.applicable) continue;
202
+ globalEffectiveRuleMap.set(String(config.metadata.id), {
203
+ ruleId: String(config.metadata.id),
204
+ priority: this.getStrategyPriority(config),
205
+ strategyConfig: config,
206
+ productRules: productRules,
207
+ globalResult: result
208
+ });
209
+ }
210
+ } catch (err) {
211
+ _iterator4.e(err);
212
+ } finally {
213
+ _iterator4.f();
214
+ }
215
+ return {
216
+ globalEffectiveRuleMap: globalEffectiveRuleMap,
217
+ rawResults: rawResults
218
+ };
219
+ }
220
+ }, {
221
+ key: "resolveProduct",
222
+ value: function resolveProduct(product, businessData, globalEffectiveRuleMap, menuScopeMap) {
223
+ var dataVariants = this.getProductDataVariants(product);
224
+ if (!dataVariants.length) return product;
225
+ var matchedVariants = [];
226
+ var _iterator5 = _createForOfIteratorHelper(dataVariants),
227
+ _step5;
228
+ try {
229
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
230
+ var variant = _step5.value;
231
+ var rule = globalEffectiveRuleMap.get(String(variant.data_variant_rule_id));
232
+ if (!rule) continue;
233
+ if (!this.evaluateProductRules(rule, product, businessData, menuScopeMap)) {
234
+ continue;
235
+ }
236
+ matchedVariants.push({
237
+ ruleId: rule.ruleId,
238
+ priority: rule.priority,
239
+ data: variant.data || {},
240
+ variant: variant
241
+ });
242
+ }
243
+ } catch (err) {
244
+ _iterator5.e(err);
245
+ } finally {
246
+ _iterator5.f();
247
+ }
248
+ if (!matchedVariants.length) return product;
249
+ return this.mergeMatchedVariants(product, matchedVariants);
250
+ }
251
+
252
+ /**
253
+ * 解析套餐子商品上的 Data Variant 覆盖。
254
+ *
255
+ * bundle_item 以 bundle_product_id / bundle_variant_id 作为商品身份参与 product_match 等条件判断。
256
+ */
257
+ }, {
258
+ key: "resolveProductBundleItems",
259
+ value: function resolveProductBundleItems(product, businessData, globalEffectiveRuleMap, menuScopeMap) {
260
+ var _this2 = this;
261
+ var bundleGroups = product.bundle_group;
262
+ if (!Array.isArray(bundleGroups) || bundleGroups.length === 0) {
263
+ return product;
264
+ }
265
+ var resolvedGroups = bundleGroups.map(function (group) {
266
+ var bundleItems = group === null || group === void 0 ? void 0 : group.bundle_item;
267
+ if (!Array.isArray(bundleItems) || bundleItems.length === 0) {
268
+ return group;
269
+ }
270
+ return _objectSpread(_objectSpread({}, group), {}, {
271
+ bundle_item: bundleItems.map(function (item) {
272
+ return _this2.resolveBundleItem(item, businessData, globalEffectiveRuleMap, menuScopeMap);
273
+ })
274
+ });
275
+ });
276
+ return _objectSpread(_objectSpread({}, product), {}, {
277
+ bundle_group: resolvedGroups
278
+ });
279
+ }
280
+
281
+ /**
282
+ * 将 bundle_item 转为 DataVariantProduct 并评估 data_variants。
283
+ */
284
+ }, {
285
+ key: "resolveBundleItem",
286
+ value: function resolveBundleItem(item, businessData, globalEffectiveRuleMap, menuScopeMap) {
287
+ var bundleProduct = this.toBundleItemDataVariantProduct(item);
288
+ if (!this.getProductDataVariants(bundleProduct).length) {
289
+ return item;
290
+ }
291
+ var resolvedItem = this.resolveProduct(bundleProduct, businessData, globalEffectiveRuleMap, menuScopeMap);
292
+ return this.mergeBundleItemResolvedData(item, resolvedItem);
293
+ }
294
+
295
+ /**
296
+ * bundle_item 的商品身份映射:bundle_product_id + bundle_variant_id。
297
+ */
298
+ }, {
299
+ key: "toBundleItemDataVariantProduct",
300
+ value: function toBundleItemDataVariantProduct(item) {
301
+ var _item$bundle_product_, _ref, _ref2, _item$bundle_variant_;
302
+ var productId = (_item$bundle_product_ = item.bundle_product_id) !== null && _item$bundle_product_ !== void 0 ? _item$bundle_product_ : item.product_id;
303
+ var variantId = (_ref = (_ref2 = (_item$bundle_variant_ = item.bundle_variant_id) !== null && _item$bundle_variant_ !== void 0 ? _item$bundle_variant_ : item.variant_id) !== null && _ref2 !== void 0 ? _ref2 : item.product_variant_id) !== null && _ref !== void 0 ? _ref : 0;
304
+ return {
305
+ id: productId,
306
+ product_id: productId,
307
+ product_variant_id: variantId,
308
+ variant_id: variantId,
309
+ collection: item.collection,
310
+ data_variants: item.data_variants
311
+ };
312
+ }
313
+
314
+ /**
315
+ * 仅回写命中的字段,避免污染 bundle_item 的结构字段。
316
+ */
317
+ }, {
318
+ key: "mergeBundleItemResolvedData",
319
+ value: function mergeBundleItemResolvedData(originalItem, resolvedItem) {
320
+ var _appliedInfo$appliedF;
321
+ var appliedInfo = resolvedItem._dataVariant;
322
+ if (!(appliedInfo !== null && appliedInfo !== void 0 && (_appliedInfo$appliedF = appliedInfo.appliedFields) !== null && _appliedInfo$appliedF !== void 0 && _appliedInfo$appliedF.length)) {
323
+ return originalItem;
324
+ }
325
+ var result = _objectSpread({}, originalItem);
326
+ var _iterator6 = _createForOfIteratorHelper(appliedInfo.appliedFields),
327
+ _step6;
328
+ try {
329
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
330
+ var field = _step6.value;
331
+ if (resolvedItem[field] !== undefined) {
332
+ result[field] = resolvedItem[field];
333
+ }
334
+ }
335
+ } catch (err) {
336
+ _iterator6.e(err);
337
+ } finally {
338
+ _iterator6.f();
339
+ }
340
+ result._dataVariant = appliedInfo;
341
+ return result;
342
+ }
343
+ }, {
344
+ key: "evaluateProductRules",
345
+ value: function evaluateProductRules(rule, product, businessData, menuScopeMap) {
346
+ if (!rule.productRules.length) return true;
347
+ var engine = this.createEngine(businessData, menuScopeMap);
348
+ var context = this.adapter.prepareProductContext(businessData, product);
349
+ var productOnlyConfig = _objectSpread(_objectSpread({}, rule.strategyConfig), {}, {
350
+ conditions: {
351
+ operator: 'and',
352
+ rules: rule.productRules,
353
+ actionIds: rule.strategyConfig.conditions.actionIds || []
354
+ }
355
+ });
356
+ return engine.evaluate(productOnlyConfig, context).applicable;
357
+ }
358
+
359
+ /**
360
+ * 拆分策略条件。
361
+ *
362
+ * 当前 MVP 支持顶层 and 原子条件拆分;复杂条件保守地放到商品级完整判断。
363
+ */
364
+ }, {
365
+ key: "splitStrategyConfig",
366
+ value: function splitStrategyConfig(config) {
367
+ var conditions = config.conditions;
368
+ var globalRules = [];
369
+ var productRules = [];
370
+ if (conditions.operator !== 'and') {
371
+ return {
372
+ globalConfig: _objectSpread(_objectSpread({}, config), {}, {
373
+ conditions: this.createAlwaysTrueConditions(conditions.actionIds)
374
+ }),
375
+ productRules: this.flattenConditionRules(conditions)
376
+ };
377
+ }
378
+ var _iterator7 = _createForOfIteratorHelper(conditions.rules),
379
+ _step7;
380
+ try {
381
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
382
+ var rule = _step7.value;
383
+ if (this.isConditionGroup(rule)) {
384
+ productRules.push.apply(productRules, _toConsumableArray(this.flattenConditionRules(rule)));
385
+ continue;
386
+ }
387
+ if (this.getConditionScope(rule) === 'product') {
388
+ productRules.push(rule);
389
+ } else {
390
+ globalRules.push(rule);
391
+ }
392
+ }
393
+ } catch (err) {
394
+ _iterator7.e(err);
395
+ } finally {
396
+ _iterator7.f();
397
+ }
398
+ return {
399
+ globalConfig: _objectSpread(_objectSpread({}, config), {}, {
400
+ conditions: {
401
+ operator: 'and',
402
+ rules: globalRules,
403
+ actionIds: conditions.actionIds || []
404
+ }
405
+ }),
406
+ productRules: productRules
407
+ };
408
+ }
409
+ }, {
410
+ key: "createEngine",
411
+ value: function createEngine(businessData, menuScopeMap) {
412
+ var _this3 = this;
413
+ var operatorHandlers = {
414
+ schedule_match: function schedule_match(fieldValue, compareValue) {
415
+ return _this3.evaluateScheduleMatch(fieldValue, compareValue, businessData.scheduleList || []);
416
+ },
417
+ menu_match: function menu_match(fieldValue, compareValue) {
418
+ return _this3.evaluateMenuMatch(fieldValue, compareValue, menuScopeMap);
419
+ },
420
+ array_intersects: function array_intersects(fieldValue, compareValue) {
421
+ return _this3.evaluateArrayIntersects(fieldValue, compareValue);
422
+ }
423
+ };
424
+ return new StrategyEngine({
425
+ debug: false,
426
+ enableTrace: false,
427
+ operatorHandlers: operatorHandlers
428
+ });
429
+ }
430
+ }, {
431
+ key: "evaluateScheduleMatch",
432
+ value: function evaluateScheduleMatch(fieldValue, compareValue, scheduleList) {
433
+ var scheduleDateTime = String(fieldValue || '');
434
+ var scheduleIds = this.normalizeNumberArray(compareValue);
435
+ if (!scheduleIds.length) return true;
436
+ if (!scheduleDateTime || !(scheduleList !== null && scheduleList !== void 0 && scheduleList.length)) return false;
437
+ var matchedSchedules = scheduleList.filter(function (schedule) {
438
+ return scheduleIds.includes(Number(schedule.id));
439
+ });
440
+ return getDateIsInSchedule(scheduleDateTime, matchedSchedules);
441
+ }
442
+ }, {
443
+ key: "evaluateMenuMatch",
444
+ value: function evaluateMenuMatch(fieldValue, compareValue, menuScopeMap) {
445
+ var menuIds = this.normalizeNumberArray(compareValue);
446
+ if (!menuIds.length) return true;
447
+ var _iterator8 = _createForOfIteratorHelper(menuIds),
448
+ _step8;
449
+ try {
450
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
451
+ var menuId = _step8.value;
452
+ var scope = menuScopeMap.get(menuId);
453
+ if (!scope) continue;
454
+ if (this.isProductInMenuScope(fieldValue, scope)) return true;
455
+ }
456
+ } catch (err) {
457
+ _iterator8.e(err);
458
+ } finally {
459
+ _iterator8.f();
460
+ }
461
+ return false;
462
+ }
463
+ }, {
464
+ key: "evaluateArrayIntersects",
465
+ value: function evaluateArrayIntersects(fieldValue, compareValue) {
466
+ var fieldValues = this.normalizeComparableArray(fieldValue);
467
+ var compareValues = this.normalizeComparableArray(compareValue);
468
+ if (!fieldValues.length || !compareValues.length) return false;
469
+ var compareSet = new Set(compareValues);
470
+ return fieldValues.some(function (item) {
471
+ return compareSet.has(item);
472
+ });
473
+ }
474
+ }, {
475
+ key: "collectScheduleIdsFromStrategies",
476
+ value: function collectScheduleIdsFromStrategies(strategyConfigs) {
477
+ var scheduleIds = new Set();
478
+ var _iterator9 = _createForOfIteratorHelper(strategyConfigs),
479
+ _step9;
480
+ try {
481
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
482
+ var config = _step9.value;
483
+ if (!this.isStrategyActive(config)) continue;
484
+ var rules = this.flattenConditionRules(config.conditions);
485
+ var _iterator10 = _createForOfIteratorHelper(rules),
486
+ _step10;
487
+ try {
488
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
489
+ var rule = _step10.value;
490
+ if (rule.operator !== 'schedule_match') continue;
491
+ var _iterator11 = _createForOfIteratorHelper(this.normalizeNumberArray(rule.value)),
492
+ _step11;
493
+ try {
494
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
495
+ var scheduleId = _step11.value;
496
+ scheduleIds.add(scheduleId);
497
+ }
498
+ } catch (err) {
499
+ _iterator11.e(err);
500
+ } finally {
501
+ _iterator11.f();
502
+ }
503
+ }
504
+ } catch (err) {
505
+ _iterator10.e(err);
506
+ } finally {
507
+ _iterator10.f();
508
+ }
509
+ }
510
+ } catch (err) {
511
+ _iterator9.e(err);
512
+ } finally {
513
+ _iterator9.f();
514
+ }
515
+ return Array.from(scheduleIds);
516
+ }
517
+ }, {
518
+ key: "extractTimePointsFromSchedules",
519
+ value: function extractTimePointsFromSchedules(schedules) {
520
+ var _this4 = this;
521
+ var timePoints = new Set();
522
+ var _iterator12 = _createForOfIteratorHelper(schedules),
523
+ _step12;
524
+ try {
525
+ for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
526
+ var schedule = _step12.value;
527
+ switch (schedule.type) {
528
+ case 'standard':
529
+ {
530
+ this.addDateTimePoint(timePoints, schedule.start_time);
531
+ this.addDateTimePoint(timePoints, schedule.end_time);
532
+ break;
533
+ }
534
+ case 'time-slots':
535
+ {
536
+ var slots = Array.isArray(schedule.time_slot) ? schedule.time_slot : [];
537
+ var _iterator13 = _createForOfIteratorHelper(slots),
538
+ _step13;
539
+ try {
540
+ for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
541
+ var slot = _step13.value;
542
+ this.addRawTimePoint(timePoints, slot.start_time);
543
+ this.addRawTimePoint(timePoints, slot.end_time);
544
+ }
545
+ } catch (err) {
546
+ _iterator13.e(err);
547
+ } finally {
548
+ _iterator13.f();
549
+ }
550
+ break;
551
+ }
552
+ case 'designation':
553
+ {
554
+ var designations = Array.isArray(schedule.designation) ? schedule.designation : schedule.designation ? [schedule.designation] : [];
555
+ var _iterator14 = _createForOfIteratorHelper(designations),
556
+ _step14;
557
+ try {
558
+ for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
559
+ var designation = _step14.value;
560
+ this.addRawTimePoint(timePoints, designation.start_time);
561
+ this.addRawTimePoint(timePoints, designation.end_time);
562
+ }
563
+ } catch (err) {
564
+ _iterator14.e(err);
565
+ } finally {
566
+ _iterator14.f();
567
+ }
568
+ break;
569
+ }
570
+ default:
571
+ break;
572
+ }
573
+ }
574
+ } catch (err) {
575
+ _iterator12.e(err);
576
+ } finally {
577
+ _iterator12.f();
578
+ }
579
+ return Array.from(timePoints).sort(function (a, b) {
580
+ return _this4.timeToMinutes(a) - _this4.timeToMinutes(b);
581
+ });
582
+ }
583
+ }, {
584
+ key: "addDateTimePoint",
585
+ value: function addDateTimePoint(points, value) {
586
+ var time = this.extractTimeFromDateTime(value);
587
+ if (time) points.add(time);
588
+ }
589
+ }, {
590
+ key: "addRawTimePoint",
591
+ value: function addRawTimePoint(points, value) {
592
+ var time = this.normalizeTime(value);
593
+ if (time) points.add(time);
594
+ }
595
+ }, {
596
+ key: "extractTimeFromDateTime",
597
+ value: function extractTimeFromDateTime(value) {
598
+ if (!value) return null;
599
+ var match = value.match(/(\d{1,2}):(\d{2})/);
600
+ if (!match) return null;
601
+ return "".concat(match[1].padStart(2, '0'), ":").concat(match[2]);
602
+ }
603
+ }, {
604
+ key: "normalizeTime",
605
+ value: function normalizeTime(value) {
606
+ if (!value) return null;
607
+ var match = value.match(/^(\d{1,2}):(\d{2})/);
608
+ if (!match) return null;
609
+ return "".concat(match[1].padStart(2, '0'), ":").concat(match[2]);
610
+ }
611
+ }, {
612
+ key: "timeToMinutes",
613
+ value: function timeToMinutes(value) {
614
+ var _value$split$map = value.split(':').map(function (item) {
615
+ return Number(item);
616
+ }),
617
+ _value$split$map2 = _slicedToArray(_value$split$map, 2),
618
+ hour = _value$split$map2[0],
619
+ minute = _value$split$map2[1];
620
+ if (!Number.isFinite(hour) || !Number.isFinite(minute)) return 0;
621
+ return hour * 60 + minute;
622
+ }
623
+ }, {
624
+ key: "isProductInMenuScope",
625
+ value: function isProductInMenuScope(product, scope) {
626
+ var _product$id,
627
+ _this5 = this;
628
+ if (scope.isAllProducts) return true;
629
+ if (!product || _typeof(product) !== 'object') return false;
630
+ var productId = this.toNumber((_product$id = product.id) !== null && _product$id !== void 0 ? _product$id : product.product_id);
631
+ var variantId = this.toNumber(product.product_variant_id);
632
+ var productKey = this.buildProductKey(productId, variantId);
633
+ var collectionIds = Array.isArray(product.collection_ids) ? product.collection_ids.map(function (id) {
634
+ return _this5.toNumber(id);
635
+ }) : [];
636
+ return collectionIds.some(function (id) {
637
+ return scope.collectionIds.has(id);
638
+ }) || scope.productKeys.has(productKey) || scope.productAllVariantIds.has(productId);
639
+ }
640
+ }, {
641
+ key: "mergeMatchedVariants",
642
+ value: function mergeMatchedVariants(product, matchedVariants) {
643
+ var original = _objectSpread({}, product);
644
+ var sortedVariants = _toConsumableArray(matchedVariants).sort(function (a, b) {
645
+ if (a.priority !== b.priority) return a.priority - b.priority;
646
+ return Number(a.ruleId) - Number(b.ruleId);
647
+ });
648
+ var result = _objectSpread({}, product);
649
+ var appliedRuleIds = [];
650
+ var appliedFields = new Set();
651
+ var _iterator15 = _createForOfIteratorHelper(sortedVariants),
652
+ _step15;
653
+ try {
654
+ for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
655
+ var matched = _step15.value;
656
+ for (var _i = 0, _Object$entries = Object.entries(matched.data); _i < _Object$entries.length; _i++) {
657
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
658
+ key = _Object$entries$_i[0],
659
+ value = _Object$entries$_i[1];
660
+ if (value === undefined) continue;
661
+ result[key] = value;
662
+ appliedFields.add(key);
663
+ }
664
+ appliedRuleIds.push(matched.ruleId);
665
+ }
666
+ } catch (err) {
667
+ _iterator15.e(err);
668
+ } finally {
669
+ _iterator15.f();
670
+ }
671
+ result._dataVariant = {
672
+ appliedRuleIds: appliedRuleIds,
673
+ appliedFields: Array.from(appliedFields),
674
+ original: original
675
+ };
676
+ return result;
677
+ }
678
+ }, {
679
+ key: "getProductDataVariants",
680
+ value: function getProductDataVariants(product) {
681
+ return Array.isArray(product.data_variants) ? product.data_variants : [];
682
+ }
683
+ }, {
684
+ key: "normalizeStrategyConfigs",
685
+ value: function normalizeStrategyConfigs(configs) {
686
+ return configs.filter(function (config) {
687
+ var _config$metadata;
688
+ return (config === null || config === void 0 || (_config$metadata = config.metadata) === null || _config$metadata === void 0 ? void 0 : _config$metadata.type) === 'data_variant';
689
+ });
690
+ }
691
+ }, {
692
+ key: "isStrategyActive",
693
+ value: function isStrategyActive(config) {
694
+ var _config$metadata$cust;
695
+ var status = (_config$metadata$cust = config.metadata.custom) === null || _config$metadata$cust === void 0 ? void 0 : _config$metadata$cust.status;
696
+ return !status || status === 'active';
697
+ }
698
+ }, {
699
+ key: "getStrategyPriority",
700
+ value: function getStrategyPriority(config) {
701
+ var _config$metadata$cust2;
702
+ var priority = Number((_config$metadata$cust2 = config.metadata.custom) === null || _config$metadata$cust2 === void 0 ? void 0 : _config$metadata$cust2.priority);
703
+ if (Number.isFinite(priority)) return priority;
704
+ return Math.max.apply(Math, [0].concat(_toConsumableArray(config.actions.map(function (action) {
705
+ return Number(action.priority || 0);
706
+ }))));
707
+ }
708
+ }, {
709
+ key: "createAlwaysTrueConditions",
710
+ value: function createAlwaysTrueConditions(actionIds) {
711
+ return {
712
+ operator: 'and',
713
+ rules: [],
714
+ actionIds: actionIds
715
+ };
716
+ }
717
+ }, {
718
+ key: "flattenConditionRules",
719
+ value: function flattenConditionRules(group) {
720
+ var rules = [];
721
+ var _iterator16 = _createForOfIteratorHelper(group.rules),
722
+ _step16;
723
+ try {
724
+ for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
725
+ var rule = _step16.value;
726
+ if (this.isConditionGroup(rule)) {
727
+ rules.push.apply(rules, _toConsumableArray(this.flattenConditionRules(rule)));
728
+ } else {
729
+ rules.push(rule);
730
+ }
731
+ }
732
+ } catch (err) {
733
+ _iterator16.e(err);
734
+ } finally {
735
+ _iterator16.f();
736
+ }
737
+ return rules;
738
+ }
739
+ }, {
740
+ key: "isConditionGroup",
741
+ value: function isConditionGroup(rule) {
742
+ return 'rules' in rule && Array.isArray(rule.rules);
743
+ }
744
+ }, {
745
+ key: "normalizeNumberArray",
746
+ value: function normalizeNumberArray(value) {
747
+ var _this6 = this;
748
+ if (!Array.isArray(value)) return [];
749
+ return value.map(function (item) {
750
+ return _this6.toNumber(item);
751
+ }).filter(function (item) {
752
+ return item > 0;
753
+ });
754
+ }
755
+ }, {
756
+ key: "normalizeComparableArray",
757
+ value: function normalizeComparableArray(value) {
758
+ var list = Array.isArray(value) ? value : value == null || value === '' ? [] : [value];
759
+ var normalized = list.map(function (item) {
760
+ if (item == null || item === '') return '';
761
+ var parsed = Number(item);
762
+ return Number.isFinite(parsed) ? String(parsed) : String(item).trim();
763
+ }).filter(Boolean);
764
+ return Array.from(new Set(normalized));
765
+ }
766
+ }, {
767
+ key: "buildProductKey",
768
+ value: function buildProductKey(productId, variantId) {
769
+ return "".concat(productId, ":").concat(variantId);
770
+ }
771
+ }, {
772
+ key: "toNumber",
773
+ value: function toNumber(value) {
774
+ var parsed = Number(value);
775
+ return Number.isFinite(parsed) ? parsed : 0;
776
+ }
777
+ }]);
778
+ return DataVariantEvaluator;
779
+ }();
780
+ export default DataVariantEvaluator;