@pisell/pisellos 2.3.73 → 2.3.75

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 (296) hide show
  1. package/dist/core/index.d.ts +7 -0
  2. package/dist/core/index.js +111 -71
  3. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  4. package/dist/model/strategy/adapter/walletPass/example.js +3 -26
  5. package/dist/model/strategy/strategy-example.js +5 -19
  6. package/dist/modules/Cart/index.js +0 -3
  7. package/dist/modules/Cart/utils/cartProduct.js +0 -1
  8. package/dist/modules/Date/index.js +1 -5
  9. package/dist/modules/Discount/index.js +2 -4
  10. package/dist/modules/OpenData/index.js +0 -2
  11. package/dist/modules/Order/index.d.ts +1 -1
  12. package/dist/modules/Order/index.js +36 -64
  13. package/dist/modules/Payment/index.js +97 -162
  14. package/dist/modules/Quotation/index.d.ts +6 -0
  15. package/dist/modules/Quotation/index.js +75 -19
  16. package/dist/modules/Rules/index.js +1 -4
  17. package/dist/modules/Schedule/index.js +0 -1
  18. package/dist/modules/Schedule/utils.js +0 -1
  19. package/dist/modules/Step/index.js +0 -1
  20. package/dist/plugins/request.d.ts +1 -0
  21. package/dist/plugins/request.js +1 -4
  22. package/dist/plugins/window.js +2 -6
  23. package/dist/server/index.d.ts +8 -2
  24. package/dist/server/index.js +303 -269
  25. package/dist/server/modules/floor-plan/index.d.ts +4 -0
  26. package/dist/server/modules/floor-plan/index.js +240 -98
  27. package/dist/server/modules/menu/index.js +75 -59
  28. package/dist/server/modules/order/index.d.ts +17 -7
  29. package/dist/server/modules/order/index.js +421 -211
  30. package/dist/server/modules/products/index.d.ts +8 -2
  31. package/dist/server/modules/products/index.js +191 -117
  32. package/dist/server/modules/quotation/index.js +29 -38
  33. package/dist/server/modules/resource/index.js +24 -17
  34. package/dist/server/modules/schedule/index.js +27 -35
  35. package/dist/server/utils/product.js +0 -1
  36. package/dist/solution/BaseSales/index.js +38 -41
  37. package/dist/solution/BookingByStep/index.d.ts +1 -1
  38. package/dist/solution/BookingByStep/index.js +7 -59
  39. package/dist/solution/BookingByStep/utils/capacity.js +1 -11
  40. package/dist/solution/BookingByStep/utils/resources.js +1 -3
  41. package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
  42. package/dist/solution/BookingTicket/index.js +0 -2
  43. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +6 -7
  44. package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
  45. package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
  46. package/dist/solution/BuyTickets/index.js +9 -12
  47. package/dist/solution/Checkout/index.js +177 -252
  48. package/dist/solution/Checkout/utils/index.js +4 -16
  49. package/dist/solution/RegisterAndLogin/index.js +30 -76
  50. package/dist/solution/ScanOrder/index.js +50 -60
  51. package/dist/solution/ShopDiscount/index.js +2 -7
  52. package/dist/solution/VenueBooking/index.js +45 -55
  53. package/dist/utils/task.js +15 -18
  54. package/dist/utils/watch.js +0 -1
  55. package/lib/apis/picoding.js +2 -0
  56. package/lib/core/index.d.ts +7 -0
  57. package/lib/core/index.js +149 -131
  58. package/lib/effects/index.js +46 -57
  59. package/lib/index.js +82 -49
  60. package/lib/model/index.js +14 -21
  61. package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
  62. package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
  63. package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
  64. package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
  65. package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
  66. package/lib/model/strategy/adapter/index.js +100 -64
  67. package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
  68. package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
  69. package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
  70. package/lib/model/strategy/adapter/itemRule/index.js +83 -57
  71. package/lib/model/strategy/adapter/itemRule/type.js +97 -36
  72. package/lib/model/strategy/adapter/promotion/adapter.js +91 -69
  73. package/lib/model/strategy/adapter/promotion/evaluator.js +444 -310
  74. package/lib/model/strategy/adapter/promotion/examples.js +222 -234
  75. package/lib/model/strategy/adapter/promotion/index.js +1 -0
  76. package/lib/model/strategy/adapter/promotion/type.js +243 -36
  77. package/lib/model/strategy/adapter/type.js +4 -16
  78. package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -150
  79. package/lib/model/strategy/adapter/walletPass/example.js +217 -190
  80. package/lib/model/strategy/adapter/walletPass/index.js +75 -51
  81. package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
  82. package/lib/model/strategy/adapter/walletPass/type.js +4 -16
  83. package/lib/model/strategy/adapter/walletPass/utils.js +588 -378
  84. package/lib/model/strategy/engine.js +270 -168
  85. package/lib/model/strategy/index.js +49 -34
  86. package/lib/model/strategy/strategy-example.js +243 -239
  87. package/lib/model/strategy/type.js +100 -40
  88. package/lib/modules/Account/index.js +39 -53
  89. package/lib/modules/Account/types.js +20 -33
  90. package/lib/modules/AccountList/index.js +116 -154
  91. package/lib/modules/AccountList/types.js +30 -31
  92. package/lib/modules/AccountList/utils.js +18 -30
  93. package/lib/modules/BaseModule.js +23 -42
  94. package/lib/modules/BookingContext/index.js +158 -136
  95. package/lib/modules/BookingContext/types.js +46 -32
  96. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +138 -146
  97. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +78 -83
  98. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +170 -150
  99. package/lib/modules/BookingContext/utils/flexible.js +38 -55
  100. package/lib/modules/BookingContext/utils/formatResourceList.js +19 -34
  101. package/lib/modules/BookingContext/utils/index.js +124 -41
  102. package/lib/modules/BookingContext/utils/noResource.js +58 -70
  103. package/lib/modules/BookingContext/utils/orderLineDisplay.js +14 -41
  104. package/lib/modules/BookingContext/utils/productExtend.js +202 -155
  105. package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
  106. package/lib/modules/BookingContext/utils/resourceSelection.js +19 -41
  107. package/lib/modules/BookingContext/utils/resources.js +209 -167
  108. package/lib/modules/BookingContext/utils/serviceTimes.js +115 -116
  109. package/lib/modules/BookingContext/utils/timeSlices.js +76 -86
  110. package/lib/modules/Cart/index.js +170 -124
  111. package/lib/modules/Cart/types.js +46 -51
  112. package/lib/modules/Cart/utils/cartAccount.js +40 -39
  113. package/lib/modules/Cart/utils/cartDate.js +56 -61
  114. package/lib/modules/Cart/utils/cartDiscount.js +28 -33
  115. package/lib/modules/Cart/utils/cartNote.js +27 -32
  116. package/lib/modules/Cart/utils/cartProduct.js +321 -251
  117. package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
  118. package/lib/modules/Cart/utils/cartResource.js +70 -78
  119. package/lib/modules/Cart/utils/changePrice.js +22 -50
  120. package/lib/modules/Cart/utils/index.js +106 -48
  121. package/lib/modules/Customer/constants.js +13 -34
  122. package/lib/modules/Customer/index.js +235 -172
  123. package/lib/modules/Customer/types.js +38 -35
  124. package/lib/modules/Date/index.js +116 -115
  125. package/lib/modules/Date/types.js +16 -28
  126. package/lib/modules/Date/utils.js +174 -123
  127. package/lib/modules/Discount/index.js +122 -127
  128. package/lib/modules/Discount/types.js +9 -31
  129. package/lib/modules/Guests/index.js +30 -56
  130. package/lib/modules/Guests/types.js +23 -33
  131. package/lib/modules/Holder/index.js +209 -189
  132. package/lib/modules/Holder/types.js +4 -16
  133. package/lib/modules/Holder/utils.js +20 -49
  134. package/lib/modules/OpenData/index.js +70 -76
  135. package/lib/modules/OpenData/types.js +4 -16
  136. package/lib/modules/OpenData/utils.js +44 -78
  137. package/lib/modules/Order/index.d.ts +1 -1
  138. package/lib/modules/Order/index.js +1713 -2118
  139. package/lib/modules/Order/payment-utils.js +77 -120
  140. package/lib/modules/Order/types.js +88 -35
  141. package/lib/modules/Order/utils/bundleDiscountHydration.js +41 -74
  142. package/lib/modules/Order/utils/discountProductLineIdentity.js +142 -100
  143. package/lib/modules/Order/utils/manualProductDiscount.js +124 -123
  144. package/lib/modules/Order/utils/orderCollectionIdentity.js +184 -244
  145. package/lib/modules/Order/utils.js +814 -647
  146. package/lib/modules/Payment/cash.js +20 -33
  147. package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
  148. package/lib/modules/Payment/eftpos.js +16 -30
  149. package/lib/modules/Payment/index.js +532 -399
  150. package/lib/modules/Payment/mx51.js +1 -0
  151. package/lib/modules/Payment/types.js +230 -108
  152. package/lib/modules/Payment/utils.js +52 -51
  153. package/lib/modules/Payment/walletpass.js +485 -660
  154. package/lib/modules/Product/index.js +51 -46
  155. package/lib/modules/Product/types.js +4 -16
  156. package/lib/modules/Product/utils.js +32 -33
  157. package/lib/modules/ProductList/index.js +113 -123
  158. package/lib/modules/ProductList/types.js +9 -31
  159. package/lib/modules/Quotation/index.d.ts +6 -0
  160. package/lib/modules/Quotation/index.js +110 -103
  161. package/lib/modules/Quotation/types.js +4 -16
  162. package/lib/modules/Resource/index.js +27 -59
  163. package/lib/modules/Resource/types.js +22 -32
  164. package/lib/modules/Resource/utils.js +30 -38
  165. package/lib/modules/ResourcePlanner/index.js +25 -23
  166. package/lib/modules/ResourcePlanner/localClock.js +54 -119
  167. package/lib/modules/ResourcePlanner/planner.js +589 -770
  168. package/lib/modules/ResourcePlanner/types.js +10 -29
  169. package/lib/modules/Rules/index.js +1218 -959
  170. package/lib/modules/Rules/types.js +17 -40
  171. package/lib/modules/SalesSummary/index.js +85 -90
  172. package/lib/modules/SalesSummary/types.js +4 -16
  173. package/lib/modules/SalesSummary/utils.js +355 -430
  174. package/lib/modules/ScanOrderLogger/index.js +59 -79
  175. package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
  176. package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
  177. package/lib/modules/ScanOrderLogger/types.js +4 -16
  178. package/lib/modules/Schedule/getDateIsInSchedule.js +334 -163
  179. package/lib/modules/Schedule/index.js +100 -114
  180. package/lib/modules/Schedule/type.js +4 -16
  181. package/lib/modules/Schedule/types.js +4 -16
  182. package/lib/modules/Schedule/utils.js +433 -291
  183. package/lib/modules/Step/index.js +40 -52
  184. package/lib/modules/Step/tyeps.js +4 -16
  185. package/lib/modules/Summary/index.js +66 -71
  186. package/lib/modules/Summary/types.js +4 -16
  187. package/lib/modules/Summary/utils.js +773 -418
  188. package/lib/modules/SurchargeList/index.js +46 -60
  189. package/lib/modules/SurchargeList/types.js +4 -16
  190. package/lib/modules/index.js +245 -63
  191. package/lib/plugins/app.js +4 -16
  192. package/lib/plugins/index.js +36 -25
  193. package/lib/plugins/request.d.ts +1 -0
  194. package/lib/plugins/request.js +137 -126
  195. package/lib/plugins/shopStore.js +4 -16
  196. package/lib/plugins/user.js +4 -16
  197. package/lib/plugins/window.js +171 -179
  198. package/lib/server/index.d.ts +8 -2
  199. package/lib/server/index.js +3083 -2663
  200. package/lib/server/modules/floor-plan/index.d.ts +4 -0
  201. package/lib/server/modules/floor-plan/index.js +159 -127
  202. package/lib/server/modules/floor-plan/types.js +15 -30
  203. package/lib/server/modules/index.js +106 -68
  204. package/lib/server/modules/menu/index.js +170 -124
  205. package/lib/server/modules/menu/types.js +18 -31
  206. package/lib/server/modules/order/index.d.ts +17 -7
  207. package/lib/server/modules/order/index.js +916 -977
  208. package/lib/server/modules/order/types.js +122 -33
  209. package/lib/server/modules/order/utils/filterBookings.js +219 -194
  210. package/lib/server/modules/order/utils/filterOrders.js +118 -92
  211. package/lib/server/modules/payment/index.js +59 -83
  212. package/lib/server/modules/payment/types.js +4 -16
  213. package/lib/server/modules/products/index.d.ts +8 -2
  214. package/lib/server/modules/products/index.js +656 -471
  215. package/lib/server/modules/products/types.js +44 -34
  216. package/lib/server/modules/quotation/index.js +137 -172
  217. package/lib/server/modules/quotation/types.js +21 -31
  218. package/lib/server/modules/resource/index.js +225 -186
  219. package/lib/server/modules/resource/types.js +42 -33
  220. package/lib/server/modules/schedule/index.js +135 -123
  221. package/lib/server/modules/schedule/types.js +14 -21
  222. package/lib/server/modules/schedule/utils.js +334 -163
  223. package/lib/server/types.js +4 -16
  224. package/lib/server/utils/index.js +25 -23
  225. package/lib/server/utils/product.js +196 -139
  226. package/lib/server/utils/schedule.js +34 -41
  227. package/lib/server/utils/small-ticket.js +479 -456
  228. package/lib/server/utils/time.js +40 -49
  229. package/lib/solution/BaseSales/index.js +1186 -1410
  230. package/lib/solution/BaseSales/types.js +42 -38
  231. package/lib/solution/BaseSales/utils/cartPromotion.js +642 -498
  232. package/lib/solution/BaseSales/utils/parseSalesResponse.js +85 -105
  233. package/lib/solution/BaseSales/utils/quotationPrice.js +56 -114
  234. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +108 -145
  235. package/lib/solution/BaseSales/utils.js +158 -143
  236. package/lib/solution/BookingByStep/index.d.ts +1 -1
  237. package/lib/solution/BookingByStep/index.js +1527 -1340
  238. package/lib/solution/BookingByStep/types.js +40 -99
  239. package/lib/solution/BookingByStep/utils/capacity.js +192 -160
  240. package/lib/solution/BookingByStep/utils/products.js +42 -52
  241. package/lib/solution/BookingByStep/utils/resources.js +527 -330
  242. package/lib/solution/BookingByStep/utils/stock.js +65 -44
  243. package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
  244. package/lib/solution/BookingTicket/index.js +607 -522
  245. package/lib/solution/BookingTicket/types.js +99 -77
  246. package/lib/solution/BookingTicket/utils/addProductDecision.js +226 -189
  247. package/lib/solution/BookingTicket/utils/addTimeAvailability.js +58 -89
  248. package/lib/solution/BookingTicket/utils/bookingStatus.js +107 -78
  249. package/lib/solution/BookingTicket/utils/cartView.js +114 -99
  250. package/lib/solution/BookingTicket/utils/exampleData.js +185 -0
  251. package/lib/solution/BookingTicket/utils/orderCustomer.js +18 -41
  252. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +219 -86
  253. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +168 -116
  254. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +79 -91
  255. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +54 -41
  256. package/lib/solution/BookingTicket/utils/scan/handleScan.js +84 -81
  257. package/lib/solution/BookingTicket/utils/scan/index.js +98 -104
  258. package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
  259. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +52 -64
  260. package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +56 -58
  261. package/lib/solution/BookingTicket/utils/weighingProductSku.js +34 -48
  262. package/lib/solution/BuyTickets/index.js +67 -70
  263. package/lib/solution/BuyTickets/types.js +22 -38
  264. package/lib/solution/Checkout/index.js +1451 -1158
  265. package/lib/solution/Checkout/types.js +91 -61
  266. package/lib/solution/Checkout/utils/index.js +228 -156
  267. package/lib/solution/PlaceOrder/index.js +55 -0
  268. package/lib/solution/RegisterAndLogin/config.js +493 -460
  269. package/lib/solution/RegisterAndLogin/index.js +633 -630
  270. package/lib/solution/RegisterAndLogin/types.js +189 -76
  271. package/lib/solution/RegisterAndLogin/utils.js +183 -125
  272. package/lib/solution/Sales/index.js +328 -324
  273. package/lib/solution/Sales/types.js +27 -33
  274. package/lib/solution/ScanOrder/index.js +832 -864
  275. package/lib/solution/ScanOrder/types.js +33 -34
  276. package/lib/solution/ScanOrder/utils.js +409 -374
  277. package/lib/solution/ShopDiscount/index.js +226 -232
  278. package/lib/solution/ShopDiscount/types.js +15 -37
  279. package/lib/solution/ShopDiscount/utils.js +300 -172
  280. package/lib/solution/UnifiedBookingSales/index.js +1035 -1201
  281. package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +99 -159
  282. package/lib/solution/UnifiedBookingSales/types.js +10 -32
  283. package/lib/solution/VenueBooking/index.js +811 -879
  284. package/lib/solution/VenueBooking/types.js +19 -39
  285. package/lib/solution/VenueBooking/utils/dateSummary.js +27 -56
  286. package/lib/solution/VenueBooking/utils/resource.js +31 -54
  287. package/lib/solution/VenueBooking/utils/slotMerge.js +94 -107
  288. package/lib/solution/VenueBooking/utils/timeSlot.js +132 -132
  289. package/lib/solution/VenueBooking/utils.js +130 -67
  290. package/lib/solution/index.js +124 -41
  291. package/lib/store/createStore.js +32 -29
  292. package/lib/types/index.js +4 -16
  293. package/lib/utils/payment-number.js +26 -46
  294. package/lib/utils/task.js +36 -36
  295. package/lib/utils/watch.js +81 -47
  296. package/package.json +2 -1
@@ -1,48 +1,52 @@
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/engine.ts
20
- var engine_exports = {};
21
- __export(engine_exports, {
22
- StrategyEngine: () => StrategyEngine,
23
- createStrategyEngine: () => createStrategyEngine,
24
- evaluate: () => evaluate
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
25
5
  });
26
- module.exports = __toCommonJS(engine_exports);
27
- var import_type = require("./type");
28
- var StrategyEngine = class {
6
+ exports.StrategyEngine = void 0;
7
+ exports.createStrategyEngine = createStrategyEngine;
8
+ exports.evaluate = evaluate;
9
+ var _type = require("./type");
10
+ /**
11
+ * 策略模型 - 核心实现
12
+ *
13
+ * 完全业务无关的通用策略引擎
14
+ * 支持条件评估、动作匹配、结果返回
15
+ */
16
+
17
+ // ============================================
18
+ // 策略引擎实现
19
+ // ============================================
20
+
21
+ /**
22
+ * 策略引擎
23
+ *
24
+ * 核心职责:
25
+ * 1. 递归评估条件组
26
+ * 2. 收集满足条件的 actionIds
27
+ * 3. 根据 actionIds 获取 ActionEffect 对象
28
+ * 4. 按 priority 排序返回
29
+ */
30
+ class StrategyEngine {
31
+ options;
32
+ operatorHandlers;
29
33
  constructor(options = {}) {
30
34
  this.options = {
31
35
  debug: options.debug ?? false,
32
36
  enableTrace: options.enableTrace ?? false,
33
37
  operatorHandlers: options.operatorHandlers ?? {},
34
- errorHandler: options.errorHandler ?? ((error) => console.error(error))
38
+ errorHandler: options.errorHandler ?? (error => console.error(error))
35
39
  };
36
- this.operatorHandlers = new Map(
37
- Object.entries(this.options.operatorHandlers)
38
- );
40
+
41
+ // 初始化内置运算符处理器
42
+ this.operatorHandlers = new Map(Object.entries(this.options.operatorHandlers));
39
43
  this.initializeBuiltInOperators();
40
44
  }
45
+
41
46
  /**
42
47
  * 评估策略
43
48
  */
44
49
  evaluate(config, context) {
45
- var _a, _b;
46
50
  const startTime = Date.now();
47
51
  const trace = {
48
52
  steps: [],
@@ -50,23 +54,23 @@ var StrategyEngine = class {
50
54
  errors: []
51
55
  };
52
56
  try {
57
+ // 验证配置
53
58
  this.validateConfig(config);
54
59
  if (this.options.enableTrace) {
55
60
  trace.steps.push({
56
- step: "validate_config",
57
- status: "success",
61
+ step: 'validate_config',
62
+ status: 'success',
58
63
  duration: Date.now() - startTime
59
64
  });
60
65
  }
66
+
67
+ // 递归评估条件组,收集 actionIds
61
68
  const evaluateStart = Date.now();
62
- const evaluationResult = this.evaluateConditionGroup(
63
- config.conditions,
64
- context
65
- );
69
+ const evaluationResult = this.evaluateConditionGroup(config.conditions, context);
66
70
  if (this.options.enableTrace) {
67
71
  trace.steps.push({
68
- step: "evaluate_conditions",
69
- status: "success",
72
+ step: 'evaluate_conditions',
73
+ status: 'success',
70
74
  duration: Date.now() - evaluateStart,
71
75
  details: {
72
76
  satisfied: evaluationResult.satisfied,
@@ -74,46 +78,51 @@ var StrategyEngine = class {
74
78
  }
75
79
  });
76
80
  }
81
+
82
+ // 根据 actionIds 获取 ActionEffect 对象
77
83
  const actionStart = Date.now();
78
- const matchedActions = this.getActionsByIds(
79
- evaluationResult.actionIds,
80
- config.actions
81
- );
84
+ const matchedActions = this.getActionsByIds(evaluationResult.actionIds, config.actions);
82
85
  if (this.options.enableTrace) {
83
86
  trace.steps.push({
84
- step: "get_actions",
85
- status: "success",
87
+ step: 'get_actions',
88
+ status: 'success',
86
89
  duration: Date.now() - actionStart,
87
- details: { matchedCount: matchedActions.length }
90
+ details: {
91
+ matchedCount: matchedActions.length
92
+ }
88
93
  });
89
94
  }
95
+
96
+ // 按 priority 排序(降序)
90
97
  const sortStart = Date.now();
91
98
  const sortedActions = this.sortActionsByPriority(matchedActions);
92
99
  if (this.options.enableTrace) {
93
100
  trace.steps.push({
94
- step: "sort_actions",
95
- status: "success",
101
+ step: 'sort_actions',
102
+ status: 'success',
96
103
  duration: Date.now() - sortStart
97
104
  });
98
105
  }
106
+
107
+ // 构建结果 - applicable 基于条件是否满足,而不是 actionIds 数量
99
108
  const applicable = evaluationResult.satisfied;
100
109
  const result = {
101
110
  success: true,
102
111
  applicable,
103
- code: applicable ? import_type.SUCCESS_CODES.SUCCESS : import_type.NOT_APPLICABLE_CODES.CONDITION_NOT_MET,
104
- message: applicable ? "Strategy is applicable" : "Conditions not met",
112
+ code: applicable ? _type.SUCCESS_CODES.SUCCESS : _type.NOT_APPLICABLE_CODES.CONDITION_NOT_MET,
113
+ message: applicable ? 'Strategy is applicable' : 'Conditions not met',
105
114
  matched: {
106
115
  conditions: applicable,
107
116
  actionIds: evaluationResult.actionIds,
108
117
  details: {},
109
- ...applicable ? {} : {
110
- failedField: (_a = evaluationResult.failedRules[0]) == null ? void 0 : _a.field,
118
+ ...(applicable ? {} : {
119
+ failedField: evaluationResult.failedRules[0]?.field,
111
120
  failedRules: evaluationResult.failedRules
112
- }
121
+ })
113
122
  },
114
123
  matchedActions: sortedActions,
115
124
  outputs: {},
116
- config
125
+ config: config
117
126
  };
118
127
  trace.duration = Date.now() - startTime;
119
128
  if (this.options.enableTrace) {
@@ -121,10 +130,10 @@ var StrategyEngine = class {
121
130
  }
122
131
  return result;
123
132
  } catch (error) {
124
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
133
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
125
134
  if (this.options.enableTrace) {
126
- (_b = trace.errors) == null ? void 0 : _b.push({
127
- step: "evaluation",
135
+ trace.errors?.push({
136
+ step: 'evaluation',
128
137
  error: errorMessage,
129
138
  timestamp: Date.now()
130
139
  });
@@ -134,7 +143,7 @@ var StrategyEngine = class {
134
143
  return {
135
144
  success: false,
136
145
  applicable: false,
137
- code: import_type.ERROR_CODES.EVALUATION_ERROR,
146
+ code: _type.ERROR_CODES.EVALUATION_ERROR,
138
147
  message: errorMessage,
139
148
  matched: {
140
149
  conditions: false,
@@ -143,11 +152,12 @@ var StrategyEngine = class {
143
152
  },
144
153
  matchedActions: [],
145
154
  outputs: {},
146
- trace: this.options.enableTrace ? trace : void 0,
147
- config
155
+ trace: this.options.enableTrace ? trace : undefined,
156
+ config: config
148
157
  };
149
158
  }
150
159
  }
160
+
151
161
  /**
152
162
  * 递归评估条件组
153
163
  *
@@ -157,12 +167,16 @@ var StrategyEngine = class {
157
167
  */
158
168
  evaluateConditionGroup(group, context) {
159
169
  const collectedActionIds = [];
160
- const { satisfied, failedRules } = this.evaluateGroupLogicDetailed(
161
- group,
162
- context
163
- );
170
+
171
+ // 评估当前层的 operator 和 rules(同时收集失败信息)
172
+ const {
173
+ satisfied,
174
+ failedRules
175
+ } = this.evaluateGroupLogicDetailed(group, context);
164
176
  if (satisfied) {
165
177
  collectedActionIds.push(...group.actionIds);
178
+
179
+ // 递归评估嵌套的 ConditionGroup,收集嵌套层的 actionIds
166
180
  for (const rule of group.rules) {
167
181
  if (this.isConditionGroup(rule)) {
168
182
  const nestedResult = this.evaluateConditionGroup(rule, context);
@@ -176,6 +190,7 @@ var StrategyEngine = class {
176
190
  failedRules
177
191
  };
178
192
  }
193
+
179
194
  /**
180
195
  * 评估条件组的逻辑运算(带失败规则收集)
181
196
  *
@@ -185,46 +200,72 @@ var StrategyEngine = class {
185
200
  * - `not`:被取反规则实际通过时,记录该规则
186
201
  */
187
202
  evaluateGroupLogicDetailed(group, context) {
188
- const { operator, rules } = group;
203
+ const {
204
+ operator,
205
+ rules
206
+ } = group;
189
207
  switch (operator) {
190
- case "and": {
191
- for (const rule of rules) {
192
- const ruleResult = this.evaluateRuleDetailed(rule, context);
193
- if (!ruleResult.satisfied) {
208
+ case 'and':
209
+ {
210
+ for (const rule of rules) {
211
+ const ruleResult = this.evaluateRuleDetailed(rule, context);
212
+ if (!ruleResult.satisfied) {
213
+ return {
214
+ satisfied: false,
215
+ failedRules: ruleResult.failedRules
216
+ };
217
+ }
218
+ }
219
+ return {
220
+ satisfied: true,
221
+ failedRules: []
222
+ };
223
+ }
224
+ case 'or':
225
+ {
226
+ const aggregated = [];
227
+ for (const rule of rules) {
228
+ const ruleResult = this.evaluateRuleDetailed(rule, context);
229
+ if (ruleResult.satisfied) {
230
+ return {
231
+ satisfied: true,
232
+ failedRules: []
233
+ };
234
+ }
235
+ aggregated.push(...ruleResult.failedRules);
236
+ }
237
+ return {
238
+ satisfied: false,
239
+ failedRules: aggregated
240
+ };
241
+ }
242
+ case 'not':
243
+ {
244
+ if (rules.length === 0) {
194
245
  return {
195
246
  satisfied: false,
196
- failedRules: ruleResult.failedRules
247
+ failedRules: []
197
248
  };
198
249
  }
199
- }
200
- return { satisfied: true, failedRules: [] };
201
- }
202
- case "or": {
203
- const aggregated = [];
204
- for (const rule of rules) {
205
- const ruleResult = this.evaluateRuleDetailed(rule, context);
250
+ const ruleResult = this.evaluateRuleDetailed(rules[0], context);
206
251
  if (ruleResult.satisfied) {
207
- return { satisfied: true, failedRules: [] };
252
+ // 被取反规则实际通过,导致 not 失败
253
+ const failed = this.isConditionGroup(rules[0]) ? [] : [this.buildFailedRuleInfo(rules[0], context)];
254
+ return {
255
+ satisfied: false,
256
+ failedRules: failed
257
+ };
208
258
  }
209
- aggregated.push(...ruleResult.failedRules);
210
- }
211
- return { satisfied: false, failedRules: aggregated };
212
- }
213
- case "not": {
214
- if (rules.length === 0) {
215
- return { satisfied: false, failedRules: [] };
259
+ return {
260
+ satisfied: true,
261
+ failedRules: []
262
+ };
216
263
  }
217
- const ruleResult = this.evaluateRuleDetailed(rules[0], context);
218
- if (ruleResult.satisfied) {
219
- const failed = this.isConditionGroup(rules[0]) ? [] : [this.buildFailedRuleInfo(rules[0], context)];
220
- return { satisfied: false, failedRules: failed };
221
- }
222
- return { satisfied: true, failedRules: [] };
223
- }
224
264
  default:
225
265
  throw new Error(`Unknown operator: ${operator}`);
226
266
  }
227
267
  }
268
+
228
269
  /**
229
270
  * 评估单个规则(带失败规则收集)
230
271
  */
@@ -235,27 +276,35 @@ var StrategyEngine = class {
235
276
  const conditionRule = rule;
236
277
  const satisfied = this.evaluateAtomicRule(conditionRule, context);
237
278
  if (satisfied) {
238
- return { satisfied: true, failedRules: [] };
279
+ return {
280
+ satisfied: true,
281
+ failedRules: []
282
+ };
239
283
  }
240
284
  return {
241
285
  satisfied: false,
242
286
  failedRules: [this.buildFailedRuleInfo(conditionRule, context)]
243
287
  };
244
288
  }
289
+
245
290
  /**
246
291
  * 评估原子规则(不收集失败信息,仅返回布尔结果)
247
292
  */
248
293
  evaluateAtomicRule(conditionRule, context) {
249
- if (conditionRule.type === "code" && conditionRule.code) {
294
+ // Code 模式:使用 eval 执行
295
+ if (conditionRule.type === 'code' && conditionRule.code) {
250
296
  return this.evaluateCodeCondition(conditionRule.code, context);
251
297
  }
298
+
299
+ // Operator 模式:标准运算符判断
252
300
  return this.evaluateOperatorCondition(conditionRule, context);
253
301
  }
302
+
254
303
  /**
255
304
  * 构建失败规则信息
256
305
  */
257
306
  buildFailedRuleInfo(conditionRule, context) {
258
- const actualValue = conditionRule.field ? this.getFieldValue(conditionRule.field, context) : void 0;
307
+ const actualValue = conditionRule.field ? this.getFieldValue(conditionRule.field, context) : undefined;
259
308
  return {
260
309
  field: conditionRule.field,
261
310
  operator: conditionRule.operator,
@@ -263,144 +312,169 @@ var StrategyEngine = class {
263
312
  actualValue
264
313
  };
265
314
  }
315
+
266
316
  /**
267
317
  * 评估代码模式条件
268
318
  */
269
319
  evaluateCodeCondition(code, context) {
270
320
  try {
271
- const { entities, attributes, metadata } = context;
272
- const evalFunc = new Function(
273
- "entities",
274
- "attributes",
275
- "metadata",
276
- `return (${code})`
277
- );
321
+ // context 解构到作用域中,方便代码直接使用
322
+ const {
323
+ entities,
324
+ attributes,
325
+ metadata
326
+ } = context;
327
+
328
+ // 使用 Function 构造器代替 eval,更安全
329
+ const evalFunc = new Function('entities', 'attributes', 'metadata', `return (${code})`);
278
330
  const result = evalFunc(entities, attributes, metadata);
279
331
  return Boolean(result);
280
332
  } catch (error) {
281
333
  if (this.options.debug) {
282
- console.error("Code evaluation error:", error);
334
+ console.error('Code evaluation error:', error);
283
335
  }
284
336
  return false;
285
337
  }
286
338
  }
339
+
287
340
  /**
288
341
  * 评估运算符模式条件
289
342
  */
290
343
  evaluateOperatorCondition(rule, context) {
291
- const { field, operator, value } = rule;
344
+ const {
345
+ field,
346
+ operator,
347
+ value
348
+ } = rule;
292
349
  if (!field || !operator) {
293
350
  return false;
294
351
  }
352
+
353
+ // 从 context.attributes 中获取字段值
295
354
  const fieldValue = this.getFieldValue(field, context);
355
+
356
+ // 使用运算符处理器
296
357
  const handler = this.operatorHandlers.get(operator);
297
358
  if (handler) {
298
359
  return handler(fieldValue, value, rule);
299
360
  }
361
+
362
+ // 回退到内置运算符
300
363
  return this.evaluateBuiltInOperator(fieldValue, operator, value);
301
364
  }
365
+
302
366
  /**
303
367
  * 获取字段值
304
368
  */
305
369
  getFieldValue(field, context) {
306
- const path = field.split(".");
370
+ // 支持点号路径,如 "order.total"
371
+ const path = field.split('.');
307
372
  let value = context.attributes;
308
373
  for (const key of path) {
309
- if (value && typeof value === "object" && key in value) {
374
+ if (value && typeof value === 'object' && key in value) {
310
375
  value = value[key];
311
376
  } else {
312
- return void 0;
377
+ return undefined;
313
378
  }
314
379
  }
315
380
  return value;
316
381
  }
382
+
317
383
  /**
318
384
  * 评估内置运算符
319
385
  */
320
386
  evaluateBuiltInOperator(fieldValue, operator, compareValue) {
321
387
  switch (operator) {
322
- case "=":
323
- case "==":
388
+ // 比较运算符
389
+ case '=':
390
+ case '==':
324
391
  return fieldValue == compareValue;
325
- case "!=":
392
+ case '!=':
326
393
  return fieldValue != compareValue;
327
- case ">":
394
+ case '>':
328
395
  return fieldValue > compareValue;
329
- case ">=":
396
+ case '>=':
330
397
  return fieldValue >= compareValue;
331
- case "<":
398
+ case '<':
332
399
  return fieldValue < compareValue;
333
- case "<=":
400
+ case '<=':
334
401
  return fieldValue <= compareValue;
335
- case "in":
402
+
403
+ // 集合运算符
404
+ case 'in':
336
405
  return Array.isArray(compareValue) && compareValue.includes(fieldValue);
337
- case "not_in":
406
+ case 'not_in':
338
407
  return Array.isArray(compareValue) && !compareValue.includes(fieldValue);
339
- case "contains":
408
+ case 'contains':
340
409
  if (Array.isArray(fieldValue)) {
341
410
  return fieldValue.includes(compareValue);
342
411
  }
343
- if (typeof fieldValue === "string") {
412
+ if (typeof fieldValue === 'string') {
344
413
  return fieldValue.includes(compareValue);
345
414
  }
346
415
  return false;
347
- case "not_contains":
416
+ case 'not_contains':
348
417
  if (Array.isArray(fieldValue)) {
349
418
  return !fieldValue.includes(compareValue);
350
419
  }
351
- if (typeof fieldValue === "string") {
420
+ if (typeof fieldValue === 'string') {
352
421
  return !fieldValue.includes(compareValue);
353
422
  }
354
423
  return true;
355
- case "starts_with":
356
- return typeof fieldValue === "string" && fieldValue.startsWith(compareValue);
357
- case "ends_with":
358
- return typeof fieldValue === "string" && fieldValue.endsWith(compareValue);
359
- case "regex":
360
- return typeof fieldValue === "string" && new RegExp(compareValue).test(fieldValue);
361
- case "between":
362
- if (!Array.isArray(compareValue) || compareValue.length !== 2)
363
- return false;
424
+
425
+ // 字符串运算符
426
+ case 'starts_with':
427
+ return typeof fieldValue === 'string' && fieldValue.startsWith(compareValue);
428
+ case 'ends_with':
429
+ return typeof fieldValue === 'string' && fieldValue.endsWith(compareValue);
430
+ case 'regex':
431
+ return typeof fieldValue === 'string' && new RegExp(compareValue).test(fieldValue);
432
+
433
+ // 范围运算符
434
+ case 'between':
435
+ if (!Array.isArray(compareValue) || compareValue.length !== 2) return false;
364
436
  return fieldValue >= compareValue[0] && fieldValue <= compareValue[1];
365
- case "is_null":
366
- return fieldValue === null || fieldValue === void 0;
367
- case "is_not_null":
368
- return fieldValue !== null && fieldValue !== void 0;
369
- case "is_empty":
370
- if (Array.isArray(fieldValue))
371
- return fieldValue.length === 0;
372
- if (typeof fieldValue === "string")
373
- return fieldValue.length === 0;
374
- if (typeof fieldValue === "object")
375
- return Object.keys(fieldValue).length === 0;
437
+
438
+ // 逻辑运算符
439
+ case 'is_null':
440
+ return fieldValue === null || fieldValue === undefined;
441
+ case 'is_not_null':
442
+ return fieldValue !== null && fieldValue !== undefined;
443
+ case 'is_empty':
444
+ if (Array.isArray(fieldValue)) return fieldValue.length === 0;
445
+ if (typeof fieldValue === 'string') return fieldValue.length === 0;
446
+ if (typeof fieldValue === 'object') return Object.keys(fieldValue).length === 0;
376
447
  return !fieldValue;
377
- case "is_not_empty":
378
- if (Array.isArray(fieldValue))
379
- return fieldValue.length > 0;
380
- if (typeof fieldValue === "string")
381
- return fieldValue.length > 0;
382
- if (typeof fieldValue === "object")
383
- return Object.keys(fieldValue).length > 0;
448
+ case 'is_not_empty':
449
+ if (Array.isArray(fieldValue)) return fieldValue.length > 0;
450
+ if (typeof fieldValue === 'string') return fieldValue.length > 0;
451
+ if (typeof fieldValue === 'object') return Object.keys(fieldValue).length > 0;
384
452
  return Boolean(fieldValue);
385
- case "product_match":
453
+
454
+ // 商品匹配运算符
455
+ case 'product_match':
386
456
  return this.evaluateProductMatch(fieldValue, compareValue);
387
- case "object_in":
457
+
458
+ // 对象包含运算符(兼容旧配置)
459
+ case 'object_in':
388
460
  return this.evaluateProductMatch(fieldValue, compareValue);
389
461
  default:
390
462
  throw new Error(`Unsupported operator: ${operator}`);
391
463
  }
392
464
  }
465
+
393
466
  /**
394
467
  * 根据 actionIds 获取 ActionEffect 对象
395
468
  */
396
469
  getActionsByIds(actionIds, actions) {
397
470
  const matchedActions = [];
398
- const actionMap = new Map(actions.map((action) => [action.id, action]));
471
+ const actionMap = new Map(actions.map(action => [action.id, action]));
399
472
  for (const id of actionIds) {
400
473
  const action = actionMap.get(id);
401
474
  if (action) {
402
475
  matchedActions.push(action);
403
476
  } else {
477
+ // 找不到的 ID 记录警告
404
478
  if (this.options.debug) {
405
479
  console.warn(`Action with id "${id}" not found in actions array`);
406
480
  }
@@ -408,6 +482,7 @@ var StrategyEngine = class {
408
482
  }
409
483
  return matchedActions;
410
484
  }
485
+
411
486
  /**
412
487
  * 按 priority 排序(降序)
413
488
  */
@@ -415,37 +490,43 @@ var StrategyEngine = class {
415
490
  return [...actions].sort((a, b) => {
416
491
  const priorityA = a.priority ?? 0;
417
492
  const priorityB = b.priority ?? 0;
418
- return priorityB - priorityA;
493
+ return priorityB - priorityA; // 降序
419
494
  });
420
495
  }
496
+
421
497
  /**
422
498
  * 判断是否为条件组
423
499
  */
424
500
  isConditionGroup(rule) {
425
- return "operator" in rule && "rules" in rule && Array.isArray(rule.rules);
501
+ return 'operator' in rule && 'rules' in rule && Array.isArray(rule.rules);
426
502
  }
503
+
427
504
  /**
428
505
  * 验证配置
429
506
  */
430
507
  validateConfig(config) {
431
508
  if (!config) {
432
- throw new Error("Strategy config is required");
509
+ throw new Error('Strategy config is required');
433
510
  }
434
511
  if (!config.metadata || !config.metadata.id) {
435
- throw new Error("Strategy metadata.id is required");
512
+ throw new Error('Strategy metadata.id is required');
436
513
  }
437
514
  if (!config.conditions) {
438
- throw new Error("Strategy conditions is required");
515
+ throw new Error('Strategy conditions is required');
439
516
  }
440
517
  if (!Array.isArray(config.actions)) {
441
- throw new Error("Strategy actions must be an array");
518
+ throw new Error('Strategy actions must be an array');
442
519
  }
443
520
  }
521
+
444
522
  /**
445
523
  * 初始化内置运算符处理器
446
524
  */
447
525
  initializeBuiltInOperators() {
526
+ // 内置运算符已经在 evaluateBuiltInOperator 中实现
527
+ // 这里可以添加自定义的运算符处理器
448
528
  }
529
+
449
530
  /**
450
531
  * 评估商品匹配运算符
451
532
  *
@@ -459,35 +540,49 @@ var StrategyEngine = class {
459
540
  * @returns 是否匹配
460
541
  */
461
542
  evaluateProductMatch(fieldValue, configValue) {
543
+ // 确保 configValue 是数组
462
544
  if (!Array.isArray(configValue)) {
463
545
  return false;
464
546
  }
465
- if (!fieldValue || typeof fieldValue !== "object" || typeof fieldValue.product_id !== "number") {
547
+
548
+ // 确保 fieldValue 是有效的商品对象
549
+ if (!fieldValue || typeof fieldValue !== 'object' || typeof fieldValue.product_id !== 'number') {
466
550
  return false;
467
551
  }
468
552
  const actualProductId = fieldValue.product_id;
469
553
  const actualVariantId = fieldValue.product_variant_id ?? 0;
470
- return configValue.some((item) => {
471
- if (!item || typeof item.product_id !== "number") {
554
+
555
+ // 遍历配置的商品列表,检查是否有匹配
556
+ return configValue.some(item => {
557
+ // 验证配置项格式
558
+ if (!item || typeof item.product_id !== 'number') {
472
559
  return false;
473
560
  }
474
561
  const configProductId = item.product_id;
475
562
  const configVariantId = item.product_variant_id ?? 0;
563
+
564
+ // 首先检查 product_id 是否匹配
476
565
  if (configProductId !== actualProductId) {
477
566
  return false;
478
567
  }
568
+
569
+ // 如果配置的 product_variant_id = 0,只需要 product_id 匹配
479
570
  if (configVariantId === 0) {
480
571
  return true;
481
572
  }
573
+
574
+ // 否则需要 product_variant_id 精确匹配
482
575
  return configVariantId === actualVariantId;
483
576
  });
484
577
  }
578
+
485
579
  /**
486
580
  * 注册自定义运算符
487
581
  */
488
582
  registerOperator(operator, handler) {
489
583
  this.operatorHandlers.set(operator, handler);
490
584
  }
585
+
491
586
  /**
492
587
  * 获取调试信息
493
588
  */
@@ -498,17 +593,24 @@ var StrategyEngine = class {
498
593
  registeredOperators: Array.from(this.operatorHandlers.keys())
499
594
  };
500
595
  }
501
- };
596
+ }
597
+
598
+ // ============================================
599
+ // 导出工具函数
600
+ // ============================================
601
+
602
+ /**
603
+ * 创建策略引擎实例
604
+ */
605
+ exports.StrategyEngine = StrategyEngine;
502
606
  function createStrategyEngine(options) {
503
607
  return new StrategyEngine(options);
504
608
  }
609
+
610
+ /**
611
+ * 快速评估(使用默认引擎配置)
612
+ */
505
613
  function evaluate(config, context) {
506
614
  const engine = new StrategyEngine();
507
615
  return engine.evaluate(config, context);
508
- }
509
- // Annotate the CommonJS export names for ESM import in node:
510
- 0 && (module.exports = {
511
- StrategyEngine,
512
- createStrategyEngine,
513
- evaluate
514
- });
616
+ }