@pisell/pisellos 0.0.458 → 0.0.460

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.
@@ -0,0 +1,447 @@
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 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; }
3
+ 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; }
4
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5
+ 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); } }
6
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
7
+ 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; }
8
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
9
+ 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); }
10
+ import { PROMOTION_ACTION_TYPES } from "./type";
11
+ // 导出类型定义
12
+ // export * from './type';
13
+
14
+ // 导出评估器
15
+ import { PromotionEvaluator } from "./evaluator";
16
+ export { PromotionEvaluator };
17
+
18
+ // ============================================
19
+ // Promotion 适配器实现
20
+ // ============================================
21
+
22
+ /**
23
+ * Promotion 适配器
24
+ *
25
+ * 用于将促销活动业务数据转换为策略引擎可识别的格式
26
+ * 策略引擎只负责匹配,具体的优惠计算由业务层完成
27
+ */
28
+ export var PromotionAdapter = /*#__PURE__*/function () {
29
+ function PromotionAdapter() {
30
+ _classCallCheck(this, PromotionAdapter);
31
+ _defineProperty(this, "name", 'PromotionAdapter');
32
+ _defineProperty(this, "version", '1.0.0');
33
+ }
34
+ _createClass(PromotionAdapter, [{
35
+ key: "prepareContext",
36
+ value:
37
+ /**
38
+ * 准备运行时上下文
39
+ *
40
+ * 将业务数据转换为策略引擎可识别的 RuntimeContext
41
+ */
42
+ function prepareContext(businessData) {
43
+ var products = businessData.products,
44
+ currentProduct = businessData.currentProduct,
45
+ channel = businessData.channel,
46
+ custom = businessData.custom;
47
+
48
+ // 当前时间(用于时间条件判断)
49
+ var now = new Date();
50
+ var currentDateTime = this.formatDateTime(now);
51
+
52
+ // 如果有 currentProduct,用于单商品场景(商品卡片展示)
53
+ var evaluatingProduct = currentProduct || (products.length > 0 ? products[0] : null);
54
+ return {
55
+ entities: {
56
+ products: products,
57
+ currentProduct: evaluatingProduct
58
+ },
59
+ attributes: _objectSpread({
60
+ // 当前时间(格式化字符串,用于时间条件判断)
61
+ currentDateTime: currentDateTime,
62
+ // 当前评估的商品信息(用于 product_match 运算符)
63
+ productIdAndVariantId: evaluatingProduct ? {
64
+ product_id: evaluatingProduct.product_id,
65
+ product_variant_id: evaluatingProduct.product_variant_id
66
+ } : null,
67
+ // 渠道
68
+ channel: channel || '',
69
+ // 商品总数量
70
+ totalQuantity: products.reduce(function (sum, p) {
71
+ return sum + p.quantity;
72
+ }, 0),
73
+ // 商品总金额
74
+ totalAmount: products.reduce(function (sum, p) {
75
+ return sum + p.price * p.quantity;
76
+ }, 0)
77
+ }, custom),
78
+ metadata: {
79
+ timestamp: Date.now()
80
+ }
81
+ };
82
+ }
83
+
84
+ /**
85
+ * 转换执行结果
86
+ *
87
+ * 将策略引擎的通用结果转换为业务层需要的格式
88
+ * 主要是整理 matchedActions,让业务层更容易使用
89
+ */
90
+ }, {
91
+ key: "transformResult",
92
+ value: function transformResult(result, businessData) {
93
+ // 获取适用的商品列表
94
+ var applicableProducts = businessData ? this.getApplicableProducts(result, businessData) : [];
95
+ if (!result.applicable) {
96
+ return {
97
+ isApplicable: false,
98
+ applicableProducts: [],
99
+ reason: result.message,
100
+ reasonCode: result.code,
101
+ strategyResult: result
102
+ };
103
+ }
104
+
105
+ // 获取第一个匹配的 action(按 priority 排序后的)
106
+ var matchedAction = result.matchedActions[0];
107
+ if (!matchedAction) {
108
+ return {
109
+ isApplicable: false,
110
+ applicableProducts: [],
111
+ reason: 'No matched action',
112
+ reasonCode: 'NO_ACTION',
113
+ strategyResult: result
114
+ };
115
+ }
116
+
117
+ // 解析 action 详情
118
+ var actionDetail = this.parseActionDetail(matchedAction);
119
+ return {
120
+ isApplicable: true,
121
+ actionType: matchedAction.type,
122
+ actionDetail: actionDetail,
123
+ applicableProducts: applicableProducts,
124
+ strategyResult: result
125
+ };
126
+ }
127
+
128
+ /**
129
+ * 格式化配置
130
+ */
131
+ }, {
132
+ key: "formatConfig",
133
+ value: function formatConfig(result, businessData) {
134
+ return {
135
+ result: result,
136
+ businessData: businessData
137
+ };
138
+ }
139
+
140
+ // ============================================
141
+ // 私有辅助方法
142
+ // ============================================
143
+
144
+ /**
145
+ * 格式化日期时间
146
+ */
147
+ }, {
148
+ key: "formatDateTime",
149
+ value: function formatDateTime(date) {
150
+ var year = date.getFullYear();
151
+ var month = String(date.getMonth() + 1).padStart(2, '0');
152
+ var day = String(date.getDate()).padStart(2, '0');
153
+ var hours = String(date.getHours()).padStart(2, '0');
154
+ var minutes = String(date.getMinutes()).padStart(2, '0');
155
+ var seconds = String(date.getSeconds()).padStart(2, '0');
156
+ return "".concat(year, "-").concat(month, "-").concat(day, " ").concat(hours, ":").concat(minutes, ":").concat(seconds);
157
+ }
158
+
159
+ /**
160
+ * 解析 Action 详情
161
+ *
162
+ * 将 matchedAction 转换为更易用的结构
163
+ */
164
+ }, {
165
+ key: "parseActionDetail",
166
+ value: function parseActionDetail(action) {
167
+ switch (action.type) {
168
+ case PROMOTION_ACTION_TYPES.X_ITEMS_FOR_Y_PRICE:
169
+ return this.parseXItemsForYPriceAction(action);
170
+ case PROMOTION_ACTION_TYPES.BUY_X_GET_Y_FREE:
171
+ return this.parseBuyXGetYFreeAction(action);
172
+ default:
173
+ return undefined;
174
+ }
175
+ }
176
+
177
+ /**
178
+ * 解析 X件Y元 Action
179
+ */
180
+ }, {
181
+ key: "parseXItemsForYPriceAction",
182
+ value: function parseXItemsForYPriceAction(action) {
183
+ var _config$allowCrossPro, _config$cumulative;
184
+ var value = action.value || {};
185
+ var config = action.config || {};
186
+ return {
187
+ type: PROMOTION_ACTION_TYPES.X_ITEMS_FOR_Y_PRICE,
188
+ x: value.x || 2,
189
+ price: value.price || 0,
190
+ allowCrossProduct: (_config$allowCrossPro = config.allowCrossProduct) !== null && _config$allowCrossPro !== void 0 ? _config$allowCrossPro : true,
191
+ cumulative: (_config$cumulative = config.cumulative) !== null && _config$cumulative !== void 0 ? _config$cumulative : true
192
+ };
193
+ }
194
+
195
+ /**
196
+ * 解析 买X送Y Action
197
+ */
198
+ }, {
199
+ key: "parseBuyXGetYFreeAction",
200
+ value: function parseBuyXGetYFreeAction(action) {
201
+ var _config$cumulative2;
202
+ var value = action.value || {};
203
+ var config = action.config || {};
204
+ return {
205
+ type: PROMOTION_ACTION_TYPES.BUY_X_GET_Y_FREE,
206
+ buyQuantity: value.buyQuantity || 1,
207
+ freeQuantity: value.freeQuantity || 1,
208
+ giftSelectionMode: config.giftSelectionMode || 'user_select',
209
+ cumulative: (_config$cumulative2 = config.cumulative) !== null && _config$cumulative2 !== void 0 ? _config$cumulative2 : true,
210
+ giftProducts: config.giftProducts || []
211
+ };
212
+ }
213
+
214
+ /**
215
+ * 获取适用的商品列表
216
+ *
217
+ * 从购物车商品中筛选出符合策略条件的商品
218
+ */
219
+ }, {
220
+ key: "getApplicableProducts",
221
+ value: function getApplicableProducts(result, businessData) {
222
+ var _this = this;
223
+ var products = businessData.products;
224
+
225
+ // 从策略配置中获取商品范围条件
226
+ var productMatchRule = this.findProductMatchRule(result.config);
227
+ if (!productMatchRule) {
228
+ // 如果没有商品范围条件,所有商品都适用
229
+ return products;
230
+ }
231
+ var configProducts = productMatchRule.value;
232
+
233
+ // 筛选适用的商品
234
+ return products.filter(function (product) {
235
+ return _this.isProductMatch(product, configProducts);
236
+ });
237
+ }
238
+
239
+ /**
240
+ * 查找商品匹配规则
241
+ */
242
+ }, {
243
+ key: "findProductMatchRule",
244
+ value: function findProductMatchRule(config) {
245
+ var _config$conditions;
246
+ if (!(config !== null && config !== void 0 && (_config$conditions = config.conditions) !== null && _config$conditions !== void 0 && _config$conditions.rules)) {
247
+ return null;
248
+ }
249
+ return config.conditions.rules.find(function (rule) {
250
+ return rule.field === 'productIdAndVariantId' && (rule.operator === 'product_match' || rule.operator === 'object_in');
251
+ });
252
+ }
253
+
254
+ /**
255
+ * 检查商品是否匹配
256
+ */
257
+ }, {
258
+ key: "isProductMatch",
259
+ value: function isProductMatch(product, configProducts) {
260
+ return configProducts.some(function (config) {
261
+ // 首先检查 product_id
262
+ if (config.product_id !== product.product_id) {
263
+ return false;
264
+ }
265
+
266
+ // 如果配置的 product_variant_id = 0,只需要 product_id 匹配
267
+ if (config.product_variant_id === 0) {
268
+ return true;
269
+ }
270
+
271
+ // 否则需要 product_variant_id 精确匹配
272
+ return config.product_variant_id === product.product_variant_id;
273
+ });
274
+ }
275
+ }]);
276
+ return PromotionAdapter;
277
+ }();
278
+
279
+ // 导出默认实例
280
+ export default PromotionAdapter;
281
+
282
+ /**
283
+ * X件Y元策略配置示例
284
+ *
285
+ * 业务规则:
286
+ * - 每X件商品固定价格Y元(可累计)
287
+ * - 支持跨商品组合(A+B可以凑成一组)
288
+ * - 买5件 = 2组优惠 + 1件原价
289
+ *
290
+ * 商品匹配规则:
291
+ * - product_variant_id = 0 表示匹配任意变体
292
+ * - product_variant_id != 0 表示精确匹配该变体
293
+ */
294
+ export var X_ITEMS_FOR_Y_PRICE_STRATEGY = {
295
+ metadata: {
296
+ id: 'STRATEGY_001',
297
+ name: {
298
+ en: '2 items for $10',
299
+ 'zh-CN': '2杯10元',
300
+ 'zh-HK': '2杯10元'
301
+ },
302
+ type: 'promotion',
303
+ custom: {
304
+ display: {
305
+ product_card: {
306
+ text: {
307
+ en: '2 for $10',
308
+ 'zh-CN': '2杯10元',
309
+ 'zh-HK': '2杯10元'
310
+ },
311
+ type: 'tag'
312
+ }
313
+ }
314
+ }
315
+ },
316
+ conditions: {
317
+ operator: 'and',
318
+ rules: [{
319
+ type: 'operator',
320
+ field: 'currentDateTime',
321
+ value: '2023-01-01 00:00:00',
322
+ operator: '>='
323
+ }, {
324
+ type: 'operator',
325
+ field: 'currentDateTime',
326
+ value: '2027-01-01 00:00:00',
327
+ operator: '<='
328
+ }, {
329
+ type: 'operator',
330
+ field: 'productIdAndVariantId',
331
+ value: [{
332
+ product_id: 60736,
333
+ product_variant_id: 0 // 0 = 匹配任意变体
334
+ }, {
335
+ product_id: 60737,
336
+ product_variant_id: 0 // 0 = 匹配任意变体
337
+ }],
338
+ operator: 'product_match'
339
+ }],
340
+ actionIds: ['1']
341
+ },
342
+ actions: [{
343
+ id: '1',
344
+ type: 'X_ITEMS_FOR_Y_PRICE',
345
+ value: {
346
+ x: 2,
347
+ // 每X件
348
+ price: 10 // 固定价格Y元
349
+ },
350
+ valueType: 'object',
351
+ target: 'product',
352
+ priority: 1,
353
+ config: {
354
+ allowCrossProduct: true,
355
+ // 允许跨商品组合(A+B可以凑成一组)
356
+ cumulative: true // 可累计(买5件 = 2组优惠 + 1件原价)
357
+ }
358
+ }]
359
+ };
360
+
361
+ /**
362
+ * 买X送Y策略配置示例
363
+ *
364
+ * 业务规则:
365
+ * - 买X件送Y件(可累计:买2送2、买3送3...)
366
+ * - 赠品由用户从列表中选择
367
+ *
368
+ * 商品匹配规则:
369
+ * - product_variant_id = 0 表示匹配任意变体
370
+ * - product_variant_id != 0 表示精确匹配该变体
371
+ */
372
+ export var BUY_X_GET_Y_FREE_STRATEGY = {
373
+ metadata: {
374
+ id: 'STRATEGY_002',
375
+ name: {
376
+ en: 'Buy 1 Get 1 Free',
377
+ 'zh-CN': '买1送1',
378
+ 'zh-HK': '買1送1'
379
+ },
380
+ type: 'promotion',
381
+ custom: {
382
+ display: {
383
+ product_card: {
384
+ text: {
385
+ en: 'Buy 1 Get 1',
386
+ 'zh-CN': '买1送1',
387
+ 'zh-HK': '買1送1'
388
+ },
389
+ type: 'tag'
390
+ }
391
+ }
392
+ }
393
+ },
394
+ conditions: {
395
+ operator: 'and',
396
+ rules: [{
397
+ type: 'operator',
398
+ field: 'currentDateTime',
399
+ value: '2023-01-01 00:00:00',
400
+ operator: '>='
401
+ }, {
402
+ type: 'operator',
403
+ field: 'currentDateTime',
404
+ value: '2027-01-01 00:00:00',
405
+ operator: '<='
406
+ }, {
407
+ type: 'operator',
408
+ field: 'productIdAndVariantId',
409
+ value: [{
410
+ product_id: 60736,
411
+ product_variant_id: 0 // 0 = 匹配任意变体
412
+ }, {
413
+ product_id: 60737,
414
+ product_variant_id: 0 // 0 = 匹配任意变体
415
+ }],
416
+ operator: 'product_match'
417
+ }],
418
+ actionIds: ['1']
419
+ },
420
+ actions: [{
421
+ id: '1',
422
+ type: 'BUY_X_GET_Y_FREE',
423
+ value: {
424
+ buyQuantity: 1,
425
+ // 买X件
426
+ freeQuantity: 1 // 送Y件
427
+ },
428
+ valueType: 'object',
429
+ target: 'product',
430
+ priority: 1,
431
+ config: {
432
+ // 可累计(买2送2、买3送3...)
433
+ cumulative: true,
434
+ // 可选的赠品列表
435
+ giftProducts: [{
436
+ product_id: 60757,
437
+ product_variant_id: 0
438
+ }, {
439
+ product_id: 38782,
440
+ product_variant_id: 0
441
+ }, {
442
+ product_id: 60749,
443
+ product_variant_id: 27267
444
+ }]
445
+ }
446
+ }]
447
+ };
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
49
49
  getCategories(): ProductCategory[];
50
50
  setOtherParams(key: string, value: any): void;
51
51
  getOtherParams(): any;
52
- getProductType(): "duration" | "session" | "normal";
52
+ getProductType(): "normal" | "duration" | "session";
53
53
  }
@@ -2215,6 +2215,7 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2215
2215
  // 计算容量的辅助函数
2216
2216
  var calculateCapacityFromCartItems = function calculateCapacityFromCartItems(items) {
2217
2217
  var _items$0$_resourceOri;
2218
+ if (items.length === 0) return 0;
2218
2219
  // 还需要增加一个判断,maxCapacity 必须是我单个人里选择的资源只有同一种的情况下才可以累加,否则单个账号都是 1
2219
2220
  var firstResource = (_items$0$_resourceOri = items[0]._resourceOrigin) === null || _items$0$_resourceOri === void 0 ? void 0 : _items$0$_resourceOri[0].id;
2220
2221
  var sameResourceLength = items.filter(function (item) {
@@ -2389,6 +2390,7 @@ export var BookingByStepImpl = /*#__PURE__*/function (_BaseModule) {
2389
2390
  // 计算容量的辅助函数
2390
2391
  calculateCapacityFromCartItems = function calculateCapacityFromCartItems(items) {
2391
2392
  var _items$0$_resourceOri2;
2393
+ if (items.length === 0) return 0;
2392
2394
  // 还需要增加一个判断,maxCapacity 必须是我单个人里选择的资源只有同一种的情况下才可以累加,否则单个账号都是 1
2393
2395
  var firstResource = (_items$0$_resourceOri2 = items[0]._resourceOrigin) === null || _items$0$_resourceOri2 === void 0 ? void 0 : _items$0$_resourceOri2[0].id;
2394
2396
  var sameResourceLength = items.filter(function (item) {
@@ -123,7 +123,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
123
123
  * 获取当前的客户搜索条件
124
124
  * @returns 当前搜索条件
125
125
  */
126
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
126
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
127
127
  /**
128
128
  * 获取客户列表状态(包含滚动加载相关状态)
129
129
  * @returns 客户状态
@@ -1,386 +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/promotion/index.ts
20
- var promotion_exports = {};
21
- __export(promotion_exports, {
22
- BUY_X_GET_Y_FREE_STRATEGY: () => BUY_X_GET_Y_FREE_STRATEGY,
23
- PromotionAdapter: () => PromotionAdapter,
24
- PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
25
- X_ITEMS_FOR_Y_PRICE_STRATEGY: () => X_ITEMS_FOR_Y_PRICE_STRATEGY,
26
- default: () => promotion_default
27
- });
28
- module.exports = __toCommonJS(promotion_exports);
29
- var import_type = require("./type");
30
- var import_evaluator = require("./evaluator");
31
- var PromotionAdapter = class {
32
- constructor() {
33
- this.name = "PromotionAdapter";
34
- this.version = "1.0.0";
35
- }
36
- /**
37
- * 准备运行时上下文
38
- *
39
- * 将业务数据转换为策略引擎可识别的 RuntimeContext
40
- */
41
- prepareContext(businessData) {
42
- const { products, currentProduct, channel, custom } = businessData;
43
- const now = /* @__PURE__ */ new Date();
44
- const currentDateTime = this.formatDateTime(now);
45
- const evaluatingProduct = currentProduct || (products.length > 0 ? products[0] : null);
46
- return {
47
- entities: {
48
- products,
49
- currentProduct: evaluatingProduct
50
- },
51
- attributes: {
52
- // 当前时间(格式化字符串,用于时间条件判断)
53
- currentDateTime,
54
- // 当前评估的商品信息(用于 product_match 运算符)
55
- productIdAndVariantId: evaluatingProduct ? {
56
- product_id: evaluatingProduct.product_id,
57
- product_variant_id: evaluatingProduct.product_variant_id
58
- } : null,
59
- // 渠道
60
- channel: channel || "",
61
- // 商品总数量
62
- totalQuantity: products.reduce((sum, p) => sum + p.quantity, 0),
63
- // 商品总金额
64
- totalAmount: products.reduce((sum, p) => sum + p.price * p.quantity, 0),
65
- // 自定义属性
66
- ...custom
67
- },
68
- metadata: {
69
- timestamp: Date.now()
70
- }
71
- };
72
- }
73
- /**
74
- * 转换执行结果
75
- *
76
- * 将策略引擎的通用结果转换为业务层需要的格式
77
- * 主要是整理 matchedActions,让业务层更容易使用
78
- */
79
- transformResult(result, businessData) {
80
- const applicableProducts = businessData ? this.getApplicableProducts(result, businessData) : [];
81
- if (!result.applicable) {
82
- return {
83
- isApplicable: false,
84
- applicableProducts: [],
85
- reason: result.message,
86
- reasonCode: result.code,
87
- strategyResult: result
88
- };
89
- }
90
- const matchedAction = result.matchedActions[0];
91
- if (!matchedAction) {
92
- return {
93
- isApplicable: false,
94
- applicableProducts: [],
95
- reason: "No matched action",
96
- reasonCode: "NO_ACTION",
97
- strategyResult: result
98
- };
99
- }
100
- const actionDetail = this.parseActionDetail(matchedAction);
101
- return {
102
- isApplicable: true,
103
- actionType: matchedAction.type,
104
- actionDetail,
105
- applicableProducts,
106
- strategyResult: result
107
- };
108
- }
109
- /**
110
- * 格式化配置
111
- */
112
- formatConfig(result, businessData) {
113
- return { result, businessData };
114
- }
115
- // ============================================
116
- // 私有辅助方法
117
- // ============================================
118
- /**
119
- * 格式化日期时间
120
- */
121
- formatDateTime(date) {
122
- const year = date.getFullYear();
123
- const month = String(date.getMonth() + 1).padStart(2, "0");
124
- const day = String(date.getDate()).padStart(2, "0");
125
- const hours = String(date.getHours()).padStart(2, "0");
126
- const minutes = String(date.getMinutes()).padStart(2, "0");
127
- const seconds = String(date.getSeconds()).padStart(2, "0");
128
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
129
- }
130
- /**
131
- * 解析 Action 详情
132
- *
133
- * 将 matchedAction 转换为更易用的结构
134
- */
135
- parseActionDetail(action) {
136
- switch (action.type) {
137
- case import_type.PROMOTION_ACTION_TYPES.X_ITEMS_FOR_Y_PRICE:
138
- return this.parseXItemsForYPriceAction(action);
139
- case import_type.PROMOTION_ACTION_TYPES.BUY_X_GET_Y_FREE:
140
- return this.parseBuyXGetYFreeAction(action);
141
- default:
142
- return void 0;
143
- }
144
- }
145
- /**
146
- * 解析 X件Y元 Action
147
- */
148
- parseXItemsForYPriceAction(action) {
149
- const value = action.value || {};
150
- const config = action.config || {};
151
- return {
152
- type: import_type.PROMOTION_ACTION_TYPES.X_ITEMS_FOR_Y_PRICE,
153
- x: value.x || 2,
154
- price: value.price || 0,
155
- allowCrossProduct: config.allowCrossProduct ?? true,
156
- cumulative: config.cumulative ?? true
157
- };
158
- }
159
- /**
160
- * 解析 买X送Y Action
161
- */
162
- parseBuyXGetYFreeAction(action) {
163
- const value = action.value || {};
164
- const config = action.config || {};
165
- return {
166
- type: import_type.PROMOTION_ACTION_TYPES.BUY_X_GET_Y_FREE,
167
- buyQuantity: value.buyQuantity || 1,
168
- freeQuantity: value.freeQuantity || 1,
169
- giftSelectionMode: config.giftSelectionMode || "user_select",
170
- cumulative: config.cumulative ?? true,
171
- giftProducts: config.giftProducts || []
172
- };
173
- }
174
- /**
175
- * 获取适用的商品列表
176
- *
177
- * 从购物车商品中筛选出符合策略条件的商品
178
- */
179
- getApplicableProducts(result, businessData) {
180
- const { products } = businessData;
181
- const productMatchRule = this.findProductMatchRule(result.config);
182
- if (!productMatchRule) {
183
- return products;
184
- }
185
- const configProducts = productMatchRule.value;
186
- return products.filter(
187
- (product) => this.isProductMatch(product, configProducts)
188
- );
189
- }
190
- /**
191
- * 查找商品匹配规则
192
- */
193
- findProductMatchRule(config) {
194
- var _a;
195
- if (!((_a = config == null ? void 0 : config.conditions) == null ? void 0 : _a.rules)) {
196
- return null;
197
- }
198
- return config.conditions.rules.find(
199
- (rule) => rule.field === "productIdAndVariantId" && (rule.operator === "product_match" || rule.operator === "object_in")
200
- );
201
- }
202
- /**
203
- * 检查商品是否匹配
204
- */
205
- isProductMatch(product, configProducts) {
206
- return configProducts.some((config) => {
207
- if (config.product_id !== product.product_id) {
208
- return false;
209
- }
210
- if (config.product_variant_id === 0) {
211
- return true;
212
- }
213
- return config.product_variant_id === product.product_variant_id;
214
- });
215
- }
216
- };
217
- var promotion_default = PromotionAdapter;
218
- var X_ITEMS_FOR_Y_PRICE_STRATEGY = {
219
- metadata: {
220
- id: "STRATEGY_001",
221
- name: {
222
- en: "2 items for $10",
223
- "zh-CN": "2杯10元",
224
- "zh-HK": "2杯10元"
225
- },
226
- type: "promotion",
227
- custom: {
228
- display: {
229
- product_card: {
230
- text: {
231
- en: "2 for $10",
232
- "zh-CN": "2杯10元",
233
- "zh-HK": "2杯10元"
234
- },
235
- type: "tag"
236
- }
237
- }
238
- }
239
- },
240
- conditions: {
241
- operator: "and",
242
- rules: [
243
- {
244
- type: "operator",
245
- field: "currentDateTime",
246
- value: "2023-01-01 00:00:00",
247
- operator: ">="
248
- },
249
- {
250
- type: "operator",
251
- field: "currentDateTime",
252
- value: "2027-01-01 00:00:00",
253
- operator: "<="
254
- },
255
- {
256
- type: "operator",
257
- field: "productIdAndVariantId",
258
- value: [
259
- {
260
- product_id: 60736,
261
- product_variant_id: 0
262
- // 0 = 匹配任意变体
263
- },
264
- {
265
- product_id: 60737,
266
- product_variant_id: 0
267
- // 0 = 匹配任意变体
268
- }
269
- ],
270
- operator: "product_match"
271
- }
272
- ],
273
- actionIds: ["1"]
274
- },
275
- actions: [
276
- {
277
- id: "1",
278
- type: "X_ITEMS_FOR_Y_PRICE",
279
- value: {
280
- x: 2,
281
- // 每X件
282
- price: 10
283
- // 固定价格Y元
284
- },
285
- valueType: "object",
286
- target: "product",
287
- priority: 1,
288
- config: {
289
- allowCrossProduct: true,
290
- // 允许跨商品组合(A+B可以凑成一组)
291
- cumulative: true
292
- // 可累计(买5件 = 2组优惠 + 1件原价)
293
- }
294
- }
295
- ]
296
- };
297
- var BUY_X_GET_Y_FREE_STRATEGY = {
298
- metadata: {
299
- id: "STRATEGY_002",
300
- name: {
301
- en: "Buy 1 Get 1 Free",
302
- "zh-CN": "买1送1",
303
- "zh-HK": "買1送1"
304
- },
305
- type: "promotion",
306
- custom: {
307
- display: {
308
- product_card: {
309
- text: {
310
- en: "Buy 1 Get 1",
311
- "zh-CN": "买1送1",
312
- "zh-HK": "買1送1"
313
- },
314
- type: "tag"
315
- }
316
- }
317
- }
318
- },
319
- conditions: {
320
- operator: "and",
321
- rules: [
322
- {
323
- type: "operator",
324
- field: "currentDateTime",
325
- value: "2023-01-01 00:00:00",
326
- operator: ">="
327
- },
328
- {
329
- type: "operator",
330
- field: "currentDateTime",
331
- value: "2027-01-01 00:00:00",
332
- operator: "<="
333
- },
334
- {
335
- type: "operator",
336
- field: "productIdAndVariantId",
337
- value: [
338
- {
339
- product_id: 60736,
340
- product_variant_id: 0
341
- // 0 = 匹配任意变体
342
- },
343
- {
344
- product_id: 60737,
345
- product_variant_id: 0
346
- // 0 = 匹配任意变体
347
- }
348
- ],
349
- operator: "product_match"
350
- }
351
- ],
352
- actionIds: ["1"]
353
- },
354
- actions: [
355
- {
356
- id: "1",
357
- type: "BUY_X_GET_Y_FREE",
358
- value: {
359
- buyQuantity: 1,
360
- // 买X件
361
- freeQuantity: 1
362
- // 送Y件
363
- },
364
- valueType: "object",
365
- target: "product",
366
- priority: 1,
367
- config: {
368
- // 可累计(买2送2、买3送3...)
369
- cumulative: true,
370
- // 可选的赠品列表
371
- giftProducts: [
372
- { product_id: 60757, product_variant_id: 0 },
373
- { product_id: 38782, product_variant_id: 0 },
374
- { product_id: 60749, product_variant_id: 27267 }
375
- ]
376
- }
377
- }
378
- ]
379
- };
380
- // Annotate the CommonJS export names for ESM import in node:
381
- 0 && (module.exports = {
382
- BUY_X_GET_Y_FREE_STRATEGY,
383
- PromotionAdapter,
384
- PromotionEvaluator,
385
- X_ITEMS_FOR_Y_PRICE_STRATEGY
386
- });
@@ -49,5 +49,5 @@ export declare class Product extends BaseModule implements Module {
49
49
  getCategories(): ProductCategory[];
50
50
  setOtherParams(key: string, value: any): void;
51
51
  getOtherParams(): any;
52
- getProductType(): "duration" | "session" | "normal";
52
+ getProductType(): "normal" | "duration" | "session";
53
53
  }
@@ -1535,6 +1535,8 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1535
1535
  }
1536
1536
  const calculateCapacityFromCartItems = (items) => {
1537
1537
  var _a2;
1538
+ if (items.length === 0)
1539
+ return 0;
1538
1540
  const firstResource = (_a2 = items[0]._resourceOrigin) == null ? void 0 : _a2[0].id;
1539
1541
  const sameResourceLength = items.filter((item) => {
1540
1542
  var _a3;
@@ -1668,6 +1670,8 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1668
1670
  }
1669
1671
  const calculateCapacityFromCartItems = (items) => {
1670
1672
  var _a2;
1673
+ if (items.length === 0)
1674
+ return 0;
1671
1675
  const firstResource = (_a2 = items[0]._resourceOrigin) == null ? void 0 : _a2[0].id;
1672
1676
  const sameResourceLength = items.filter((item) => {
1673
1677
  var _a3;
@@ -123,7 +123,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
123
123
  * 获取当前的客户搜索条件
124
124
  * @returns 当前搜索条件
125
125
  */
126
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
126
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
127
127
  /**
128
128
  * 获取客户列表状态(包含滚动加载相关状态)
129
129
  * @returns 客户状态
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.0.458",
4
+ "version": "0.0.460",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",