@pisell/pisellos 2.1.45 → 2.1.47
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/modules/Cart/utils/cartProduct.js +41 -26
- package/dist/modules/Discount/index.d.ts +2 -0
- package/dist/modules/Discount/index.js +69 -36
- package/dist/modules/Discount/types.d.ts +14 -0
- package/dist/modules/Order/index.js +4 -1
- package/dist/modules/Order/utils.d.ts +1 -0
- package/dist/modules/Order/utils.js +9 -0
- package/dist/modules/Product/index.d.ts +1 -1
- package/dist/modules/Rules/index.d.ts +7 -0
- package/dist/modules/Rules/index.js +1050 -192
- package/dist/modules/Rules/types.d.ts +4 -1
- package/dist/solution/BookingByStep/index.js +1 -0
- package/dist/solution/Checkout/index.d.ts +1 -0
- package/dist/solution/Checkout/index.js +69 -28
- package/dist/solution/ShopDiscount/index.d.ts +2 -0
- package/dist/solution/ShopDiscount/index.js +81 -20
- package/dist/solution/ShopDiscount/types.d.ts +4 -1
- package/dist/solution/ShopDiscount/utils.d.ts +55 -0
- package/dist/solution/ShopDiscount/utils.js +418 -3
- package/lib/modules/Cart/utils/cartProduct.js +35 -22
- package/lib/modules/Discount/index.d.ts +2 -0
- package/lib/modules/Discount/index.js +19 -4
- package/lib/modules/Discount/types.d.ts +14 -0
- package/lib/modules/Order/index.js +2 -0
- package/lib/modules/Order/utils.d.ts +1 -0
- package/lib/modules/Order/utils.js +11 -0
- package/lib/modules/Product/index.d.ts +1 -1
- package/lib/modules/Rules/index.d.ts +7 -0
- package/lib/modules/Rules/index.js +809 -175
- package/lib/modules/Rules/types.d.ts +4 -1
- package/lib/solution/BookingByStep/index.js +4 -0
- package/lib/solution/BookingTicket/index.js +0 -6
- package/lib/solution/Checkout/index.d.ts +1 -0
- package/lib/solution/Checkout/index.js +58 -16
- package/lib/solution/ShopDiscount/index.d.ts +2 -0
- package/lib/solution/ShopDiscount/index.js +56 -10
- package/lib/solution/ShopDiscount/types.d.ts +4 -1
- package/lib/solution/ShopDiscount/utils.d.ts +55 -0
- package/lib/solution/ShopDiscount/utils.js +257 -3
- package/package.json +1 -1
|
@@ -40,6 +40,7 @@ type ProductDetail = {
|
|
|
40
40
|
num?: number;
|
|
41
41
|
quantity: number;
|
|
42
42
|
vouchersApplicable?: boolean;
|
|
43
|
+
startDate?: any;
|
|
43
44
|
};
|
|
44
45
|
export interface RulesParamsHooks {
|
|
45
46
|
getProduct: (product: Record<string, any>) => ProductDetail;
|
|
@@ -50,8 +51,10 @@ export interface RulesParamsHooks {
|
|
|
50
51
|
origin_total?: number;
|
|
51
52
|
price?: string | number;
|
|
52
53
|
variant?: any[];
|
|
53
|
-
original_price?: number;
|
|
54
|
+
original_price?: number | string;
|
|
54
55
|
quantity?: number;
|
|
56
|
+
bundle?: any[];
|
|
57
|
+
main_product_selling_price?: string | number;
|
|
55
58
|
}) => Record<string, any>;
|
|
56
59
|
}
|
|
57
60
|
export {};
|
|
@@ -1619,6 +1619,10 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
|
|
|
1619
1619
|
}
|
|
1620
1620
|
});
|
|
1621
1621
|
});
|
|
1622
|
+
this.core.effects.emit(
|
|
1623
|
+
`${this.store.cart.name}:onUpdateBookingDate`,
|
|
1624
|
+
{}
|
|
1625
|
+
);
|
|
1622
1626
|
}
|
|
1623
1627
|
getScheduleDataByIds(scheduleIds) {
|
|
1624
1628
|
const targetSchedules = this.store.schedule.getScheduleListByIds(scheduleIds);
|
|
@@ -122,12 +122,6 @@ var BookingTicketImpl = class extends import_BaseModule.BaseModule {
|
|
|
122
122
|
throw error;
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
-
/**
|
|
126
|
-
* 初始化外设扫码结果监听
|
|
127
|
-
*/
|
|
128
|
-
initPeripheralsListener() {
|
|
129
|
-
this.scan.initPeripheralsListener();
|
|
130
|
-
}
|
|
131
125
|
/**
|
|
132
126
|
* 获取商品列表(不加载到模块中)
|
|
133
127
|
* @returns 商品列表
|
|
@@ -48,6 +48,7 @@ export declare class CheckoutImpl extends BaseModule implements Module, Checkout
|
|
|
48
48
|
* 初始化结账流程
|
|
49
49
|
*/
|
|
50
50
|
initializeCheckoutAsync(params: CheckoutInitParams): Promise<void>;
|
|
51
|
+
getHolderIdFromBooking(obj: any): number | undefined;
|
|
51
52
|
getProductListByOrder(): {
|
|
52
53
|
product_id: number;
|
|
53
54
|
product_variant_id: string;
|
|
@@ -196,6 +196,16 @@ var CheckoutImpl = class extends import_BaseModule.BaseModule {
|
|
|
196
196
|
throw error;
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
+
getHolderIdFromBooking(obj) {
|
|
200
|
+
var _a;
|
|
201
|
+
if (!obj)
|
|
202
|
+
return void 0;
|
|
203
|
+
let ret = obj.holder_id || ((_a = obj.holder) == null ? void 0 : _a.form_record);
|
|
204
|
+
if (Array.isArray(ret)) {
|
|
205
|
+
return ret.length > 0 ? Number(ret[0]) : void 0;
|
|
206
|
+
}
|
|
207
|
+
return Number(ret) || void 0;
|
|
208
|
+
}
|
|
199
209
|
getProductListByOrder() {
|
|
200
210
|
var _a, _b, _c, _d, _e;
|
|
201
211
|
if (!this.store.currentOrder) {
|
|
@@ -206,22 +216,54 @@ var CheckoutImpl = class extends import_BaseModule.BaseModule {
|
|
|
206
216
|
return pre + (item.amount || 0);
|
|
207
217
|
}, 0);
|
|
208
218
|
};
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
219
|
+
const formatProduct = (items) => {
|
|
220
|
+
return items.map(
|
|
221
|
+
(item) => ({
|
|
222
|
+
product_id: item.product_id,
|
|
223
|
+
product_variant_id: item.product_variant_id,
|
|
224
|
+
quantity: item.num,
|
|
225
|
+
// 商品是否含税:1;0
|
|
226
|
+
is_charge_tax: item.is_charge_tax ?? 0,
|
|
227
|
+
// 若商品不含税,计算得到的税费,单位(元)
|
|
228
|
+
tax_fee: item.tax_fee,
|
|
229
|
+
// 整个商品折扣后的总金额
|
|
230
|
+
selling_price: item.calculated_selling_price,
|
|
231
|
+
// 使用者id
|
|
232
|
+
holder_id: item.holder_id,
|
|
233
|
+
// 整个商品折扣前的总金额
|
|
234
|
+
original_price: item.calculated_original_price,
|
|
235
|
+
// 主商品折扣前金额,不包含套餐子商品
|
|
236
|
+
main_product_original_price: item.price,
|
|
237
|
+
// 主商品折扣后金额,不包含套餐子商品
|
|
238
|
+
main_product_selling_price: item.main_product_selling_price,
|
|
239
|
+
product_bundle: item.product_bundle.map((bundle) => {
|
|
240
|
+
return {
|
|
241
|
+
bundle_id: bundle.bundle_id,
|
|
242
|
+
bundle_product_id: bundle.bundle_product_id,
|
|
243
|
+
bundle_variant_id: bundle.bundle_variant_id,
|
|
244
|
+
price_type: bundle.price_type,
|
|
245
|
+
price_type_ext: bundle.price_type_ext,
|
|
246
|
+
// 套餐子商品总价,不包含折扣金额
|
|
247
|
+
bundle_sum_price: bundle.bundle_sum_price,
|
|
248
|
+
// 套餐子商品折扣后金额
|
|
249
|
+
bundle_selling_price: bundle.bundle_selling_price,
|
|
250
|
+
num: bundle.num
|
|
251
|
+
};
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
) || [];
|
|
255
|
+
};
|
|
256
|
+
const productList = formatProduct(
|
|
257
|
+
((_c = (_b = (_a = this.store.currentOrder.order_info) == null ? void 0 : _a.original_order_data) == null ? void 0 : _b.bookings) == null ? void 0 : _c.map(
|
|
258
|
+
(item) => {
|
|
259
|
+
return {
|
|
260
|
+
...item.product,
|
|
261
|
+
holder_id: this.getHolderIdFromBooking(item)
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
)) || []
|
|
265
|
+
);
|
|
266
|
+
const relationProducts = formatProduct(((_e = (_d = this.store.currentOrder.order_info) == null ? void 0 : _d.original_order_data) == null ? void 0 : _e.relation_products) || []);
|
|
225
267
|
return [...productList, ...relationProducts];
|
|
226
268
|
}
|
|
227
269
|
async initWalletData(params) {
|
|
@@ -18,6 +18,8 @@ export declare class ShopDiscountImpl extends BaseModule implements Module {
|
|
|
18
18
|
private initializePlugins;
|
|
19
19
|
private registerDependentModules;
|
|
20
20
|
private registerEventListeners;
|
|
21
|
+
getCurrentBookingTime(): string | null;
|
|
22
|
+
private filterDiscountListByBookingTime;
|
|
21
23
|
setCustomer(customer: Customer): Promise<void>;
|
|
22
24
|
calcDiscount(productList: Record<string, any>[], options?: SetDiscountSelectedParams): {
|
|
23
25
|
productList: Record<string, any>[];
|
|
@@ -36,6 +36,7 @@ module.exports = __toCommonJS(ShopDiscount_exports);
|
|
|
36
36
|
var import_BaseModule = require("../../modules/BaseModule");
|
|
37
37
|
var import_Discount = require("../../modules/Discount");
|
|
38
38
|
var import_Rules = require("../../modules/Rules");
|
|
39
|
+
var import_utils = require("./utils");
|
|
39
40
|
var import_decimal = __toESM(require("decimal.js"));
|
|
40
41
|
var import_lodash_es = require("lodash-es");
|
|
41
42
|
var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
@@ -50,7 +51,9 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
50
51
|
productList: [],
|
|
51
52
|
discount: null,
|
|
52
53
|
rules: null,
|
|
53
|
-
originalDiscountList: []
|
|
54
|
+
originalDiscountList: [],
|
|
55
|
+
currentBookingTime: "",
|
|
56
|
+
filteredDiscountList: []
|
|
54
57
|
};
|
|
55
58
|
}
|
|
56
59
|
// =========== 生命周期方法 ===========
|
|
@@ -139,6 +142,44 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
139
142
|
);
|
|
140
143
|
}
|
|
141
144
|
// =========== 公共 API ===========
|
|
145
|
+
// 设置预约时间
|
|
146
|
+
// public async setBookingTime(bookingTime: string | null): Promise<void> {
|
|
147
|
+
// if (this.store.currentBookingTime !== bookingTime) {
|
|
148
|
+
// this.store.currentBookingTime = bookingTime;
|
|
149
|
+
//
|
|
150
|
+
// // 更新过滤后的优惠券列表
|
|
151
|
+
// await this.updateFilteredDiscountList();
|
|
152
|
+
// }
|
|
153
|
+
// }
|
|
154
|
+
// 获取当前预约时间
|
|
155
|
+
getCurrentBookingTime() {
|
|
156
|
+
return this.store.currentBookingTime;
|
|
157
|
+
}
|
|
158
|
+
// 根据预约时间过滤优惠券列表
|
|
159
|
+
filterDiscountListByBookingTime(discountList, bookingTime) {
|
|
160
|
+
if ((0, import_utils.isAllNormalProduct)(this.store.productList || [])) {
|
|
161
|
+
return discountList;
|
|
162
|
+
}
|
|
163
|
+
return (0, import_utils.filterDiscountListByBookingTime)(discountList, bookingTime);
|
|
164
|
+
}
|
|
165
|
+
// 更新过滤后的优惠券列表
|
|
166
|
+
// private async updateFilteredDiscountList(): Promise<void> {
|
|
167
|
+
// const originalList = this.store.originalDiscountList;
|
|
168
|
+
// const filteredList = this.filterDiscountListByBookingTime(originalList, this.store.currentBookingTime);
|
|
169
|
+
//
|
|
170
|
+
// this.store.filteredDiscountList = filteredList;
|
|
171
|
+
//
|
|
172
|
+
// // 更新 DiscountModule 中的优惠券列表
|
|
173
|
+
// this.setDiscountList(filteredList);
|
|
174
|
+
//
|
|
175
|
+
// if (this.store.productList?.length) {
|
|
176
|
+
// const result = this.calcDiscount(this.store.productList);
|
|
177
|
+
// await this.core.effects.emit(
|
|
178
|
+
// ShopDiscountHooks.onLoadPrepareCalcResult,
|
|
179
|
+
// result,
|
|
180
|
+
// );
|
|
181
|
+
// }
|
|
182
|
+
// }
|
|
142
183
|
// 设置客户
|
|
143
184
|
async setCustomer(customer) {
|
|
144
185
|
var _a;
|
|
@@ -324,7 +365,7 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
324
365
|
editModeDiscountList[index] = {
|
|
325
366
|
...editModeDiscountList[index],
|
|
326
367
|
amount: new import_decimal.default(discount.amount || 0).plus(new import_decimal.default(editModeDiscountList[index].amount || 0)).toNumber(),
|
|
327
|
-
savedAmount: new import_decimal.default(discount.amount || 0).times((product == null ? void 0 : product.num) || 1).plus(new import_decimal.default(editModeDiscountList[index].savedAmount || 0)).toNumber()
|
|
368
|
+
savedAmount: new import_decimal.default(discount.amount || 0).times((product == null ? void 0 : product.quantity) || (product == null ? void 0 : product.num) || 1).plus(new import_decimal.default(editModeDiscountList[index].savedAmount || 0)).toNumber()
|
|
328
369
|
};
|
|
329
370
|
} else {
|
|
330
371
|
if (discount.type && !discount.tag) {
|
|
@@ -335,7 +376,7 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
335
376
|
name: discount.name || discount.discount.title.auto,
|
|
336
377
|
isEditMode: true,
|
|
337
378
|
limited_relation_product_data: {},
|
|
338
|
-
savedAmount: discount.amount * ((product == null ? void 0 : product.num) || 1),
|
|
379
|
+
savedAmount: discount.amount * ((product == null ? void 0 : product.quantity) || (product == null ? void 0 : product.num) || 1),
|
|
339
380
|
isAvailable: true,
|
|
340
381
|
id: ((_a3 = discount.discount) == null ? void 0 : _a3.resource_id) || discount.id,
|
|
341
382
|
format_title: ((_b = discount.discount) == null ? void 0 : _b.title) || discount.format_title,
|
|
@@ -355,15 +396,17 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
355
396
|
const isProductFree = (id) => {
|
|
356
397
|
var _a2;
|
|
357
398
|
const targetProduct = productList.find((n) => n.id === id);
|
|
399
|
+
if (!targetProduct)
|
|
400
|
+
return false;
|
|
358
401
|
const product = (_a2 = this.hooks) == null ? void 0 : _a2.getProduct(targetProduct);
|
|
359
402
|
return Number(product == null ? void 0 : product.total) <= 0 && (Number(product == null ? void 0 : product.origin_total) <= 0 || !(product == null ? void 0 : product.origin_total)) || (0, import_lodash_es.isBoolean)(product == null ? void 0 : product.vouchersApplicable) && !(product == null ? void 0 : product.vouchersApplicable);
|
|
360
403
|
};
|
|
361
|
-
const allUsedProductIds = newDiscountList.map((n) => {
|
|
404
|
+
const allUsedProductIds = newDiscountList.filter((item) => !(item == null ? void 0 : item.isEditMode)).map((n) => {
|
|
362
405
|
var _a2;
|
|
363
|
-
return n.isSelected ? (_a2 = n.appliedProductDetails) == null ? void 0 : _a2.map((n2) => {
|
|
406
|
+
return n.isSelected ? ((_a2 = n.appliedProductDetails) == null ? void 0 : _a2.map((n2) => {
|
|
364
407
|
var _a3;
|
|
365
408
|
return (_a3 = n2.discount) == null ? void 0 : _a3.product_id;
|
|
366
|
-
}) : [];
|
|
409
|
+
})) || n.product_id : [];
|
|
367
410
|
}).flat();
|
|
368
411
|
newDiscountList.forEach((item) => {
|
|
369
412
|
var _a2;
|
|
@@ -425,7 +468,7 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
425
468
|
}
|
|
426
469
|
// 加载准备配置
|
|
427
470
|
async loadPrepareConfig(params) {
|
|
428
|
-
var _a, _b, _c, _d;
|
|
471
|
+
var _a, _b, _c, _d, _e;
|
|
429
472
|
try {
|
|
430
473
|
const customerId = params.customerId || ((_a = this.getCustomer()) == null ? void 0 : _a.id);
|
|
431
474
|
const goodPassList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
|
|
@@ -441,8 +484,11 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
441
484
|
const newGoodPassList = goodPassList == null ? void 0 : goodPassList.filter((n) => !scanDiscountIds.includes(n.id));
|
|
442
485
|
const newDiscountList = [...scanDiscount, ...newGoodPassList || []];
|
|
443
486
|
this.store.originalDiscountList = newDiscountList;
|
|
444
|
-
this.
|
|
445
|
-
|
|
487
|
+
await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(newDiscountList));
|
|
488
|
+
const filteredDiscountList = this.filterDiscountListByBookingTime(newDiscountList, this.store.currentBookingTime);
|
|
489
|
+
this.store.filteredDiscountList = filteredDiscountList;
|
|
490
|
+
this.setDiscountList(filteredDiscountList || []);
|
|
491
|
+
if ((_e = this.store.productList) == null ? void 0 : _e.length) {
|
|
446
492
|
const result = this.calcDiscount(this.store.productList);
|
|
447
493
|
await this.core.effects.emit(
|
|
448
494
|
`${this.name}:onLoadPrepareCalcResult`,
|
|
@@ -451,7 +497,7 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
451
497
|
}
|
|
452
498
|
await this.core.effects.emit(
|
|
453
499
|
`${this.name}:onLoadDiscountList`,
|
|
454
|
-
|
|
500
|
+
filteredDiscountList
|
|
455
501
|
);
|
|
456
502
|
} catch (error) {
|
|
457
503
|
console.error("[ShopDiscount] 加载准备配置出错:", error);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { DiscountModule
|
|
1
|
+
import { DiscountModule } from '../../modules/Discount';
|
|
2
2
|
import { RulesModule } from '../../modules/Rules';
|
|
3
|
+
import { Discount } from "../../modules/Discount/types";
|
|
3
4
|
export declare enum ShopDiscountHooks {
|
|
4
5
|
onInited = "shopDiscount:onInited",
|
|
5
6
|
onDestroy = "shopDiscount:onDestroy",
|
|
@@ -23,6 +24,8 @@ export interface ShopDiscountState {
|
|
|
23
24
|
rules: RulesModule | null;
|
|
24
25
|
productList: Record<string, any>[];
|
|
25
26
|
originalDiscountList: Discount[];
|
|
27
|
+
currentBookingTime: string | null;
|
|
28
|
+
filteredDiscountList: Discount[];
|
|
26
29
|
}
|
|
27
30
|
export interface SetDiscountSelectedParams {
|
|
28
31
|
discountId: number;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Discount } from "../../modules/Discount/types";
|
|
2
2
|
export declare const uniqueById: <T>(arr: T[], key?: string) => T[];
|
|
3
|
+
export declare const isNormalProductByDurationSchedule: (item: any) => boolean;
|
|
4
|
+
export declare const isAllNormalProduct: (items: any[]) => boolean;
|
|
3
5
|
/**
|
|
4
6
|
* 获取折扣金额 基于折扣卡类型计算
|
|
5
7
|
* 商品券:直接返回商品价格
|
|
@@ -10,3 +12,56 @@ export declare const uniqueById: <T>(arr: T[], key?: string) => T[];
|
|
|
10
12
|
* @returns
|
|
11
13
|
*/
|
|
12
14
|
export declare const getDiscountAmount: (discount: Discount, total: number, price: number) => number;
|
|
15
|
+
export declare const getDiscountListAmountTotal: (discount: Discount[]) => any;
|
|
16
|
+
/**
|
|
17
|
+
* 获取折扣金额 计算每个折扣的金额
|
|
18
|
+
* @param discount
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
export declare const getDiscountListAmount: (discount: Discount[]) => any;
|
|
22
|
+
export interface ScheduleItem {
|
|
23
|
+
id: number;
|
|
24
|
+
name: string | {
|
|
25
|
+
[key: string]: string;
|
|
26
|
+
};
|
|
27
|
+
type: 'standard' | 'time-slots' | 'designation';
|
|
28
|
+
start_time: string | null;
|
|
29
|
+
end_time: string | null;
|
|
30
|
+
repeat_type: 'none' | 'daily' | 'weekly';
|
|
31
|
+
repeat_rule: {
|
|
32
|
+
end: {
|
|
33
|
+
type: 'never' | 'date' | 'occurrence';
|
|
34
|
+
end_date: string | null;
|
|
35
|
+
occurrence: number | null;
|
|
36
|
+
};
|
|
37
|
+
frequency: number;
|
|
38
|
+
excluded_date: Array<{
|
|
39
|
+
start: string;
|
|
40
|
+
end: string;
|
|
41
|
+
}>;
|
|
42
|
+
included_date: Array<{
|
|
43
|
+
start: string;
|
|
44
|
+
end: string;
|
|
45
|
+
}>;
|
|
46
|
+
frequency_date: number[];
|
|
47
|
+
} | null;
|
|
48
|
+
designation: Array<{
|
|
49
|
+
start_date: string;
|
|
50
|
+
start_time: string;
|
|
51
|
+
end_date: string;
|
|
52
|
+
end_time: string;
|
|
53
|
+
}> | null;
|
|
54
|
+
is_all: number;
|
|
55
|
+
time_slot: Array<{
|
|
56
|
+
start_time: string;
|
|
57
|
+
end_time: string;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
export declare const getDateIsInSchedule: (dateTime: string, scheduleList: ScheduleItem[]) => boolean;
|
|
61
|
+
/**
|
|
62
|
+
* 根据预约时间过滤优惠券列表
|
|
63
|
+
* @param discountList 优惠券列表
|
|
64
|
+
* @param bookingTime 预约时间 (格式: YYYY-MM-DD HH:mm:ss)
|
|
65
|
+
* @returns 过滤后的优惠券列表
|
|
66
|
+
*/
|
|
67
|
+
export declare const filterDiscountListByBookingTime: (discountList: Discount[], bookingTime: string | null) => Discount[];
|
|
@@ -29,28 +29,282 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/solution/ShopDiscount/utils.ts
|
|
30
30
|
var utils_exports = {};
|
|
31
31
|
__export(utils_exports, {
|
|
32
|
+
filterDiscountListByBookingTime: () => filterDiscountListByBookingTime,
|
|
33
|
+
getDateIsInSchedule: () => getDateIsInSchedule,
|
|
32
34
|
getDiscountAmount: () => getDiscountAmount,
|
|
35
|
+
getDiscountListAmount: () => getDiscountListAmount,
|
|
36
|
+
getDiscountListAmountTotal: () => getDiscountListAmountTotal,
|
|
37
|
+
isAllNormalProduct: () => isAllNormalProduct,
|
|
38
|
+
isNormalProductByDurationSchedule: () => isNormalProductByDurationSchedule,
|
|
33
39
|
uniqueById: () => uniqueById
|
|
34
40
|
});
|
|
35
41
|
module.exports = __toCommonJS(utils_exports);
|
|
36
42
|
var import_decimal = __toESM(require("decimal.js"));
|
|
43
|
+
var import_dayjs = __toESM(require("dayjs"));
|
|
37
44
|
var uniqueById = (arr, key = "id") => {
|
|
38
45
|
const seen = /* @__PURE__ */ new Set();
|
|
39
46
|
return arr.filter((item) => !seen.has(item[key]) && seen.add(item[key]));
|
|
40
47
|
};
|
|
48
|
+
var isNormalProductByDurationSchedule = (item) => {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
return !(item == null ? void 0 : item.duration) && !((_a = item == null ? void 0 : item.schedules) == null ? void 0 : _a.length) && !((_b = item == null ? void 0 : item["schedule.ids"]) == null ? void 0 : _b.length);
|
|
51
|
+
};
|
|
52
|
+
var isAllNormalProduct = (items) => {
|
|
53
|
+
return items.every((item) => isNormalProductByDurationSchedule(item));
|
|
54
|
+
};
|
|
41
55
|
var getDiscountAmount = (discount, total, price) => {
|
|
42
56
|
var _a;
|
|
43
57
|
if (discount.tag === "good_pass") {
|
|
44
|
-
return new import_decimal.default(
|
|
58
|
+
return new import_decimal.default(price).minus(new import_decimal.default(price || 0)).toNumber();
|
|
45
59
|
}
|
|
46
60
|
const isFixedAmount = ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.discount_card_type) === "fixed_amount";
|
|
47
61
|
if (isFixedAmount) {
|
|
48
|
-
return Math.max(new import_decimal.default(
|
|
62
|
+
return Math.max(new import_decimal.default(price).minus(new import_decimal.default(discount.par_value || 0)).toNumber(), 0);
|
|
63
|
+
}
|
|
64
|
+
return new import_decimal.default(100).minus(discount.par_value || 0).div(100).mul(new import_decimal.default(price)).toNumber();
|
|
65
|
+
};
|
|
66
|
+
var getDiscountListAmountTotal = (discount) => {
|
|
67
|
+
return discount.reduce((acc, cur) => {
|
|
68
|
+
return new import_decimal.default(acc).plus(new import_decimal.default(cur.num || 1).mul(new import_decimal.default(cur.amount || 0))).toNumber();
|
|
69
|
+
}, new import_decimal.default(0));
|
|
70
|
+
};
|
|
71
|
+
var getDiscountListAmount = (discount) => {
|
|
72
|
+
return discount.reduce((acc, cur) => {
|
|
73
|
+
return new import_decimal.default(acc).plus(new import_decimal.default(cur.amount || 0)).toNumber();
|
|
74
|
+
}, new import_decimal.default(0));
|
|
75
|
+
};
|
|
76
|
+
var getDateIsInSchedule = (dateTime, scheduleList) => {
|
|
77
|
+
if (!dateTime || !scheduleList || scheduleList.length === 0) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const targetDate = (0, import_dayjs.default)(dateTime);
|
|
81
|
+
if (!targetDate.isValid()) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
for (const schedule of scheduleList) {
|
|
85
|
+
if (isTimeInScheduleItem(dateTime, schedule)) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
};
|
|
91
|
+
var isTimeInScheduleItem = (dateTime, schedule) => {
|
|
92
|
+
const targetDate = (0, import_dayjs.default)(dateTime);
|
|
93
|
+
const targetDateString = dateTime.split(" ")[0];
|
|
94
|
+
const targetTimeString = dateTime.split(" ")[1] || "00:00:00";
|
|
95
|
+
switch (schedule.type) {
|
|
96
|
+
case "standard":
|
|
97
|
+
return isInStandardSchedule(targetDate, targetDateString, targetTimeString, schedule);
|
|
98
|
+
case "time-slots":
|
|
99
|
+
return isInTimeSlotsSchedule(targetDate, targetDateString, targetTimeString, schedule);
|
|
100
|
+
case "designation":
|
|
101
|
+
return isInDesignationSchedule(targetDate, targetDateString, targetTimeString, schedule);
|
|
102
|
+
default:
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
var isInStandardSchedule = (targetDate, targetDateString, targetTimeString, schedule) => {
|
|
107
|
+
if (!schedule.start_time || !schedule.end_time) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
const startDate = (0, import_dayjs.default)(schedule.start_time);
|
|
111
|
+
const endDate = (0, import_dayjs.default)(schedule.end_time);
|
|
112
|
+
const isInBasicRange = targetDate.isSameOrAfter(startDate) && targetDate.isSameOrBefore(endDate);
|
|
113
|
+
if (schedule.repeat_type === "none") {
|
|
114
|
+
return isInBasicRange;
|
|
115
|
+
}
|
|
116
|
+
return isInRepeatingSchedule(targetDate, targetDateString, targetTimeString, schedule, startDate, endDate);
|
|
117
|
+
};
|
|
118
|
+
var isInTimeSlotsSchedule = (targetDate, targetDateString, targetTimeString, schedule) => {
|
|
119
|
+
if (!schedule.start_time) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
if (schedule.repeat_type === "none") {
|
|
123
|
+
const scheduleDate = schedule.start_time.split(" ")[0];
|
|
124
|
+
if (targetDateString !== scheduleDate) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
return checkTimeSlotsForDate(targetDate, targetDateString, schedule.time_slot);
|
|
128
|
+
}
|
|
129
|
+
return isInTimeSlotsRepeatingSchedule(targetDate, targetDateString, targetTimeString, schedule);
|
|
130
|
+
};
|
|
131
|
+
var isInDesignationSchedule = (targetDate, targetDateString, targetTimeString, schedule) => {
|
|
132
|
+
if (!schedule.designation) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
for (const designation of schedule.designation) {
|
|
136
|
+
const startDateTime = `${designation.start_date} ${designation.start_time}:00`;
|
|
137
|
+
const endDateTime = `${designation.end_date} ${designation.end_time}:00`;
|
|
138
|
+
const startDate = (0, import_dayjs.default)(startDateTime);
|
|
139
|
+
const endDate = (0, import_dayjs.default)(endDateTime);
|
|
140
|
+
if (targetDate.isSameOrAfter(startDate) && targetDate.isSameOrBefore(endDate)) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
};
|
|
146
|
+
var isInRepeatingSchedule = (targetDate, targetDateString, targetTimeString, schedule, startDate, endDate) => {
|
|
147
|
+
if (!schedule.repeat_rule) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
const { repeat_rule, repeat_type } = schedule;
|
|
151
|
+
const targetDateOnly = (0, import_dayjs.default)(targetDateString);
|
|
152
|
+
if (repeat_rule.included_date && repeat_rule.included_date.length > 0) {
|
|
153
|
+
for (const includedDate of repeat_rule.included_date) {
|
|
154
|
+
const includeStartDate = (0, import_dayjs.default)(includedDate.start);
|
|
155
|
+
const includeEndDate = (0, import_dayjs.default)(includedDate.end);
|
|
156
|
+
if (targetDateOnly.isSameOrAfter(includeStartDate, "day") && targetDateOnly.isSameOrBefore(includeEndDate, "day")) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
for (const excludedDate of repeat_rule.excluded_date) {
|
|
162
|
+
const excludeStartDate = (0, import_dayjs.default)(excludedDate.start);
|
|
163
|
+
const excludeEndDate = (0, import_dayjs.default)(excludedDate.end);
|
|
164
|
+
if (targetDateOnly.isSameOrAfter(excludeStartDate, "day") && targetDateOnly.isSameOrBefore(excludeEndDate, "day")) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (repeat_rule.end.type === "date" && repeat_rule.end.end_date) {
|
|
169
|
+
const ruleEndDate = (0, import_dayjs.default)(repeat_rule.end.end_date);
|
|
170
|
+
if (targetDate.isAfter(ruleEndDate)) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
switch (repeat_type) {
|
|
175
|
+
case "daily":
|
|
176
|
+
return isInDailyRepeat(targetDate, startDate, endDate, repeat_rule);
|
|
177
|
+
case "weekly":
|
|
178
|
+
return isInWeeklyRepeat(targetDate, startDate, endDate, repeat_rule);
|
|
179
|
+
default:
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
var isInDailyRepeat = (targetDate, startDate, endDate, repeatRule) => {
|
|
184
|
+
const daysDiff = targetDate.diff(startDate, "day");
|
|
185
|
+
if (daysDiff < 0) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
if (daysDiff % repeatRule.frequency !== 0) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
const targetTimeOfDay = targetDate.hour() * 3600 + targetDate.minute() * 60 + targetDate.second();
|
|
192
|
+
const startTimeOfDay = startDate.hour() * 3600 + startDate.minute() * 60 + startDate.second();
|
|
193
|
+
const endTimeOfDay = endDate.hour() * 3600 + endDate.minute() * 60 + endDate.second();
|
|
194
|
+
return targetTimeOfDay >= startTimeOfDay && targetTimeOfDay <= endTimeOfDay;
|
|
195
|
+
};
|
|
196
|
+
var isInWeeklyRepeat = (targetDate, startDate, endDate, repeatRule) => {
|
|
197
|
+
const targetDayOfWeek = targetDate.day();
|
|
198
|
+
if (!repeatRule.frequency_date.includes(targetDayOfWeek)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
const weeksDiff = targetDate.diff(startDate, "week");
|
|
202
|
+
if (weeksDiff < 0) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
if (weeksDiff % repeatRule.frequency !== 0) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
const targetTimeOfDay = targetDate.hour() * 3600 + targetDate.minute() * 60 + targetDate.second();
|
|
209
|
+
const startTimeOfDay = startDate.hour() * 3600 + startDate.minute() * 60 + startDate.second();
|
|
210
|
+
const endTimeOfDay = endDate.hour() * 3600 + endDate.minute() * 60 + endDate.second();
|
|
211
|
+
return targetTimeOfDay >= startTimeOfDay && targetTimeOfDay <= endTimeOfDay;
|
|
212
|
+
};
|
|
213
|
+
var isInTimeSlotsRepeatingSchedule = (targetDate, targetDateString, targetTimeString, schedule) => {
|
|
214
|
+
if (!schedule.repeat_rule || !schedule.start_time) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
const { repeat_rule, repeat_type } = schedule;
|
|
218
|
+
const startDate = (0, import_dayjs.default)(schedule.start_time);
|
|
219
|
+
const targetDateOnly = (0, import_dayjs.default)(targetDateString);
|
|
220
|
+
if (repeat_rule.included_date && repeat_rule.included_date.length > 0) {
|
|
221
|
+
for (const includedDate of repeat_rule.included_date) {
|
|
222
|
+
const includeStartDate = (0, import_dayjs.default)(includedDate.start);
|
|
223
|
+
const includeEndDate = (0, import_dayjs.default)(includedDate.end);
|
|
224
|
+
if (targetDateOnly.isSameOrAfter(includeStartDate, "day") && targetDateOnly.isSameOrBefore(includeEndDate, "day")) {
|
|
225
|
+
return checkTimeSlotsForDate(targetDate, targetDateString, schedule.time_slot);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
for (const excludedDate of repeat_rule.excluded_date) {
|
|
230
|
+
const excludeStartDate = (0, import_dayjs.default)(excludedDate.start);
|
|
231
|
+
const excludeEndDate = (0, import_dayjs.default)(excludedDate.end);
|
|
232
|
+
if (targetDateOnly.isSameOrAfter(excludeStartDate, "day") && targetDateOnly.isSameOrBefore(excludeEndDate, "day")) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (repeat_rule.end.type === "date" && repeat_rule.end.end_date) {
|
|
237
|
+
const ruleEndDate = (0, import_dayjs.default)(repeat_rule.end.end_date);
|
|
238
|
+
if (targetDateOnly.isAfter(ruleEndDate, "day")) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
let isDateValid = false;
|
|
243
|
+
switch (repeat_type) {
|
|
244
|
+
case "daily":
|
|
245
|
+
isDateValid = isInDailyRepeatForDate(targetDateOnly, startDate, repeat_rule);
|
|
246
|
+
break;
|
|
247
|
+
case "weekly":
|
|
248
|
+
isDateValid = isInWeeklyRepeatForDate(targetDateOnly, startDate, repeat_rule);
|
|
249
|
+
break;
|
|
250
|
+
default:
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
if (isDateValid) {
|
|
254
|
+
return checkTimeSlotsForDate(targetDate, targetDateString, schedule.time_slot);
|
|
255
|
+
}
|
|
256
|
+
return false;
|
|
257
|
+
};
|
|
258
|
+
var checkTimeSlotsForDate = (targetDate, targetDateString, timeSlots) => {
|
|
259
|
+
for (const timeSlot of timeSlots) {
|
|
260
|
+
const slotStart = `${targetDateString} ${timeSlot.start_time}:00`;
|
|
261
|
+
const slotEnd = `${targetDateString} ${timeSlot.end_time}:00`;
|
|
262
|
+
const slotStartDate = (0, import_dayjs.default)(slotStart);
|
|
263
|
+
const slotEndDate = (0, import_dayjs.default)(slotEnd);
|
|
264
|
+
if (targetDate.isSameOrAfter(slotStartDate) && targetDate.isSameOrBefore(slotEndDate)) {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return false;
|
|
269
|
+
};
|
|
270
|
+
var isInDailyRepeatForDate = (targetDate, startDate, repeatRule) => {
|
|
271
|
+
const daysDiff = targetDate.diff(startDate, "day");
|
|
272
|
+
if (daysDiff < 0) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
return daysDiff % repeatRule.frequency === 0;
|
|
276
|
+
};
|
|
277
|
+
var isInWeeklyRepeatForDate = (targetDate, startDate, repeatRule) => {
|
|
278
|
+
const targetDayOfWeek = targetDate.day();
|
|
279
|
+
if (!repeatRule.frequency_date.includes(targetDayOfWeek)) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
const weeksDiff = targetDate.diff(startDate, "week");
|
|
283
|
+
if (weeksDiff < 0) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
return weeksDiff % repeatRule.frequency === 0;
|
|
287
|
+
};
|
|
288
|
+
var filterDiscountListByBookingTime = (discountList, bookingTime) => {
|
|
289
|
+
if (!bookingTime) {
|
|
290
|
+
return discountList;
|
|
49
291
|
}
|
|
50
|
-
return
|
|
292
|
+
return discountList.filter((discount) => {
|
|
293
|
+
var _a, _b, _c;
|
|
294
|
+
if (!((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.validity_type) || ((_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.validity_type) === "fixed_validity") {
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
return getDateIsInSchedule(bookingTime, ((_c = discount.custom_schedule_snapshot) == null ? void 0 : _c.data) || []);
|
|
298
|
+
});
|
|
51
299
|
};
|
|
52
300
|
// Annotate the CommonJS export names for ESM import in node:
|
|
53
301
|
0 && (module.exports = {
|
|
302
|
+
filterDiscountListByBookingTime,
|
|
303
|
+
getDateIsInSchedule,
|
|
54
304
|
getDiscountAmount,
|
|
305
|
+
getDiscountListAmount,
|
|
306
|
+
getDiscountListAmountTotal,
|
|
307
|
+
isAllNormalProduct,
|
|
308
|
+
isNormalProductByDurationSchedule,
|
|
55
309
|
uniqueById
|
|
56
310
|
});
|