@pisell/pisellos 2.1.170 → 2.1.172

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 (231) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +1 -3
  3. package/dist/model/strategy/adapter/index.d.ts +0 -4
  4. package/dist/model/strategy/adapter/index.js +1 -5
  5. package/dist/model/strategy/adapter/promotion/evaluator.js +99 -26
  6. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  7. package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  8. package/dist/model/strategy/adapter/walletPass/evaluator.js +61 -8
  9. package/dist/model/strategy/adapter/walletPass/locales.js +12 -3
  10. package/dist/model/strategy/engine.d.ts +18 -5
  11. package/dist/model/strategy/engine.js +145 -45
  12. package/dist/model/strategy/type.d.ts +17 -0
  13. package/dist/model/strategy/type.js +4 -0
  14. package/dist/modules/Cart/types.d.ts +2 -0
  15. package/dist/modules/Cart/utils/cartProduct.js +56 -25
  16. package/dist/modules/Cart/utils/changePrice.js +9 -16
  17. package/dist/modules/Discount/index.d.ts +4 -13
  18. package/dist/modules/Discount/index.js +12 -124
  19. package/dist/modules/Discount/types.d.ts +18 -13
  20. package/dist/modules/Order/index.d.ts +1 -67
  21. package/dist/modules/Order/index.js +30 -918
  22. package/dist/modules/Order/types.d.ts +12 -176
  23. package/dist/modules/Order/types.js +0 -2
  24. package/dist/modules/Order/utils.d.ts +0 -118
  25. package/dist/modules/Order/utils.js +2 -586
  26. package/dist/modules/Payment/index.d.ts +2 -1
  27. package/dist/modules/Payment/index.js +10 -7
  28. package/dist/modules/Payment/utils.js +3 -0
  29. package/dist/modules/Payment/walletpass.d.ts +23 -0
  30. package/dist/modules/Payment/walletpass.js +191 -95
  31. package/dist/modules/Product/utils.js +2 -2
  32. package/dist/modules/ProductList/index.d.ts +2 -4
  33. package/dist/modules/ProductList/index.js +12 -24
  34. package/dist/modules/Rules/index.d.ts +9 -5
  35. package/dist/modules/Rules/index.js +669 -173
  36. package/dist/modules/Rules/types.d.ts +2 -0
  37. package/dist/modules/Schedule/getDateIsInSchedule.js +18 -16
  38. package/dist/modules/Schedule/utils.d.ts +1 -1
  39. package/dist/modules/Summary/types.d.ts +2 -0
  40. package/dist/modules/Summary/utils.d.ts +9 -3
  41. package/dist/modules/Summary/utils.js +57 -67
  42. package/dist/modules/index.d.ts +0 -4
  43. package/dist/modules/index.js +1 -5
  44. package/dist/plugins/window.d.ts +2 -0
  45. package/dist/solution/BookingByStep/index.d.ts +3 -2
  46. package/dist/solution/BookingByStep/index.js +43 -46
  47. package/dist/solution/BookingByStep/types.d.ts +1 -3
  48. package/dist/solution/BookingByStep/types.js +1 -5
  49. package/dist/solution/BookingByStep/utils/timeslots.d.ts +1 -3
  50. package/dist/solution/BookingByStep/utils/timeslots.js +12 -19
  51. package/dist/solution/Checkout/index.js +2 -0
  52. package/dist/solution/ShopDiscount/index.d.ts +2 -3
  53. package/dist/solution/ShopDiscount/index.js +60 -62
  54. package/dist/solution/ShopDiscount/types.d.ts +1 -1
  55. package/dist/solution/ShopDiscount/types.js +2 -1
  56. package/dist/solution/ShopDiscount/utils.js +26 -12
  57. package/dist/solution/index.d.ts +0 -2
  58. package/dist/solution/index.js +1 -3
  59. package/lib/index.d.ts +1 -1
  60. package/lib/index.js +3 -4
  61. package/lib/model/strategy/adapter/index.d.ts +0 -4
  62. package/lib/model/strategy/adapter/index.js +2 -13
  63. package/lib/model/strategy/adapter/promotion/evaluator.js +57 -8
  64. package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
  65. package/lib/model/strategy/adapter/walletPass/evaluator.js +34 -3
  66. package/lib/model/strategy/adapter/walletPass/locales.js +12 -3
  67. package/lib/model/strategy/engine.d.ts +18 -5
  68. package/lib/model/strategy/engine.js +85 -21
  69. package/lib/model/strategy/type.d.ts +17 -0
  70. package/lib/modules/Cart/types.d.ts +2 -0
  71. package/lib/modules/Cart/utils/cartProduct.js +39 -12
  72. package/lib/modules/Cart/utils/changePrice.js +9 -13
  73. package/lib/modules/Discount/index.d.ts +4 -13
  74. package/lib/modules/Discount/index.js +5 -76
  75. package/lib/modules/Discount/types.d.ts +18 -13
  76. package/lib/modules/Order/index.d.ts +1 -67
  77. package/lib/modules/Order/index.js +1 -525
  78. package/lib/modules/Order/types.d.ts +12 -176
  79. package/lib/modules/Order/utils.d.ts +0 -118
  80. package/lib/modules/Order/utils.js +2 -483
  81. package/lib/modules/Payment/index.d.ts +2 -1
  82. package/lib/modules/Payment/index.js +1 -0
  83. package/lib/modules/Payment/utils.js +3 -0
  84. package/lib/modules/Payment/walletpass.d.ts +23 -0
  85. package/lib/modules/Payment/walletpass.js +94 -17
  86. package/lib/modules/Product/utils.js +2 -2
  87. package/lib/modules/ProductList/index.d.ts +2 -4
  88. package/lib/modules/ProductList/index.js +39 -46
  89. package/lib/modules/Rules/index.d.ts +9 -5
  90. package/lib/modules/Rules/index.js +776 -292
  91. package/lib/modules/Rules/types.d.ts +2 -0
  92. package/lib/modules/Schedule/getDateIsInSchedule.js +11 -13
  93. package/lib/modules/Schedule/utils.d.ts +1 -1
  94. package/lib/modules/Summary/types.d.ts +2 -0
  95. package/lib/modules/Summary/utils.d.ts +9 -3
  96. package/lib/modules/Summary/utils.js +34 -45
  97. package/lib/modules/index.d.ts +0 -4
  98. package/lib/modules/index.js +1 -9
  99. package/lib/plugins/window.d.ts +2 -0
  100. package/lib/solution/BookingByStep/index.d.ts +3 -2
  101. package/lib/solution/BookingByStep/index.js +4 -6
  102. package/lib/solution/BookingByStep/types.d.ts +1 -3
  103. package/lib/solution/BookingByStep/types.js +0 -10
  104. package/lib/solution/BookingByStep/utils/timeslots.d.ts +1 -3
  105. package/lib/solution/BookingByStep/utils/timeslots.js +11 -19
  106. package/lib/solution/Checkout/index.js +2 -0
  107. package/lib/solution/ShopDiscount/index.d.ts +2 -3
  108. package/lib/solution/ShopDiscount/index.js +27 -22
  109. package/lib/solution/ShopDiscount/types.d.ts +1 -1
  110. package/lib/solution/ShopDiscount/utils.js +10 -6
  111. package/lib/solution/index.d.ts +0 -2
  112. package/lib/solution/index.js +1 -5
  113. package/package.json +2 -2
  114. package/dist/apis/picoding.d.ts +0 -0
  115. package/dist/apis/picoding.js +0 -1
  116. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
  117. package/dist/model/strategy/adapter/dataVariant/adapter.js +0 -167
  118. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
  119. package/dist/model/strategy/adapter/dataVariant/evaluator.js +0 -867
  120. package/dist/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
  121. package/dist/model/strategy/adapter/dataVariant/examples.js +0 -277
  122. package/dist/model/strategy/adapter/dataVariant/index.d.ts +0 -4
  123. package/dist/model/strategy/adapter/dataVariant/index.js +0 -4
  124. package/dist/model/strategy/adapter/dataVariant/type.d.ts +0 -149
  125. package/dist/model/strategy/adapter/dataVariant/type.js +0 -54
  126. package/dist/modules/OpenData/index.d.ts +0 -24
  127. package/dist/modules/OpenData/index.js +0 -173
  128. package/dist/modules/OpenData/types.d.ts +0 -73
  129. package/dist/modules/OpenData/types.js +0 -1
  130. package/dist/modules/OpenData/utils.d.ts +0 -2
  131. package/dist/modules/OpenData/utils.js +0 -75
  132. package/dist/modules/Quotation/index.d.ts +0 -48
  133. package/dist/modules/Quotation/index.js +0 -248
  134. package/dist/modules/Quotation/types.d.ts +0 -42
  135. package/dist/modules/Quotation/types.js +0 -1
  136. package/dist/modules/SalesSummary/index.d.ts +0 -63
  137. package/dist/modules/SalesSummary/index.js +0 -174
  138. package/dist/modules/SalesSummary/types.d.ts +0 -60
  139. package/dist/modules/SalesSummary/types.js +0 -1
  140. package/dist/modules/SalesSummary/utils.d.ts +0 -30
  141. package/dist/modules/SalesSummary/utils.js +0 -480
  142. package/dist/modules/ScanOrderLogger/index.d.ts +0 -23
  143. package/dist/modules/ScanOrderLogger/index.js +0 -174
  144. package/dist/modules/ScanOrderLogger/providers/feishu.d.ts +0 -2
  145. package/dist/modules/ScanOrderLogger/providers/feishu.js +0 -221
  146. package/dist/modules/ScanOrderLogger/providers/grafana.d.ts +0 -2
  147. package/dist/modules/ScanOrderLogger/providers/grafana.js +0 -50
  148. package/dist/modules/ScanOrderLogger/types.d.ts +0 -53
  149. package/dist/modules/ScanOrderLogger/types.js +0 -1
  150. package/dist/solution/ScanOrder/index.d.ts +0 -158
  151. package/dist/solution/ScanOrder/index.js +0 -3474
  152. package/dist/solution/ScanOrder/types.d.ts +0 -306
  153. package/dist/solution/ScanOrder/types.js +0 -35
  154. package/dist/solution/ScanOrder/utils.d.ts +0 -172
  155. package/dist/solution/ScanOrder/utils.js +0 -796
  156. package/dist/solution/VenueBooking/index.d.ts +0 -252
  157. package/dist/solution/VenueBooking/index.js +0 -3769
  158. package/dist/solution/VenueBooking/sales-section-4-annotated.json +0 -343
  159. package/dist/solution/VenueBooking/types.d.ts +0 -156
  160. package/dist/solution/VenueBooking/types.js +0 -22
  161. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +0 -11
  162. package/dist/solution/VenueBooking/utils/dateSummary.js +0 -91
  163. package/dist/solution/VenueBooking/utils/resource.d.ts +0 -14
  164. package/dist/solution/VenueBooking/utils/resource.js +0 -131
  165. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +0 -32
  166. package/dist/solution/VenueBooking/utils/slotMerge.js +0 -233
  167. package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -71
  168. package/dist/solution/VenueBooking/utils/smartPricing.js +0 -302
  169. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -34
  170. package/dist/solution/VenueBooking/utils/timeSlot.js +0 -458
  171. package/dist/solution/VenueBooking/utils.d.ts +0 -1
  172. package/dist/solution/VenueBooking/utils.js +0 -1
  173. package/lib/apis/picoding.d.ts +0 -0
  174. package/lib/apis/picoding.js +0 -0
  175. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
  176. package/lib/model/strategy/adapter/dataVariant/adapter.js +0 -149
  177. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
  178. package/lib/model/strategy/adapter/dataVariant/evaluator.js +0 -666
  179. package/lib/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
  180. package/lib/model/strategy/adapter/dataVariant/examples.js +0 -293
  181. package/lib/model/strategy/adapter/dataVariant/index.d.ts +0 -4
  182. package/lib/model/strategy/adapter/dataVariant/index.js +0 -38
  183. package/lib/model/strategy/adapter/dataVariant/type.d.ts +0 -149
  184. package/lib/model/strategy/adapter/dataVariant/type.js +0 -31
  185. package/lib/modules/OpenData/index.d.ts +0 -24
  186. package/lib/modules/OpenData/index.js +0 -119
  187. package/lib/modules/OpenData/types.d.ts +0 -73
  188. package/lib/modules/OpenData/types.js +0 -17
  189. package/lib/modules/OpenData/utils.d.ts +0 -2
  190. package/lib/modules/OpenData/utils.js +0 -111
  191. package/lib/modules/Quotation/index.d.ts +0 -48
  192. package/lib/modules/Quotation/index.js +0 -152
  193. package/lib/modules/Quotation/types.d.ts +0 -42
  194. package/lib/modules/Quotation/types.js +0 -17
  195. package/lib/modules/SalesSummary/index.d.ts +0 -63
  196. package/lib/modules/SalesSummary/index.js +0 -105
  197. package/lib/modules/SalesSummary/types.d.ts +0 -60
  198. package/lib/modules/SalesSummary/types.js +0 -17
  199. package/lib/modules/SalesSummary/utils.d.ts +0 -30
  200. package/lib/modules/SalesSummary/utils.js +0 -420
  201. package/lib/modules/ScanOrderLogger/index.d.ts +0 -23
  202. package/lib/modules/ScanOrderLogger/index.js +0 -147
  203. package/lib/modules/ScanOrderLogger/providers/feishu.d.ts +0 -2
  204. package/lib/modules/ScanOrderLogger/providers/feishu.js +0 -157
  205. package/lib/modules/ScanOrderLogger/providers/grafana.d.ts +0 -2
  206. package/lib/modules/ScanOrderLogger/providers/grafana.js +0 -52
  207. package/lib/modules/ScanOrderLogger/types.d.ts +0 -53
  208. package/lib/modules/ScanOrderLogger/types.js +0 -17
  209. package/lib/solution/ScanOrder/index.d.ts +0 -158
  210. package/lib/solution/ScanOrder/index.js +0 -2135
  211. package/lib/solution/ScanOrder/types.d.ts +0 -306
  212. package/lib/solution/ScanOrder/types.js +0 -36
  213. package/lib/solution/ScanOrder/utils.d.ts +0 -172
  214. package/lib/solution/ScanOrder/utils.js +0 -658
  215. package/lib/solution/VenueBooking/index.d.ts +0 -252
  216. package/lib/solution/VenueBooking/index.js +0 -2204
  217. package/lib/solution/VenueBooking/sales-section-4-annotated.json +0 -343
  218. package/lib/solution/VenueBooking/types.d.ts +0 -156
  219. package/lib/solution/VenueBooking/types.js +0 -45
  220. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +0 -11
  221. package/lib/solution/VenueBooking/utils/dateSummary.js +0 -105
  222. package/lib/solution/VenueBooking/utils/resource.d.ts +0 -14
  223. package/lib/solution/VenueBooking/utils/resource.js +0 -92
  224. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +0 -32
  225. package/lib/solution/VenueBooking/utils/slotMerge.js +0 -236
  226. package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -71
  227. package/lib/solution/VenueBooking/utils/smartPricing.js +0 -225
  228. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -34
  229. package/lib/solution/VenueBooking/utils/timeSlot.js +0 -343
  230. package/lib/solution/VenueBooking/utils.d.ts +0 -1
  231. package/lib/solution/VenueBooking/utils.js +0 -69
@@ -1,666 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
-
19
- // src/model/strategy/adapter/dataVariant/evaluator.ts
20
- var evaluator_exports = {};
21
- __export(evaluator_exports, {
22
- DataVariantEvaluator: () => DataVariantEvaluator,
23
- default: () => evaluator_default
24
- });
25
- module.exports = __toCommonJS(evaluator_exports);
26
- var import_engine = require("../../engine");
27
- var import_getDateIsInSchedule = require("../../../../modules/Schedule/getDateIsInSchedule");
28
- var import_adapter = require("./adapter");
29
- var DataVariantEvaluator = class {
30
- constructor() {
31
- this.strategyConfigs = [];
32
- this.adapter = new import_adapter.DataVariantAdapter();
33
- }
34
- /**
35
- * 设置策略配置列表,仅保留 metadata.type === 'data_variant' 的策略。
36
- */
37
- setStrategyConfigs(configs) {
38
- this.strategyConfigs = this.normalizeStrategyConfigs(configs);
39
- }
40
- getStrategyConfigs() {
41
- return this.strategyConfigs;
42
- }
43
- /**
44
- * 批量解析商品 Data Variant。
45
- *
46
- * 先执行全局预计算,再只针对商品自身 data_variants 引用到的规则做商品级判断。
47
- */
48
- resolveProducts(businessData) {
49
- var _a;
50
- const strategyConfigs = businessData.strategyConfigs ? this.normalizeStrategyConfigs(businessData.strategyConfigs) : this.strategyConfigs;
51
- const menuScopeMap = this.buildMenuScopeMap(businessData.menuList || []);
52
- const scheduleTimePoints = this.buildScheduleTimePoints(
53
- strategyConfigs,
54
- businessData.scheduleList || []
55
- );
56
- const { globalEffectiveRuleMap, rawResults } = this.buildGlobalEffectiveRuleMap(
57
- strategyConfigs,
58
- businessData,
59
- menuScopeMap
60
- );
61
- const productDiagnostics = businessData.debugLog ? [] : void 0;
62
- const products = businessData.products.map((product) => {
63
- const resolvedProduct = this.resolveProduct(
64
- product,
65
- businessData,
66
- globalEffectiveRuleMap,
67
- menuScopeMap,
68
- productDiagnostics
69
- );
70
- return this.resolveProductBundleItems(
71
- resolvedProduct,
72
- businessData,
73
- globalEffectiveRuleMap,
74
- menuScopeMap
75
- );
76
- });
77
- (_a = businessData == null ? void 0 : businessData.debugLog) == null ? void 0 : _a.call(businessData, "[VenueBooking][smartPricing] evaluator result", {
78
- scheduleDateTime: businessData.scheduleDateTime,
79
- strategyConfigs: strategyConfigs.map((config) => {
80
- var _a2, _b, _c, _d;
81
- return {
82
- ruleId: String((_a2 = config == null ? void 0 : config.metadata) == null ? void 0 : _a2.id),
83
- name: (_b = config == null ? void 0 : config.metadata) == null ? void 0 : _b.name,
84
- status: (_d = (_c = config == null ? void 0 : config.metadata) == null ? void 0 : _c.custom) == null ? void 0 : _d.status,
85
- priority: this.getStrategyPriority(config),
86
- conditions: config == null ? void 0 : config.conditions
87
- };
88
- }),
89
- globalRuleResults: rawResults.map((result) => {
90
- var _a2, _b, _c, _d;
91
- return {
92
- ruleId: String((_b = (_a2 = result == null ? void 0 : result.config) == null ? void 0 : _a2.metadata) == null ? void 0 : _b.id),
93
- name: (_d = (_c = result == null ? void 0 : result.config) == null ? void 0 : _c.metadata) == null ? void 0 : _d.name,
94
- applicable: result == null ? void 0 : result.applicable,
95
- code: result == null ? void 0 : result.code,
96
- message: result == null ? void 0 : result.message,
97
- matched: result == null ? void 0 : result.matched
98
- };
99
- }),
100
- effectiveRuleIds: Array.from(globalEffectiveRuleMap.keys()),
101
- productDiagnostics: productDiagnostics || []
102
- });
103
- return {
104
- products,
105
- globalEffectiveRuleMap,
106
- menuScopeMap,
107
- scheduleTimePoints,
108
- rawResults
109
- };
110
- }
111
- /**
112
- * 根据 operator/field 判断条件是否依赖当前商品。
113
- */
114
- getConditionScope(rule) {
115
- if (rule.operator === "schedule_match")
116
- return "global";
117
- if (rule.operator === "menu_match")
118
- return "product";
119
- if (rule.operator === "product_match")
120
- return "product";
121
- if (rule.field === "product" || rule.field === "productIdAndVariantId") {
122
- return "product";
123
- }
124
- return "global";
125
- }
126
- /**
127
- * 将餐牌 partyroom_package 预构建为 Map/Set 索引。
128
- */
129
- buildMenuScopeMap(menuList) {
130
- const map = /* @__PURE__ */ new Map();
131
- for (const menu of menuList) {
132
- if ((menu == null ? void 0 : menu.status) && menu.status !== "valid")
133
- continue;
134
- const menuId = this.toNumber(menu == null ? void 0 : menu.form_record_id);
135
- if (!menuId)
136
- continue;
137
- const scope = {
138
- isAllProducts: false,
139
- collectionIds: /* @__PURE__ */ new Set(),
140
- productKeys: /* @__PURE__ */ new Set(),
141
- productAllVariantIds: /* @__PURE__ */ new Set()
142
- };
143
- const packageConfig = menu.partyroom_package;
144
- const products = Array.isArray(packageConfig == null ? void 0 : packageConfig.products) ? packageConfig.products : [];
145
- if ((packageConfig == null ? void 0 : packageConfig.type) === "product_all") {
146
- scope.isAllProducts = true;
147
- } else if ((packageConfig == null ? void 0 : packageConfig.type) === "product_collection") {
148
- for (const item of products) {
149
- const collectionId = this.toNumber(item.product_collection_id);
150
- if (collectionId) {
151
- scope.collectionIds.add(collectionId);
152
- }
153
- }
154
- } else if ((packageConfig == null ? void 0 : packageConfig.type) === "products") {
155
- for (const item of products) {
156
- const productId = this.toNumber(item.product_id);
157
- const variantId = this.toNumber(item.product_variant_id);
158
- if (!productId)
159
- continue;
160
- if (variantId === 0) {
161
- scope.productAllVariantIds.add(productId);
162
- } else {
163
- scope.productKeys.add(this.buildProductKey(productId, variantId));
164
- }
165
- }
166
- }
167
- map.set(menuId, scope);
168
- }
169
- return map;
170
- }
171
- /**
172
- * 从当前策略中所有 schedule_match.value 绑定的 schedule_id 提取时间点。
173
- *
174
- * 这里不依赖餐牌,只读取策略配置和调用方传入的 scheduleList。
175
- */
176
- buildScheduleTimePoints(strategyConfigs, scheduleList) {
177
- const scheduleIds = this.collectScheduleIdsFromStrategies(strategyConfigs);
178
- if (!scheduleIds.length || !scheduleList.length)
179
- return [];
180
- const scheduleIdSet = new Set(scheduleIds);
181
- const matchedSchedules = scheduleList.filter(
182
- (schedule) => scheduleIdSet.has(Number(schedule.id))
183
- );
184
- return this.extractTimePointsFromSchedules(matchedSchedules);
185
- }
186
- buildGlobalEffectiveRuleMap(strategyConfigs, businessData, menuScopeMap) {
187
- const globalEffectiveRuleMap = /* @__PURE__ */ new Map();
188
- const rawResults = [];
189
- const engine = this.createEngine(businessData, menuScopeMap);
190
- const context = this.adapter.prepareGlobalContext(businessData);
191
- for (const config of strategyConfigs) {
192
- if (!this.isStrategyActive(config))
193
- continue;
194
- const { globalConfig, productRules } = this.splitStrategyConfig(config);
195
- const result = engine.evaluate(globalConfig, context);
196
- rawResults.push(result);
197
- if (!result.applicable)
198
- continue;
199
- globalEffectiveRuleMap.set(String(config.metadata.id), {
200
- ruleId: String(config.metadata.id),
201
- priority: this.getStrategyPriority(config),
202
- strategyConfig: config,
203
- productRules,
204
- globalResult: result
205
- });
206
- }
207
- return { globalEffectiveRuleMap, rawResults };
208
- }
209
- resolveProduct(product, businessData, globalEffectiveRuleMap, menuScopeMap, diagnostics) {
210
- var _a, _b;
211
- const dataVariants = this.getProductDataVariants(product);
212
- const productId = (product == null ? void 0 : product.id) ?? (product == null ? void 0 : product.product_id);
213
- if (!dataVariants.length) {
214
- diagnostics == null ? void 0 : diagnostics.push({
215
- productId,
216
- originalPrice: (product == null ? void 0 : product.price) ?? (product == null ? void 0 : product.selling_price),
217
- finalPrice: (product == null ? void 0 : product.price) ?? (product == null ? void 0 : product.selling_price),
218
- reason: "product has no data_variants",
219
- variants: []
220
- });
221
- return product;
222
- }
223
- const matchedVariants = [];
224
- const variantDiagnostics = [];
225
- for (const variant of dataVariants) {
226
- const ruleId = String(variant.data_variant_rule_id);
227
- const rule = globalEffectiveRuleMap.get(
228
- ruleId
229
- );
230
- if (!rule) {
231
- variantDiagnostics.push({
232
- ruleId,
233
- variantData: variant.data || {},
234
- globalRuleEffective: false,
235
- productRulesMatched: false,
236
- reason: "referenced rule is missing or its global conditions did not match"
237
- });
238
- continue;
239
- }
240
- const productRulesMatched = this.evaluateProductRules(rule, product, businessData, menuScopeMap);
241
- if (!productRulesMatched) {
242
- variantDiagnostics.push({
243
- ruleId,
244
- variantData: variant.data || {},
245
- globalRuleEffective: true,
246
- productRulesMatched: false,
247
- productRules: rule.productRules,
248
- reason: "product-level conditions did not match"
249
- });
250
- continue;
251
- }
252
- variantDiagnostics.push({
253
- ruleId,
254
- variantData: variant.data || {},
255
- globalRuleEffective: true,
256
- productRulesMatched: true,
257
- priority: rule.priority,
258
- reason: "variant matched and will be merged into the product"
259
- });
260
- matchedVariants.push({
261
- ruleId: rule.ruleId,
262
- priority: rule.priority,
263
- data: variant.data || {},
264
- variant
265
- });
266
- }
267
- if (!matchedVariants.length) {
268
- diagnostics == null ? void 0 : diagnostics.push({
269
- productId,
270
- originalPrice: (product == null ? void 0 : product.price) ?? (product == null ? void 0 : product.selling_price),
271
- finalPrice: (product == null ? void 0 : product.price) ?? (product == null ? void 0 : product.selling_price),
272
- reason: "no data_variant matched",
273
- variants: variantDiagnostics
274
- });
275
- return product;
276
- }
277
- const resolvedProduct = this.mergeMatchedVariants(product, matchedVariants);
278
- diagnostics == null ? void 0 : diagnostics.push({
279
- productId,
280
- originalPrice: (product == null ? void 0 : product.price) ?? (product == null ? void 0 : product.selling_price),
281
- finalPrice: (resolvedProduct == null ? void 0 : resolvedProduct.price) ?? (resolvedProduct == null ? void 0 : resolvedProduct.selling_price),
282
- appliedRuleIds: ((_a = resolvedProduct == null ? void 0 : resolvedProduct._dataVariant) == null ? void 0 : _a.appliedRuleIds) || [],
283
- appliedFields: ((_b = resolvedProduct == null ? void 0 : resolvedProduct._dataVariant) == null ? void 0 : _b.appliedFields) || [],
284
- variants: variantDiagnostics
285
- });
286
- return resolvedProduct;
287
- }
288
- /**
289
- * 解析套餐子商品上的 Data Variant 覆盖。
290
- *
291
- * bundle_item 以 bundle_product_id / bundle_variant_id 作为商品身份参与 product_match 等条件判断。
292
- */
293
- resolveProductBundleItems(product, businessData, globalEffectiveRuleMap, menuScopeMap) {
294
- const bundleGroups = product.bundle_group;
295
- if (!Array.isArray(bundleGroups) || bundleGroups.length === 0) {
296
- return product;
297
- }
298
- const resolvedGroups = bundleGroups.map((group) => {
299
- const bundleItems = group == null ? void 0 : group.bundle_item;
300
- if (!Array.isArray(bundleItems) || bundleItems.length === 0) {
301
- return group;
302
- }
303
- return {
304
- ...group,
305
- bundle_item: bundleItems.map(
306
- (item) => this.resolveBundleItem(
307
- item,
308
- businessData,
309
- globalEffectiveRuleMap,
310
- menuScopeMap
311
- )
312
- )
313
- };
314
- });
315
- return {
316
- ...product,
317
- bundle_group: resolvedGroups
318
- };
319
- }
320
- /**
321
- * 将 bundle_item 转为 DataVariantProduct 并评估 data_variants。
322
- */
323
- resolveBundleItem(item, businessData, globalEffectiveRuleMap, menuScopeMap) {
324
- const bundleProduct = this.toBundleItemDataVariantProduct(item);
325
- if (!this.getProductDataVariants(bundleProduct).length) {
326
- return item;
327
- }
328
- const resolvedItem = this.resolveProduct(
329
- bundleProduct,
330
- businessData,
331
- globalEffectiveRuleMap,
332
- menuScopeMap
333
- );
334
- return this.mergeBundleItemResolvedData(item, resolvedItem);
335
- }
336
- /**
337
- * bundle_item 的商品身份映射:bundle_product_id + bundle_variant_id。
338
- */
339
- toBundleItemDataVariantProduct(item) {
340
- const productId = item.bundle_product_id ?? item.product_id;
341
- const variantId = item.bundle_variant_id ?? item.variant_id ?? item.product_variant_id ?? 0;
342
- return {
343
- id: productId,
344
- product_id: productId,
345
- product_variant_id: variantId,
346
- variant_id: variantId,
347
- collection: item.collection,
348
- data_variants: item.data_variants
349
- };
350
- }
351
- /**
352
- * 仅回写命中的字段,避免污染 bundle_item 的结构字段。
353
- */
354
- mergeBundleItemResolvedData(originalItem, resolvedItem) {
355
- var _a;
356
- const appliedInfo = resolvedItem._dataVariant;
357
- if (!((_a = appliedInfo == null ? void 0 : appliedInfo.appliedFields) == null ? void 0 : _a.length)) {
358
- return originalItem;
359
- }
360
- const result = { ...originalItem };
361
- for (const field of appliedInfo.appliedFields) {
362
- if (resolvedItem[field] !== void 0) {
363
- result[field] = resolvedItem[field];
364
- }
365
- }
366
- result._dataVariant = appliedInfo;
367
- return result;
368
- }
369
- evaluateProductRules(rule, product, businessData, menuScopeMap) {
370
- if (!rule.productRules.length)
371
- return true;
372
- const engine = this.createEngine(businessData, menuScopeMap);
373
- const context = this.adapter.prepareProductContext(businessData, product);
374
- const productOnlyConfig = {
375
- ...rule.strategyConfig,
376
- conditions: {
377
- operator: "and",
378
- rules: rule.productRules,
379
- actionIds: rule.strategyConfig.conditions.actionIds || []
380
- }
381
- };
382
- return engine.evaluate(productOnlyConfig, context).applicable;
383
- }
384
- /**
385
- * 拆分策略条件。
386
- *
387
- * 当前 MVP 支持顶层 and 原子条件拆分;复杂条件保守地放到商品级完整判断。
388
- */
389
- splitStrategyConfig(config) {
390
- const conditions = config.conditions;
391
- const globalRules = [];
392
- const productRules = [];
393
- if (conditions.operator !== "and") {
394
- return {
395
- globalConfig: {
396
- ...config,
397
- conditions: this.createAlwaysTrueConditions(conditions.actionIds)
398
- },
399
- productRules: this.flattenConditionRules(conditions)
400
- };
401
- }
402
- for (const rule of conditions.rules) {
403
- if (this.isConditionGroup(rule)) {
404
- productRules.push(...this.flattenConditionRules(rule));
405
- continue;
406
- }
407
- if (this.getConditionScope(rule) === "product") {
408
- productRules.push(rule);
409
- } else {
410
- globalRules.push(rule);
411
- }
412
- }
413
- return {
414
- globalConfig: {
415
- ...config,
416
- conditions: {
417
- operator: "and",
418
- rules: globalRules,
419
- actionIds: conditions.actionIds || []
420
- }
421
- },
422
- productRules
423
- };
424
- }
425
- createEngine(businessData, menuScopeMap) {
426
- const operatorHandlers = {
427
- schedule_match: (fieldValue, compareValue) => this.evaluateScheduleMatch(
428
- fieldValue,
429
- compareValue,
430
- businessData.scheduleList || []
431
- ),
432
- menu_match: (fieldValue, compareValue) => this.evaluateMenuMatch(fieldValue, compareValue, menuScopeMap),
433
- array_intersects: (fieldValue, compareValue) => this.evaluateArrayIntersects(fieldValue, compareValue)
434
- };
435
- return new import_engine.StrategyEngine({
436
- debug: false,
437
- enableTrace: false,
438
- operatorHandlers
439
- });
440
- }
441
- evaluateScheduleMatch(fieldValue, compareValue, scheduleList) {
442
- const scheduleDateTime = String(fieldValue || "");
443
- const scheduleIds = this.normalizeNumberArray(compareValue);
444
- if (!scheduleIds.length)
445
- return true;
446
- if (!scheduleDateTime || !(scheduleList == null ? void 0 : scheduleList.length))
447
- return false;
448
- const matchedSchedules = scheduleList.filter(
449
- (schedule) => scheduleIds.includes(Number(schedule.id))
450
- );
451
- return (0, import_getDateIsInSchedule.getDateIsInSchedule)(scheduleDateTime, matchedSchedules);
452
- }
453
- evaluateMenuMatch(fieldValue, compareValue, menuScopeMap) {
454
- const menuIds = this.normalizeNumberArray(compareValue);
455
- if (!menuIds.length)
456
- return true;
457
- for (const menuId of menuIds) {
458
- const scope = menuScopeMap.get(menuId);
459
- if (!scope)
460
- continue;
461
- if (this.isProductInMenuScope(fieldValue, scope))
462
- return true;
463
- }
464
- return false;
465
- }
466
- evaluateArrayIntersects(fieldValue, compareValue) {
467
- const fieldValues = this.normalizeComparableArray(fieldValue);
468
- const compareValues = this.normalizeComparableArray(compareValue);
469
- if (!fieldValues.length || !compareValues.length)
470
- return false;
471
- const compareSet = new Set(compareValues);
472
- return fieldValues.some((item) => compareSet.has(item));
473
- }
474
- collectScheduleIdsFromStrategies(strategyConfigs) {
475
- const scheduleIds = /* @__PURE__ */ new Set();
476
- for (const config of strategyConfigs) {
477
- if (!this.isStrategyActive(config))
478
- continue;
479
- const rules = this.flattenConditionRules(config.conditions);
480
- for (const rule of rules) {
481
- if (rule.operator !== "schedule_match")
482
- continue;
483
- for (const scheduleId of this.normalizeNumberArray(rule.value)) {
484
- scheduleIds.add(scheduleId);
485
- }
486
- }
487
- }
488
- return Array.from(scheduleIds);
489
- }
490
- extractTimePointsFromSchedules(schedules) {
491
- const timePoints = /* @__PURE__ */ new Set();
492
- for (const schedule of schedules) {
493
- switch (schedule.type) {
494
- case "standard": {
495
- this.addDateTimePoint(timePoints, schedule.start_time);
496
- this.addDateTimePoint(timePoints, schedule.end_time);
497
- break;
498
- }
499
- case "time-slots": {
500
- const slots = Array.isArray(schedule.time_slot) ? schedule.time_slot : [];
501
- for (const slot of slots) {
502
- this.addRawTimePoint(timePoints, slot.start_time);
503
- this.addRawTimePoint(timePoints, slot.end_time);
504
- }
505
- break;
506
- }
507
- case "designation": {
508
- const designations = Array.isArray(schedule.designation) ? schedule.designation : schedule.designation ? [schedule.designation] : [];
509
- for (const designation of designations) {
510
- this.addRawTimePoint(timePoints, designation.start_time);
511
- this.addRawTimePoint(timePoints, designation.end_time);
512
- }
513
- break;
514
- }
515
- default:
516
- break;
517
- }
518
- }
519
- return Array.from(timePoints).sort(
520
- (a, b) => this.timeToMinutes(a) - this.timeToMinutes(b)
521
- );
522
- }
523
- addDateTimePoint(points, value) {
524
- const time = this.extractTimeFromDateTime(value);
525
- if (time)
526
- points.add(time);
527
- }
528
- addRawTimePoint(points, value) {
529
- const time = this.normalizeTime(value);
530
- if (time)
531
- points.add(time);
532
- }
533
- extractTimeFromDateTime(value) {
534
- if (!value)
535
- return null;
536
- const match = value.match(/(\d{1,2}):(\d{2})/);
537
- if (!match)
538
- return null;
539
- return `${match[1].padStart(2, "0")}:${match[2]}`;
540
- }
541
- normalizeTime(value) {
542
- if (!value)
543
- return null;
544
- const match = value.match(/^(\d{1,2}):(\d{2})/);
545
- if (!match)
546
- return null;
547
- return `${match[1].padStart(2, "0")}:${match[2]}`;
548
- }
549
- timeToMinutes(value) {
550
- const [hour, minute] = value.split(":").map((item) => Number(item));
551
- if (!Number.isFinite(hour) || !Number.isFinite(minute))
552
- return 0;
553
- return hour * 60 + minute;
554
- }
555
- isProductInMenuScope(product, scope) {
556
- if (scope.isAllProducts)
557
- return true;
558
- if (!product || typeof product !== "object")
559
- return false;
560
- const productId = this.toNumber(product.id ?? product.product_id);
561
- const variantId = this.toNumber(product.product_variant_id);
562
- const productKey = this.buildProductKey(productId, variantId);
563
- const collectionIds = Array.isArray(product.collection_ids) ? product.collection_ids.map((id) => this.toNumber(id)) : [];
564
- return collectionIds.some((id) => scope.collectionIds.has(id)) || scope.productKeys.has(productKey) || scope.productAllVariantIds.has(productId);
565
- }
566
- mergeMatchedVariants(product, matchedVariants) {
567
- const original = { ...product };
568
- const sortedVariants = [...matchedVariants].sort((a, b) => {
569
- if (a.priority !== b.priority)
570
- return a.priority - b.priority;
571
- return Number(a.ruleId) - Number(b.ruleId);
572
- });
573
- const result = { ...product };
574
- const appliedRuleIds = [];
575
- const appliedFields = /* @__PURE__ */ new Set();
576
- for (const matched of sortedVariants) {
577
- for (const [key, value] of Object.entries(matched.data)) {
578
- if (value === void 0)
579
- continue;
580
- result[key] = value;
581
- appliedFields.add(key);
582
- }
583
- appliedRuleIds.push(matched.ruleId);
584
- }
585
- result._dataVariant = {
586
- appliedRuleIds,
587
- appliedFields: Array.from(appliedFields),
588
- original
589
- };
590
- return result;
591
- }
592
- getProductDataVariants(product) {
593
- return Array.isArray(product.data_variants) ? product.data_variants : [];
594
- }
595
- normalizeStrategyConfigs(configs) {
596
- return configs.filter(
597
- (config) => {
598
- var _a;
599
- return ((_a = config == null ? void 0 : config.metadata) == null ? void 0 : _a.type) === "data_variant";
600
- }
601
- );
602
- }
603
- isStrategyActive(config) {
604
- var _a;
605
- const status = (_a = config.metadata.custom) == null ? void 0 : _a.status;
606
- return !status || status === "active";
607
- }
608
- getStrategyPriority(config) {
609
- var _a;
610
- const priority = Number((_a = config.metadata.custom) == null ? void 0 : _a.priority);
611
- if (Number.isFinite(priority))
612
- return priority;
613
- return Math.max(
614
- 0,
615
- ...config.actions.map((action) => Number(action.priority || 0))
616
- );
617
- }
618
- createAlwaysTrueConditions(actionIds) {
619
- return {
620
- operator: "and",
621
- rules: [],
622
- actionIds
623
- };
624
- }
625
- flattenConditionRules(group) {
626
- const rules = [];
627
- for (const rule of group.rules) {
628
- if (this.isConditionGroup(rule)) {
629
- rules.push(...this.flattenConditionRules(rule));
630
- } else {
631
- rules.push(rule);
632
- }
633
- }
634
- return rules;
635
- }
636
- isConditionGroup(rule) {
637
- return "rules" in rule && Array.isArray(rule.rules);
638
- }
639
- normalizeNumberArray(value) {
640
- if (!Array.isArray(value))
641
- return [];
642
- return value.map((item) => this.toNumber(item)).filter((item) => item > 0);
643
- }
644
- normalizeComparableArray(value) {
645
- const list = Array.isArray(value) ? value : value == null || value === "" ? [] : [value];
646
- const normalized = list.map((item) => {
647
- if (item == null || item === "")
648
- return "";
649
- const parsed = Number(item);
650
- return Number.isFinite(parsed) ? String(parsed) : String(item).trim();
651
- }).filter(Boolean);
652
- return Array.from(new Set(normalized));
653
- }
654
- buildProductKey(productId, variantId) {
655
- return `${productId}:${variantId}`;
656
- }
657
- toNumber(value) {
658
- const parsed = Number(value);
659
- return Number.isFinite(parsed) ? parsed : 0;
660
- }
661
- };
662
- var evaluator_default = DataVariantEvaluator;
663
- // Annotate the CommonJS export names for ESM import in node:
664
- 0 && (module.exports = {
665
- DataVariantEvaluator
666
- });
@@ -1,39 +0,0 @@
1
- import type { StrategyConfig } from '../../type';
2
- import type { ScheduleItem } from '../../../../modules/Schedule/types';
3
- import type { DataVariantItem, DataVariantMenu, DataVariantProduct, DataVariantRuleMetadata } from './type';
4
- /**
5
- * 构造示例用 data_variant 记录,字段结构与后端 /product/query 返回一致。
6
- */
7
- export declare function createExampleDataVariant(ruleId: number | string, data: Record<string, any>, overrides?: Partial<Omit<DataVariantItem, 'data_variant_rule_id' | 'data'>>): DataVariantItem;
8
- /**
9
- * 晚场餐牌价:命中日程 + 餐牌商品范围后覆盖 price / stock。
10
- */
11
- export declare const EVENING_MENU_PRICE_STRATEGY: StrategyConfig<DataVariantRuleMetadata>;
12
- /**
13
- * VIP 商品价:演示 product_match 与更高优先级字段覆盖。
14
- */
15
- export declare const VIP_PRODUCT_PRICE_STRATEGY: StrategyConfig<DataVariantRuleMetadata>;
16
- /**
17
- * 客户/渠道/业务范围价:演示 customer_id、channel、business_code 的 in 条件。
18
- */
19
- export declare const CUSTOMER_SCOPE_PRICE_STRATEGY: StrategyConfig<DataVariantRuleMetadata>;
20
- /**
21
- * 示例日程:2026-06-26 17:00 ~ 20:00 生效。
22
- */
23
- export declare const DATA_VARIANT_EXAMPLE_SCHEDULES: ScheduleItem[];
24
- /**
25
- * 示例餐牌:product_collection = 128 的商品均属于餐牌。
26
- */
27
- export declare const DATA_VARIANT_EXAMPLE_MENUS: DataVariantMenu[];
28
- /**
29
- * 示例商品:同时带两条 Data Variant 覆盖数据。
30
- */
31
- export declare const DATA_VARIANT_EXAMPLE_PRODUCTS: DataVariantProduct[];
32
- /**
33
- * Data Variant 评估器示例调用。
34
- */
35
- export declare function runDataVariantDemo(): import("./type").ResolvedDataVariantResult;
36
- /**
37
- * 客户/渠道/业务范围条件示例调用。
38
- */
39
- export declare function runCustomerScopeDataVariantDemo(): import("./type").ResolvedDataVariantResult;