@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
@@ -0,0 +1,711 @@
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 _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; } } }; }
3
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
4
+ 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."); }
5
+ 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); }
6
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
7
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
8
+ 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; }
9
+ 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; }
10
+ 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; }
11
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12
+ 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); } }
13
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
14
+ 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; }
15
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
16
+ 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); }
17
+ import { SUCCESS_CODES, NOT_APPLICABLE_CODES, ERROR_CODES } from "./type";
18
+
19
+ /**
20
+ * 策略模型 - 核心实现
21
+ *
22
+ * 完全业务无关的通用策略引擎
23
+ * 支持条件评估、动作匹配、结果返回
24
+ */
25
+
26
+ // ============================================
27
+ // 策略引擎实现
28
+ // ============================================
29
+
30
+ /**
31
+ * 策略引擎
32
+ *
33
+ * 核心职责:
34
+ * 1. 递归评估条件组
35
+ * 2. 收集满足条件的 actionIds
36
+ * 3. 根据 actionIds 获取 ActionEffect 对象
37
+ * 4. 按 priority 排序返回
38
+ */
39
+ export var StrategyEngine = /*#__PURE__*/function () {
40
+ function StrategyEngine() {
41
+ var _options$debug, _options$enableTrace, _options$operatorHand, _options$errorHandler;
42
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
43
+ _classCallCheck(this, StrategyEngine);
44
+ _defineProperty(this, "options", void 0);
45
+ _defineProperty(this, "operatorHandlers", void 0);
46
+ this.options = {
47
+ debug: (_options$debug = options.debug) !== null && _options$debug !== void 0 ? _options$debug : false,
48
+ enableTrace: (_options$enableTrace = options.enableTrace) !== null && _options$enableTrace !== void 0 ? _options$enableTrace : false,
49
+ operatorHandlers: (_options$operatorHand = options.operatorHandlers) !== null && _options$operatorHand !== void 0 ? _options$operatorHand : {},
50
+ errorHandler: (_options$errorHandler = options.errorHandler) !== null && _options$errorHandler !== void 0 ? _options$errorHandler : function (error) {
51
+ return console.error(error);
52
+ }
53
+ };
54
+
55
+ // 初始化内置运算符处理器
56
+ this.operatorHandlers = new Map(Object.entries(this.options.operatorHandlers));
57
+ this.initializeBuiltInOperators();
58
+ }
59
+
60
+ /**
61
+ * 评估策略
62
+ */
63
+ _createClass(StrategyEngine, [{
64
+ key: "evaluate",
65
+ value: function evaluate(config, context) {
66
+ var startTime = Date.now();
67
+ var trace = {
68
+ steps: [],
69
+ duration: 0,
70
+ errors: []
71
+ };
72
+ try {
73
+ var _evaluationResult$fai;
74
+ // 验证配置
75
+ this.validateConfig(config);
76
+ if (this.options.enableTrace) {
77
+ trace.steps.push({
78
+ step: 'validate_config',
79
+ status: 'success',
80
+ duration: Date.now() - startTime
81
+ });
82
+ }
83
+
84
+ // 递归评估条件组,收集 actionIds
85
+ var evaluateStart = Date.now();
86
+ var evaluationResult = this.evaluateConditionGroup(config.conditions, context);
87
+ if (this.options.enableTrace) {
88
+ trace.steps.push({
89
+ step: 'evaluate_conditions',
90
+ status: 'success',
91
+ duration: Date.now() - evaluateStart,
92
+ details: {
93
+ satisfied: evaluationResult.satisfied,
94
+ collectedActionIds: evaluationResult.actionIds
95
+ }
96
+ });
97
+ }
98
+
99
+ // 根据 actionIds 获取 ActionEffect 对象
100
+ var actionStart = Date.now();
101
+ var matchedActions = this.getActionsByIds(evaluationResult.actionIds, config.actions);
102
+ if (this.options.enableTrace) {
103
+ trace.steps.push({
104
+ step: 'get_actions',
105
+ status: 'success',
106
+ duration: Date.now() - actionStart,
107
+ details: {
108
+ matchedCount: matchedActions.length
109
+ }
110
+ });
111
+ }
112
+
113
+ // 按 priority 排序(降序)
114
+ var sortStart = Date.now();
115
+ var sortedActions = this.sortActionsByPriority(matchedActions);
116
+ if (this.options.enableTrace) {
117
+ trace.steps.push({
118
+ step: 'sort_actions',
119
+ status: 'success',
120
+ duration: Date.now() - sortStart
121
+ });
122
+ }
123
+
124
+ // 构建结果 - applicable 基于条件是否满足,而不是 actionIds 数量
125
+ var applicable = evaluationResult.satisfied;
126
+ var result = {
127
+ success: true,
128
+ applicable: applicable,
129
+ code: applicable ? SUCCESS_CODES.SUCCESS : NOT_APPLICABLE_CODES.CONDITION_NOT_MET,
130
+ message: applicable ? 'Strategy is applicable' : 'Conditions not met',
131
+ matched: _objectSpread({
132
+ conditions: applicable,
133
+ actionIds: evaluationResult.actionIds,
134
+ details: {}
135
+ }, applicable ? {} : {
136
+ failedField: (_evaluationResult$fai = evaluationResult.failedRules[0]) === null || _evaluationResult$fai === void 0 ? void 0 : _evaluationResult$fai.field,
137
+ failedRules: evaluationResult.failedRules
138
+ }),
139
+ matchedActions: sortedActions,
140
+ outputs: {},
141
+ config: config
142
+ };
143
+ trace.duration = Date.now() - startTime;
144
+ if (this.options.enableTrace) {
145
+ result.trace = trace;
146
+ }
147
+ return result;
148
+ } catch (error) {
149
+ var errorMessage = error instanceof Error ? error.message : 'Unknown error';
150
+ if (this.options.enableTrace) {
151
+ var _trace$errors;
152
+ (_trace$errors = trace.errors) === null || _trace$errors === void 0 || _trace$errors.push({
153
+ step: 'evaluation',
154
+ error: errorMessage,
155
+ timestamp: Date.now()
156
+ });
157
+ trace.duration = Date.now() - startTime;
158
+ }
159
+ this.options.errorHandler(error, context);
160
+ return {
161
+ success: false,
162
+ applicable: false,
163
+ code: ERROR_CODES.EVALUATION_ERROR,
164
+ message: errorMessage,
165
+ matched: {
166
+ conditions: false,
167
+ actionIds: [],
168
+ details: {}
169
+ },
170
+ matchedActions: [],
171
+ outputs: {},
172
+ trace: this.options.enableTrace ? trace : undefined,
173
+ config: config
174
+ };
175
+ }
176
+ }
177
+
178
+ /**
179
+ * 递归评估条件组
180
+ *
181
+ * @param group 条件组
182
+ * @param context 运行时上下文
183
+ * @returns 评估结果对象,包含条件是否满足、收集到的 actionIds、以及失败的原子规则信息
184
+ */
185
+ }, {
186
+ key: "evaluateConditionGroup",
187
+ value: function evaluateConditionGroup(group, context) {
188
+ var collectedActionIds = [];
189
+
190
+ // 评估当前层的 operator 和 rules(同时收集失败信息)
191
+ var _this$evaluateGroupLo = this.evaluateGroupLogicDetailed(group, context),
192
+ satisfied = _this$evaluateGroupLo.satisfied,
193
+ failedRules = _this$evaluateGroupLo.failedRules;
194
+ if (satisfied) {
195
+ collectedActionIds.push.apply(collectedActionIds, _toConsumableArray(group.actionIds));
196
+
197
+ // 递归评估嵌套的 ConditionGroup,收集嵌套层的 actionIds
198
+ var _iterator = _createForOfIteratorHelper(group.rules),
199
+ _step;
200
+ try {
201
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
202
+ var rule = _step.value;
203
+ if (this.isConditionGroup(rule)) {
204
+ var nestedResult = this.evaluateConditionGroup(rule, context);
205
+ collectedActionIds.push.apply(collectedActionIds, _toConsumableArray(nestedResult.actionIds));
206
+ }
207
+ }
208
+ } catch (err) {
209
+ _iterator.e(err);
210
+ } finally {
211
+ _iterator.f();
212
+ }
213
+ }
214
+ return {
215
+ satisfied: satisfied,
216
+ actionIds: collectedActionIds,
217
+ failedRules: failedRules
218
+ };
219
+ }
220
+
221
+ /**
222
+ * 评估条件组的逻辑运算(带失败规则收集)
223
+ *
224
+ * 失败规则收集策略:
225
+ * - `and`:返回第一个失败的原子规则(嵌套 group 递归取其首个失败原子规则)
226
+ * - `or`:所有分支失败时,聚合每个分支的失败规则
227
+ * - `not`:被取反规则实际通过时,记录该规则
228
+ */
229
+ }, {
230
+ key: "evaluateGroupLogicDetailed",
231
+ value: function evaluateGroupLogicDetailed(group, context) {
232
+ var operator = group.operator,
233
+ rules = group.rules;
234
+ switch (operator) {
235
+ case 'and':
236
+ {
237
+ var _iterator2 = _createForOfIteratorHelper(rules),
238
+ _step2;
239
+ try {
240
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
241
+ var rule = _step2.value;
242
+ var ruleResult = this.evaluateRuleDetailed(rule, context);
243
+ if (!ruleResult.satisfied) {
244
+ return {
245
+ satisfied: false,
246
+ failedRules: ruleResult.failedRules
247
+ };
248
+ }
249
+ }
250
+ } catch (err) {
251
+ _iterator2.e(err);
252
+ } finally {
253
+ _iterator2.f();
254
+ }
255
+ return {
256
+ satisfied: true,
257
+ failedRules: []
258
+ };
259
+ }
260
+ case 'or':
261
+ {
262
+ var aggregated = [];
263
+ var _iterator3 = _createForOfIteratorHelper(rules),
264
+ _step3;
265
+ try {
266
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
267
+ var _rule = _step3.value;
268
+ var _ruleResult = this.evaluateRuleDetailed(_rule, context);
269
+ if (_ruleResult.satisfied) {
270
+ return {
271
+ satisfied: true,
272
+ failedRules: []
273
+ };
274
+ }
275
+ aggregated.push.apply(aggregated, _toConsumableArray(_ruleResult.failedRules));
276
+ }
277
+ } catch (err) {
278
+ _iterator3.e(err);
279
+ } finally {
280
+ _iterator3.f();
281
+ }
282
+ return {
283
+ satisfied: false,
284
+ failedRules: aggregated
285
+ };
286
+ }
287
+ case 'not':
288
+ {
289
+ if (rules.length === 0) {
290
+ return {
291
+ satisfied: false,
292
+ failedRules: []
293
+ };
294
+ }
295
+ var _ruleResult2 = this.evaluateRuleDetailed(rules[0], context);
296
+ if (_ruleResult2.satisfied) {
297
+ // 被取反规则实际通过,导致 not 失败
298
+ var failed = this.isConditionGroup(rules[0]) ? [] : [this.buildFailedRuleInfo(rules[0], context)];
299
+ return {
300
+ satisfied: false,
301
+ failedRules: failed
302
+ };
303
+ }
304
+ return {
305
+ satisfied: true,
306
+ failedRules: []
307
+ };
308
+ }
309
+ default:
310
+ throw new Error("Unknown operator: ".concat(operator));
311
+ }
312
+ }
313
+
314
+ /**
315
+ * 评估单个规则(带失败规则收集)
316
+ */
317
+ }, {
318
+ key: "evaluateRuleDetailed",
319
+ value: function evaluateRuleDetailed(rule, context) {
320
+ if (this.isConditionGroup(rule)) {
321
+ return this.evaluateGroupLogicDetailed(rule, context);
322
+ }
323
+ var conditionRule = rule;
324
+ var satisfied = this.evaluateAtomicRule(conditionRule, context);
325
+ if (satisfied) {
326
+ return {
327
+ satisfied: true,
328
+ failedRules: []
329
+ };
330
+ }
331
+ return {
332
+ satisfied: false,
333
+ failedRules: [this.buildFailedRuleInfo(conditionRule, context)]
334
+ };
335
+ }
336
+
337
+ /**
338
+ * 评估原子规则(不收集失败信息,仅返回布尔结果)
339
+ */
340
+ }, {
341
+ key: "evaluateAtomicRule",
342
+ value: function evaluateAtomicRule(conditionRule, context) {
343
+ // Code 模式:使用 eval 执行
344
+ if (conditionRule.type === 'code' && conditionRule.code) {
345
+ return this.evaluateCodeCondition(conditionRule.code, context);
346
+ }
347
+
348
+ // Operator 模式:标准运算符判断
349
+ return this.evaluateOperatorCondition(conditionRule, context);
350
+ }
351
+
352
+ /**
353
+ * 构建失败规则信息
354
+ */
355
+ }, {
356
+ key: "buildFailedRuleInfo",
357
+ value: function buildFailedRuleInfo(conditionRule, context) {
358
+ var actualValue = conditionRule.field ? this.getFieldValue(conditionRule.field, context) : undefined;
359
+ return {
360
+ field: conditionRule.field,
361
+ operator: conditionRule.operator,
362
+ value: conditionRule.value,
363
+ actualValue: actualValue
364
+ };
365
+ }
366
+
367
+ /**
368
+ * 评估代码模式条件
369
+ */
370
+ }, {
371
+ key: "evaluateCodeCondition",
372
+ value: function evaluateCodeCondition(code, context) {
373
+ try {
374
+ // 将 context 解构到作用域中,方便代码直接使用
375
+ var entities = context.entities,
376
+ attributes = context.attributes,
377
+ metadata = context.metadata;
378
+
379
+ // 使用 Function 构造器代替 eval,更安全
380
+ var evalFunc = new Function('entities', 'attributes', 'metadata', "return (".concat(code, ")"));
381
+ var result = evalFunc(entities, attributes, metadata);
382
+ return Boolean(result);
383
+ } catch (error) {
384
+ if (this.options.debug) {
385
+ console.error('Code evaluation error:', error);
386
+ }
387
+ return false;
388
+ }
389
+ }
390
+
391
+ /**
392
+ * 评估运算符模式条件
393
+ */
394
+ }, {
395
+ key: "evaluateOperatorCondition",
396
+ value: function evaluateOperatorCondition(rule, context) {
397
+ var field = rule.field,
398
+ operator = rule.operator,
399
+ value = rule.value;
400
+ if (!field || !operator) {
401
+ return false;
402
+ }
403
+
404
+ // 从 context.attributes 中获取字段值
405
+ var fieldValue = this.getFieldValue(field, context);
406
+
407
+ // 使用运算符处理器
408
+ var handler = this.operatorHandlers.get(operator);
409
+ if (handler) {
410
+ return handler(fieldValue, value, rule);
411
+ }
412
+
413
+ // 回退到内置运算符
414
+ return this.evaluateBuiltInOperator(fieldValue, operator, value);
415
+ }
416
+
417
+ /**
418
+ * 获取字段值
419
+ */
420
+ }, {
421
+ key: "getFieldValue",
422
+ value: function getFieldValue(field, context) {
423
+ // 支持点号路径,如 "order.total"
424
+ var path = field.split('.');
425
+ var value = context.attributes;
426
+ var _iterator4 = _createForOfIteratorHelper(path),
427
+ _step4;
428
+ try {
429
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
430
+ var key = _step4.value;
431
+ if (value && _typeof(value) === 'object' && key in value) {
432
+ value = value[key];
433
+ } else {
434
+ return undefined;
435
+ }
436
+ }
437
+ } catch (err) {
438
+ _iterator4.e(err);
439
+ } finally {
440
+ _iterator4.f();
441
+ }
442
+ return value;
443
+ }
444
+
445
+ /**
446
+ * 评估内置运算符
447
+ */
448
+ }, {
449
+ key: "evaluateBuiltInOperator",
450
+ value: function evaluateBuiltInOperator(fieldValue, operator, compareValue) {
451
+ switch (operator) {
452
+ // 比较运算符
453
+ case '=':
454
+ case '==':
455
+ return fieldValue == compareValue;
456
+ case '!=':
457
+ return fieldValue != compareValue;
458
+ case '>':
459
+ return fieldValue > compareValue;
460
+ case '>=':
461
+ return fieldValue >= compareValue;
462
+ case '<':
463
+ return fieldValue < compareValue;
464
+ case '<=':
465
+ return fieldValue <= compareValue;
466
+
467
+ // 集合运算符
468
+ case 'in':
469
+ return Array.isArray(compareValue) && compareValue.includes(fieldValue);
470
+ case 'not_in':
471
+ return Array.isArray(compareValue) && !compareValue.includes(fieldValue);
472
+ case 'contains':
473
+ if (Array.isArray(fieldValue)) {
474
+ return fieldValue.includes(compareValue);
475
+ }
476
+ if (typeof fieldValue === 'string') {
477
+ return fieldValue.includes(compareValue);
478
+ }
479
+ return false;
480
+ case 'not_contains':
481
+ if (Array.isArray(fieldValue)) {
482
+ return !fieldValue.includes(compareValue);
483
+ }
484
+ if (typeof fieldValue === 'string') {
485
+ return !fieldValue.includes(compareValue);
486
+ }
487
+ return true;
488
+
489
+ // 字符串运算符
490
+ case 'starts_with':
491
+ return typeof fieldValue === 'string' && fieldValue.startsWith(compareValue);
492
+ case 'ends_with':
493
+ return typeof fieldValue === 'string' && fieldValue.endsWith(compareValue);
494
+ case 'regex':
495
+ return typeof fieldValue === 'string' && new RegExp(compareValue).test(fieldValue);
496
+
497
+ // 范围运算符
498
+ case 'between':
499
+ if (!Array.isArray(compareValue) || compareValue.length !== 2) return false;
500
+ return fieldValue >= compareValue[0] && fieldValue <= compareValue[1];
501
+
502
+ // 逻辑运算符
503
+ case 'is_null':
504
+ return fieldValue === null || fieldValue === undefined;
505
+ case 'is_not_null':
506
+ return fieldValue !== null && fieldValue !== undefined;
507
+ case 'is_empty':
508
+ if (Array.isArray(fieldValue)) return fieldValue.length === 0;
509
+ if (typeof fieldValue === 'string') return fieldValue.length === 0;
510
+ if (_typeof(fieldValue) === 'object') return Object.keys(fieldValue).length === 0;
511
+ return !fieldValue;
512
+ case 'is_not_empty':
513
+ if (Array.isArray(fieldValue)) return fieldValue.length > 0;
514
+ if (typeof fieldValue === 'string') return fieldValue.length > 0;
515
+ if (_typeof(fieldValue) === 'object') return Object.keys(fieldValue).length > 0;
516
+ return Boolean(fieldValue);
517
+
518
+ // 商品匹配运算符
519
+ case 'product_match':
520
+ return this.evaluateProductMatch(fieldValue, compareValue);
521
+
522
+ // 对象包含运算符(兼容旧配置)
523
+ case 'object_in':
524
+ return this.evaluateProductMatch(fieldValue, compareValue);
525
+ default:
526
+ throw new Error("Unsupported operator: ".concat(operator));
527
+ }
528
+ }
529
+
530
+ /**
531
+ * 根据 actionIds 获取 ActionEffect 对象
532
+ */
533
+ }, {
534
+ key: "getActionsByIds",
535
+ value: function getActionsByIds(actionIds, actions) {
536
+ var matchedActions = [];
537
+ var actionMap = new Map(actions.map(function (action) {
538
+ return [action.id, action];
539
+ }));
540
+ var _iterator5 = _createForOfIteratorHelper(actionIds),
541
+ _step5;
542
+ try {
543
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
544
+ var id = _step5.value;
545
+ var action = actionMap.get(id);
546
+ if (action) {
547
+ matchedActions.push(action);
548
+ } else {
549
+ // 找不到的 ID 记录警告
550
+ if (this.options.debug) {
551
+ console.warn("Action with id \"".concat(id, "\" not found in actions array"));
552
+ }
553
+ }
554
+ }
555
+ } catch (err) {
556
+ _iterator5.e(err);
557
+ } finally {
558
+ _iterator5.f();
559
+ }
560
+ return matchedActions;
561
+ }
562
+
563
+ /**
564
+ * 按 priority 排序(降序)
565
+ */
566
+ }, {
567
+ key: "sortActionsByPriority",
568
+ value: function sortActionsByPriority(actions) {
569
+ return _toConsumableArray(actions).sort(function (a, b) {
570
+ var _a$priority, _b$priority;
571
+ var priorityA = (_a$priority = a.priority) !== null && _a$priority !== void 0 ? _a$priority : 0;
572
+ var priorityB = (_b$priority = b.priority) !== null && _b$priority !== void 0 ? _b$priority : 0;
573
+ return priorityB - priorityA; // 降序
574
+ });
575
+ }
576
+
577
+ /**
578
+ * 判断是否为条件组
579
+ */
580
+ }, {
581
+ key: "isConditionGroup",
582
+ value: function isConditionGroup(rule) {
583
+ return 'operator' in rule && 'rules' in rule && Array.isArray(rule.rules);
584
+ }
585
+
586
+ /**
587
+ * 验证配置
588
+ */
589
+ }, {
590
+ key: "validateConfig",
591
+ value: function validateConfig(config) {
592
+ if (!config) {
593
+ throw new Error('Strategy config is required');
594
+ }
595
+ if (!config.metadata || !config.metadata.id) {
596
+ throw new Error('Strategy metadata.id is required');
597
+ }
598
+ if (!config.conditions) {
599
+ throw new Error('Strategy conditions is required');
600
+ }
601
+ if (!Array.isArray(config.actions)) {
602
+ throw new Error('Strategy actions must be an array');
603
+ }
604
+ }
605
+
606
+ /**
607
+ * 初始化内置运算符处理器
608
+ */
609
+ }, {
610
+ key: "initializeBuiltInOperators",
611
+ value: function initializeBuiltInOperators() {
612
+ // 内置运算符已经在 evaluateBuiltInOperator 中实现
613
+ // 这里可以添加自定义的运算符处理器
614
+ }
615
+
616
+ /**
617
+ * 评估商品匹配运算符
618
+ *
619
+ * 匹配规则:
620
+ * - 首先匹配 product_id
621
+ * - 如果配置的 product_variant_id = 0,只需要 product_id 匹配(表示任意变体)
622
+ * - 如果配置的 product_variant_id != 0,还需要 product_variant_id 精确匹配
623
+ *
624
+ * @param fieldValue 实际商品 { product_id: number, product_variant_id: number }
625
+ * @param configValue 配置的商品列表 Array<{ product_id: number, product_variant_id: number }>
626
+ * @returns 是否匹配
627
+ */
628
+ }, {
629
+ key: "evaluateProductMatch",
630
+ value: function evaluateProductMatch(fieldValue, configValue) {
631
+ var _fieldValue$product_v;
632
+ // 确保 configValue 是数组
633
+ if (!Array.isArray(configValue)) {
634
+ return false;
635
+ }
636
+
637
+ // 确保 fieldValue 是有效的商品对象
638
+ if (!fieldValue || _typeof(fieldValue) !== 'object' || typeof fieldValue.product_id !== 'number') {
639
+ return false;
640
+ }
641
+ var actualProductId = fieldValue.product_id;
642
+ var actualVariantId = (_fieldValue$product_v = fieldValue.product_variant_id) !== null && _fieldValue$product_v !== void 0 ? _fieldValue$product_v : 0;
643
+
644
+ // 遍历配置的商品列表,检查是否有匹配
645
+ return configValue.some(function (item) {
646
+ var _item$product_variant;
647
+ // 验证配置项格式
648
+ if (!item || typeof item.product_id !== 'number') {
649
+ return false;
650
+ }
651
+ var configProductId = item.product_id;
652
+ var configVariantId = (_item$product_variant = item.product_variant_id) !== null && _item$product_variant !== void 0 ? _item$product_variant : 0;
653
+
654
+ // 首先检查 product_id 是否匹配
655
+ if (configProductId !== actualProductId) {
656
+ return false;
657
+ }
658
+
659
+ // 如果配置的 product_variant_id = 0,只需要 product_id 匹配
660
+ if (configVariantId === 0) {
661
+ return true;
662
+ }
663
+
664
+ // 否则需要 product_variant_id 精确匹配
665
+ return configVariantId === actualVariantId;
666
+ });
667
+ }
668
+
669
+ /**
670
+ * 注册自定义运算符
671
+ */
672
+ }, {
673
+ key: "registerOperator",
674
+ value: function registerOperator(operator, handler) {
675
+ this.operatorHandlers.set(operator, handler);
676
+ }
677
+
678
+ /**
679
+ * 获取调试信息
680
+ */
681
+ }, {
682
+ key: "getDebugInfo",
683
+ value: function getDebugInfo() {
684
+ return {
685
+ debug: this.options.debug,
686
+ enableTrace: this.options.enableTrace,
687
+ registeredOperators: Array.from(this.operatorHandlers.keys())
688
+ };
689
+ }
690
+ }]);
691
+ return StrategyEngine;
692
+ }();
693
+
694
+ // ============================================
695
+ // 导出工具函数
696
+ // ============================================
697
+
698
+ /**
699
+ * 创建策略引擎实例
700
+ */
701
+ export function createStrategyEngine(options) {
702
+ return new StrategyEngine(options);
703
+ }
704
+
705
+ /**
706
+ * 快速评估(使用默认引擎配置)
707
+ */
708
+ export function evaluate(config, context) {
709
+ var engine = new StrategyEngine();
710
+ return engine.evaluate(config, context);
711
+ }