@pisell/pisellos 0.0.460 → 0.0.461
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.
- package/dist/model/strategy/adapter/promotion/index.js +0 -447
- package/dist/modules/Discount/types.d.ts +1 -0
- package/dist/modules/Rules/index.js +21 -11
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/ShopDiscount/index.js +10 -4
- package/lib/modules/Discount/types.d.ts +1 -0
- package/lib/modules/Rules/index.js +8 -0
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/ShopDiscount/index.js +14 -6
- package/package.json +1 -1
|
@@ -1,447 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -83,6 +83,7 @@ export interface Discount {
|
|
|
83
83
|
balance: string;
|
|
84
84
|
format_title: Formattitle;
|
|
85
85
|
metadata?: {
|
|
86
|
+
num?: number;
|
|
86
87
|
discount_card_type?: 'fixed_amount' | 'percent';
|
|
87
88
|
custom_product_bundle_map_id?: string;
|
|
88
89
|
validity_type?: "custom_schedule_validity" | "fixed_validity";
|
|
@@ -627,6 +627,16 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
627
627
|
// 🔥 统计每张折扣卡的 applicableProductLimit 已使用次数(跨商品全局计数)
|
|
628
628
|
var usedDiscountCardLimitCounts = new Map();
|
|
629
629
|
|
|
630
|
+
// 🔥 预先将 editModeDiscount 中的折扣卡计入 applicableProductLimit 已使用次数
|
|
631
|
+
editModeDiscount.forEach(function (discount) {
|
|
632
|
+
var discountType = discount.tag || discount.type;
|
|
633
|
+
if (['discount_card', 'product_discount_card'].includes(discountType)) {
|
|
634
|
+
var _discount$metadata4;
|
|
635
|
+
var currentCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
|
|
636
|
+
usedDiscountCardLimitCounts.set(discount.id, currentCount + (((_discount$metadata4 = discount.metadata) === null || _discount$metadata4 === void 0 ? void 0 : _discount$metadata4.num) || 1));
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
|
|
630
640
|
// 记录每个优惠券适用的商品ID
|
|
631
641
|
var discountApplicability = new Map();
|
|
632
642
|
|
|
@@ -881,7 +891,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
881
891
|
|
|
882
892
|
// 判断优惠券是否适用于该商品
|
|
883
893
|
if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && (_discount$config = discount.config) !== null && _discount$config !== void 0 && _discount$config.isAvailable) {
|
|
884
|
-
var _discountApplicabilit, _discount$
|
|
894
|
+
var _discountApplicabilit, _discount$metadata5, _discount$metadata6;
|
|
885
895
|
// 记录此优惠券适用的商品
|
|
886
896
|
(_discountApplicabilit = discountApplicability.get(discount.id)) === null || _discountApplicabilit === void 0 || _discountApplicabilit.push(product.id);
|
|
887
897
|
|
|
@@ -897,9 +907,9 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
897
907
|
type: discountType,
|
|
898
908
|
tag: discountType,
|
|
899
909
|
discount: {
|
|
900
|
-
discount_card_type: discount === null || discount === void 0 || (_discount$
|
|
910
|
+
discount_card_type: discount === null || discount === void 0 || (_discount$metadata5 = discount.metadata) === null || _discount$metadata5 === void 0 ? void 0 : _discount$metadata5.discount_card_type,
|
|
901
911
|
fixed_amount: product.price,
|
|
902
|
-
discount_calculation_mode: discount === null || discount === void 0 || (_discount$
|
|
912
|
+
discount_calculation_mode: discount === null || discount === void 0 || (_discount$metadata6 = discount.metadata) === null || _discount$metadata6 === void 0 ? void 0 : _discount$metadata6.discount_calculation_mode,
|
|
903
913
|
resource_id: discount.id,
|
|
904
914
|
title: discount.format_title,
|
|
905
915
|
original_amount: product.price || product.origin_total,
|
|
@@ -1687,8 +1697,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1687
1697
|
|
|
1688
1698
|
// 🔥 更新主商品自己的 discount_list 中的 num(quantity=1)
|
|
1689
1699
|
var updatedMainDiscountList = mainProductData.discount_list.map(function (discount) {
|
|
1690
|
-
var _discount$
|
|
1691
|
-
if (discount !== null && discount !== void 0 && (_discount$
|
|
1700
|
+
var _discount$metadata7, _discount$metadata8;
|
|
1701
|
+
if (discount !== null && discount !== void 0 && (_discount$metadata7 = discount.metadata) !== null && _discount$metadata7 !== void 0 && _discount$metadata7.custom_product_bundle_map_id) {
|
|
1692
1702
|
// bundle的discount_list保持不变
|
|
1693
1703
|
return discount;
|
|
1694
1704
|
}
|
|
@@ -1696,7 +1706,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1696
1706
|
return _objectSpread(_objectSpread({}, discount), {}, {
|
|
1697
1707
|
// num: 1,
|
|
1698
1708
|
metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
|
|
1699
|
-
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$
|
|
1709
|
+
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata8 = discount.metadata) === null || _discount$metadata8 === void 0 ? void 0 : _discount$metadata8.custom_product_bundle_map_id,
|
|
1700
1710
|
num: 1
|
|
1701
1711
|
})
|
|
1702
1712
|
});
|
|
@@ -1761,8 +1771,8 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1761
1771
|
|
|
1762
1772
|
// 🔥 更新主商品自己的 discount_list 中的 num(quantity=原quantity-1)
|
|
1763
1773
|
var updatedMainDiscountListOriginal = mainProductData.discount_list.map(function (discount) {
|
|
1764
|
-
var _discount$
|
|
1765
|
-
if (discount !== null && discount !== void 0 && (_discount$
|
|
1774
|
+
var _discount$metadata9, _discount$metadata10;
|
|
1775
|
+
if (discount !== null && discount !== void 0 && (_discount$metadata9 = discount.metadata) !== null && _discount$metadata9 !== void 0 && _discount$metadata9.custom_product_bundle_map_id) {
|
|
1766
1776
|
// bundle的discount_list保持不变
|
|
1767
1777
|
return discount;
|
|
1768
1778
|
}
|
|
@@ -1770,7 +1780,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1770
1780
|
return _objectSpread(_objectSpread({}, discount), {}, {
|
|
1771
1781
|
metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
|
|
1772
1782
|
num: mainProductQuantity - 1,
|
|
1773
|
-
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$
|
|
1783
|
+
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata10 = discount.metadata) === null || _discount$metadata10 === void 0 ? void 0 : _discount$metadata10.custom_product_bundle_map_id
|
|
1774
1784
|
})
|
|
1775
1785
|
// num: mainProductQuantity - 1,
|
|
1776
1786
|
});
|
|
@@ -1835,11 +1845,11 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
|
|
|
1835
1845
|
processedBundleItems.forEach(function (item) {
|
|
1836
1846
|
// 🔥 更新 discount_list 中的 num,使其与拆分后的 item.num 一致
|
|
1837
1847
|
var updatedDiscountList = (item.discount_list || []).map(function (discount) {
|
|
1838
|
-
var _discount$
|
|
1848
|
+
var _discount$metadata11;
|
|
1839
1849
|
return _objectSpread(_objectSpread({}, discount), {}, {
|
|
1840
1850
|
metadata: _objectSpread(_objectSpread({}, discount.metadata), {}, {
|
|
1841
1851
|
num: item.num,
|
|
1842
|
-
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$
|
|
1852
|
+
custom_product_bundle_map_id: discount === null || discount === void 0 || (_discount$metadata11 = discount.metadata) === null || _discount$metadata11 === void 0 ? void 0 : _discount$metadata11.custom_product_bundle_map_id
|
|
1843
1853
|
})
|
|
1844
1854
|
// num: item.num, // 使用拆分后的 num
|
|
1845
1855
|
});
|
|
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
311
311
|
date: string;
|
|
312
312
|
status: string;
|
|
313
313
|
week: string;
|
|
314
|
-
weekNum: 0 |
|
|
314
|
+
weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
|
|
315
315
|
}[]>;
|
|
316
316
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
317
317
|
private getScheduleDataByIds;
|
|
@@ -358,7 +358,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
358
358
|
};
|
|
359
359
|
setOtherData(key: string, value: any): void;
|
|
360
360
|
getOtherData(key: string): any;
|
|
361
|
-
getProductTypeById(id: number): Promise<"
|
|
361
|
+
getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
|
|
362
362
|
/**
|
|
363
363
|
* 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
|
|
364
364
|
*
|
|
@@ -618,21 +618,27 @@ export var ShopDiscountImpl = /*#__PURE__*/function (_BaseModule) {
|
|
|
618
618
|
return n.id === (((_discount$discount = discount.discount) === null || _discount$discount === void 0 ? void 0 : _discount$discount.resource_id) || discount.id);
|
|
619
619
|
});
|
|
620
620
|
if (index !== -1) {
|
|
621
|
-
var _discount$metadata;
|
|
621
|
+
var _editModeDiscountList, _discount$metadata, _discount$metadata2;
|
|
622
622
|
editModeDiscountList[index] = _objectSpread(_objectSpread({}, editModeDiscountList[index]), {}, {
|
|
623
|
+
metadata: _objectSpread(_objectSpread({}, discount.metadata || {}), {}, {
|
|
624
|
+
num: ((editModeDiscountList === null || editModeDiscountList === void 0 || (_editModeDiscountList = editModeDiscountList[index]) === null || _editModeDiscountList === void 0 || (_editModeDiscountList = _editModeDiscountList.metadata) === null || _editModeDiscountList === void 0 ? void 0 : _editModeDiscountList.num) || 1) + (((_discount$metadata = discount.metadata) === null || _discount$metadata === void 0 ? void 0 : _discount$metadata.num) || 1)
|
|
625
|
+
}),
|
|
623
626
|
amount: new Decimal(discount.amount || 0).plus(new Decimal(editModeDiscountList[index].amount || 0)).toNumber(),
|
|
624
|
-
savedAmount: new Decimal(discount.amount || 0).times((product === null || product === void 0 ? void 0 : product.quantity) || (product === null || product === void 0 ? void 0 : product.num) || 1).plus((discount === null || discount === void 0 || (_discount$
|
|
627
|
+
savedAmount: new Decimal(discount.amount || 0).times((product === null || product === void 0 ? void 0 : product.quantity) || (product === null || product === void 0 ? void 0 : product.num) || 1).plus((discount === null || discount === void 0 || (_discount$metadata2 = discount.metadata) === null || _discount$metadata2 === void 0 ? void 0 : _discount$metadata2.product_discount_difference) || 0).plus(new Decimal(editModeDiscountList[index].savedAmount || 0)).toNumber()
|
|
625
628
|
});
|
|
626
629
|
} else {
|
|
627
|
-
var _discount$
|
|
630
|
+
var _discount$metadata3, _discount$metadata4, _discount$discount2, _discount$discount3, _discount$discount4;
|
|
628
631
|
if (discount.type && !discount.tag) {
|
|
629
632
|
discount.tag = discount.type;
|
|
630
633
|
}
|
|
631
634
|
editModeDiscountList.push(_objectSpread(_objectSpread({}, discount), {}, {
|
|
635
|
+
metadata: _objectSpread(_objectSpread({}, discount.metadata || {}), {}, {
|
|
636
|
+
num: ((_discount$metadata3 = discount.metadata) === null || _discount$metadata3 === void 0 ? void 0 : _discount$metadata3.num) || 1
|
|
637
|
+
}),
|
|
632
638
|
name: discount.name || discount.discount.title.auto,
|
|
633
639
|
isEditMode: true,
|
|
634
640
|
limited_relation_product_data: {},
|
|
635
|
-
savedAmount: new Decimal(discount.amount || 0).times((product === null || product === void 0 ? void 0 : product.quantity) || (product === null || product === void 0 ? void 0 : product.num) || 1).plus((discount === null || discount === void 0 || (_discount$
|
|
641
|
+
savedAmount: new Decimal(discount.amount || 0).times((product === null || product === void 0 ? void 0 : product.quantity) || (product === null || product === void 0 ? void 0 : product.num) || 1).plus((discount === null || discount === void 0 || (_discount$metadata4 = discount.metadata) === null || _discount$metadata4 === void 0 ? void 0 : _discount$metadata4.product_discount_difference) || 0).toNumber(),
|
|
636
642
|
isAvailable: true,
|
|
637
643
|
id: ((_discount$discount2 = discount.discount) === null || _discount$discount2 === void 0 ? void 0 : _discount$discount2.resource_id) || discount.id,
|
|
638
644
|
format_title: ((_discount$discount3 = discount.discount) === null || _discount$discount3 === void 0 ? void 0 : _discount$discount3.title) || discount.format_title,
|
|
@@ -83,6 +83,7 @@ export interface Discount {
|
|
|
83
83
|
balance: string;
|
|
84
84
|
format_title: Formattitle;
|
|
85
85
|
metadata?: {
|
|
86
|
+
num?: number;
|
|
86
87
|
discount_card_type?: 'fixed_amount' | 'percent';
|
|
87
88
|
custom_product_bundle_map_id?: string;
|
|
88
89
|
validity_type?: "custom_schedule_validity" | "fixed_validity";
|
|
@@ -418,6 +418,14 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
418
418
|
const usedDiscounts = /* @__PURE__ */ new Map();
|
|
419
419
|
const usedProductIdCounts = /* @__PURE__ */ new Map();
|
|
420
420
|
const usedDiscountCardLimitCounts = /* @__PURE__ */ new Map();
|
|
421
|
+
editModeDiscount.forEach((discount) => {
|
|
422
|
+
var _a;
|
|
423
|
+
const discountType = discount.tag || discount.type;
|
|
424
|
+
if (["discount_card", "product_discount_card"].includes(discountType)) {
|
|
425
|
+
const currentCount = usedDiscountCardLimitCounts.get(discount.id) || 0;
|
|
426
|
+
usedDiscountCardLimitCounts.set(discount.id, currentCount + (((_a = discount.metadata) == null ? void 0 : _a.num) || 1));
|
|
427
|
+
}
|
|
428
|
+
});
|
|
421
429
|
const discountApplicability = /* @__PURE__ */ new Map();
|
|
422
430
|
const discountApplicableProducts = /* @__PURE__ */ new Map();
|
|
423
431
|
addModeDiscount.forEach((discount) => {
|
|
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
311
311
|
date: string;
|
|
312
312
|
status: string;
|
|
313
313
|
week: string;
|
|
314
|
-
weekNum: 0 |
|
|
314
|
+
weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
|
|
315
315
|
}[]>;
|
|
316
316
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
317
317
|
private getScheduleDataByIds;
|
|
@@ -358,7 +358,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
358
358
|
};
|
|
359
359
|
setOtherData(key: string, value: any): void;
|
|
360
360
|
getOtherData(key: string): any;
|
|
361
|
-
getProductTypeById(id: number): Promise<"
|
|
361
|
+
getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
|
|
362
362
|
/**
|
|
363
363
|
* 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
|
|
364
364
|
*
|
|
@@ -394,7 +394,7 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
394
394
|
if (item.booking_id) {
|
|
395
395
|
const product = (_a2 = this.hooks) == null ? void 0 : _a2.getProduct(item);
|
|
396
396
|
(item.discount_list || []).forEach((discount) => {
|
|
397
|
-
var _a3, _b, _c, _d, _e;
|
|
397
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
398
398
|
if (discount.id && ["good_pass", "discount_card"].includes(discount.type)) {
|
|
399
399
|
const index = editModeDiscountList.findIndex((n) => {
|
|
400
400
|
var _a4;
|
|
@@ -403,8 +403,12 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
403
403
|
if (index !== -1) {
|
|
404
404
|
editModeDiscountList[index] = {
|
|
405
405
|
...editModeDiscountList[index],
|
|
406
|
+
metadata: {
|
|
407
|
+
...discount.metadata || {},
|
|
408
|
+
num: (((_b = (_a3 = editModeDiscountList == null ? void 0 : editModeDiscountList[index]) == null ? void 0 : _a3.metadata) == null ? void 0 : _b.num) || 1) + (((_c = discount.metadata) == null ? void 0 : _c.num) || 1)
|
|
409
|
+
},
|
|
406
410
|
amount: new import_decimal.default(discount.amount || 0).plus(new import_decimal.default(editModeDiscountList[index].amount || 0)).toNumber(),
|
|
407
|
-
savedAmount: new import_decimal.default(discount.amount || 0).times((product == null ? void 0 : product.quantity) || (product == null ? void 0 : product.num) || 1).plus(((
|
|
411
|
+
savedAmount: new import_decimal.default(discount.amount || 0).times((product == null ? void 0 : product.quantity) || (product == null ? void 0 : product.num) || 1).plus(((_d = discount == null ? void 0 : discount.metadata) == null ? void 0 : _d.product_discount_difference) || 0).plus(new import_decimal.default(editModeDiscountList[index].savedAmount || 0)).toNumber()
|
|
408
412
|
};
|
|
409
413
|
} else {
|
|
410
414
|
if (discount.type && !discount.tag) {
|
|
@@ -412,16 +416,20 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
412
416
|
}
|
|
413
417
|
editModeDiscountList.push({
|
|
414
418
|
...discount,
|
|
419
|
+
metadata: {
|
|
420
|
+
...discount.metadata || {},
|
|
421
|
+
num: ((_e = discount.metadata) == null ? void 0 : _e.num) || 1
|
|
422
|
+
},
|
|
415
423
|
name: discount.name || discount.discount.title.auto,
|
|
416
424
|
isEditMode: true,
|
|
417
425
|
limited_relation_product_data: {},
|
|
418
|
-
savedAmount: new import_decimal.default(discount.amount || 0).times((product == null ? void 0 : product.quantity) || (product == null ? void 0 : product.num) || 1).plus(((
|
|
426
|
+
savedAmount: new import_decimal.default(discount.amount || 0).times((product == null ? void 0 : product.quantity) || (product == null ? void 0 : product.num) || 1).plus(((_f = discount == null ? void 0 : discount.metadata) == null ? void 0 : _f.product_discount_difference) || 0).toNumber(),
|
|
419
427
|
isAvailable: true,
|
|
420
|
-
id: ((
|
|
421
|
-
format_title: ((
|
|
428
|
+
id: ((_g = discount.discount) == null ? void 0 : _g.resource_id) || discount.id,
|
|
429
|
+
format_title: ((_h = discount.discount) == null ? void 0 : _h.title) || discount.format_title,
|
|
422
430
|
isDisabled: true,
|
|
423
431
|
isSelected: true,
|
|
424
|
-
product_id: ((
|
|
432
|
+
product_id: ((_i = discount.discount) == null ? void 0 : _i.product_id) || discount.product_id
|
|
425
433
|
});
|
|
426
434
|
}
|
|
427
435
|
}
|