@pisell/pisellos 2.2.261 → 2.2.263
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/dataVariant/adapter.d.ts +50 -0
- package/dist/model/strategy/adapter/dataVariant/adapter.js +167 -0
- package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
- package/dist/model/strategy/adapter/dataVariant/evaluator.js +780 -0
- package/dist/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
- package/dist/model/strategy/adapter/dataVariant/examples.js +277 -0
- package/dist/model/strategy/adapter/dataVariant/index.d.ts +4 -0
- package/dist/model/strategy/adapter/dataVariant/index.js +4 -0
- package/dist/model/strategy/adapter/dataVariant/type.d.ts +148 -0
- package/dist/model/strategy/adapter/dataVariant/type.js +54 -0
- package/dist/model/strategy/adapter/index.d.ts +4 -0
- package/dist/model/strategy/adapter/index.js +5 -1
- package/dist/model/strategy/adapter/promotion/adapter.d.ts +0 -4
- package/dist/model/strategy/adapter/promotion/adapter.js +0 -23
- package/dist/model/strategy/adapter/promotion/evaluator.d.ts +0 -17
- package/dist/model/strategy/adapter/promotion/evaluator.js +6 -279
- package/dist/model/strategy/adapter/promotion/examples.d.ts +0 -86
- package/dist/model/strategy/adapter/promotion/examples.js +0 -99
- package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
- package/dist/model/strategy/adapter/promotion/index.js +1 -1
- package/dist/model/strategy/adapter/promotion/type.d.ts +2 -90
- package/dist/model/strategy/adapter/promotion/type.js +0 -45
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +16 -10
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
- package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +32 -1
- package/dist/modules/Discount/index.d.ts +5 -2
- package/dist/modules/Discount/index.js +30 -7
- package/dist/modules/Discount/types.d.ts +4 -0
- package/dist/modules/Order/index.d.ts +14 -2
- package/dist/modules/Order/index.js +1035 -736
- package/dist/modules/Order/types.d.ts +16 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
- package/dist/modules/Order/utils.d.ts +4 -3
- package/dist/modules/Order/utils.js +54 -61
- package/dist/modules/Product/types.d.ts +22 -0
- package/dist/modules/ProductList/index.d.ts +1 -1
- package/dist/modules/ProductList/index.js +4 -2
- package/dist/modules/ProductList/types.d.ts +2 -0
- package/dist/modules/Rules/index.d.ts +2 -9
- package/dist/modules/Rules/index.js +69 -43
- package/dist/modules/Rules/types.d.ts +10 -1
- package/dist/server/index.d.ts +55 -0
- package/dist/server/index.js +1173 -753
- package/dist/server/modules/order/index.d.ts +10 -4
- package/dist/server/modules/order/index.js +404 -399
- package/dist/server/modules/order/types.d.ts +4 -0
- package/dist/server/modules/products/index.d.ts +31 -8
- package/dist/server/modules/products/index.js +549 -390
- package/dist/server/modules/products/types.d.ts +18 -0
- package/dist/solution/BaseSales/index.d.ts +21 -1
- package/dist/solution/BaseSales/index.js +1136 -789
- package/dist/solution/BaseSales/types.d.ts +6 -1
- package/dist/solution/BaseSales/types.js +1 -1
- package/dist/solution/BaseSales/utils/cartPromotion.d.ts +1 -3
- package/dist/solution/BaseSales/utils/cartPromotion.js +48 -81
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
- package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
- package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -1
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +59 -25
- package/dist/solution/BookingTicket/types.d.ts +2 -0
- package/dist/solution/ScanOrder/index.js +20 -31
- package/dist/solution/ShopDiscount/index.js +15 -14
- package/dist/solution/VenueBooking/index.js +19 -30
- package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
- package/lib/model/strategy/adapter/dataVariant/adapter.js +149 -0
- package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +583 -0
- package/lib/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
- package/lib/model/strategy/adapter/dataVariant/examples.js +293 -0
- package/lib/model/strategy/adapter/dataVariant/index.d.ts +4 -0
- package/lib/model/strategy/adapter/dataVariant/index.js +38 -0
- package/lib/model/strategy/adapter/dataVariant/type.d.ts +148 -0
- package/lib/model/strategy/adapter/dataVariant/type.js +31 -0
- package/lib/model/strategy/adapter/index.d.ts +4 -0
- package/lib/model/strategy/adapter/index.js +13 -2
- package/lib/model/strategy/adapter/promotion/adapter.d.ts +0 -4
- package/lib/model/strategy/adapter/promotion/adapter.js +0 -20
- package/lib/model/strategy/adapter/promotion/evaluator.d.ts +0 -17
- package/lib/model/strategy/adapter/promotion/evaluator.js +0 -235
- package/lib/model/strategy/adapter/promotion/examples.d.ts +0 -86
- package/lib/model/strategy/adapter/promotion/examples.js +0 -91
- package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
- package/lib/model/strategy/adapter/promotion/index.js +0 -51
- package/lib/model/strategy/adapter/promotion/type.d.ts +2 -90
- package/lib/model/strategy/adapter/promotion/type.js +0 -2
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -0
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +1 -0
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +23 -2
- package/lib/modules/Discount/index.d.ts +5 -2
- package/lib/modules/Discount/index.js +23 -3
- package/lib/modules/Discount/types.d.ts +4 -0
- package/lib/modules/Order/index.d.ts +14 -2
- package/lib/modules/Order/index.js +326 -60
- package/lib/modules/Order/types.d.ts +16 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +415 -0
- package/lib/modules/Order/utils.d.ts +4 -3
- package/lib/modules/Order/utils.js +22 -23
- package/lib/modules/Product/types.d.ts +22 -0
- package/lib/modules/ProductList/index.d.ts +1 -1
- package/lib/modules/ProductList/index.js +4 -2
- package/lib/modules/ProductList/types.d.ts +2 -0
- package/lib/modules/Rules/index.d.ts +2 -9
- package/lib/modules/Rules/index.js +61 -29
- package/lib/modules/Rules/types.d.ts +10 -1
- package/lib/server/index.d.ts +55 -0
- package/lib/server/index.js +332 -34
- package/lib/server/modules/order/index.d.ts +10 -4
- package/lib/server/modules/order/index.js +198 -139
- package/lib/server/modules/order/types.d.ts +4 -0
- package/lib/server/modules/products/index.d.ts +31 -8
- package/lib/server/modules/products/index.js +134 -35
- package/lib/server/modules/products/types.d.ts +18 -0
- package/lib/solution/BaseSales/index.d.ts +21 -1
- package/lib/solution/BaseSales/index.js +313 -72
- package/lib/solution/BaseSales/types.d.ts +6 -1
- package/lib/solution/BaseSales/utils/cartPromotion.d.ts +1 -3
- package/lib/solution/BaseSales/utils/cartPromotion.js +29 -60
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +8 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +33 -8
- package/lib/solution/BookingTicket/types.d.ts +2 -0
- package/lib/solution/ScanOrder/index.js +0 -8
- package/lib/solution/ShopDiscount/index.js +2 -1
- package/lib/solution/VenueBooking/index.js +0 -8
- package/package.json +1 -1
|
@@ -9,6 +9,26 @@ export interface ProductCollection {
|
|
|
9
9
|
/** 商品集合封面 */
|
|
10
10
|
cover: string;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 商品 Data Variant 记录,结构与后端 data_variant 表对齐。
|
|
14
|
+
*/
|
|
15
|
+
export interface ProductDataVariant {
|
|
16
|
+
/** 变体记录 id */
|
|
17
|
+
id: number;
|
|
18
|
+
/** 店铺 id */
|
|
19
|
+
shop_id: number;
|
|
20
|
+
/** 所属模块,商品场景固定为 product */
|
|
21
|
+
module: string;
|
|
22
|
+
/** 模块数据 id,商品场景对应 product.id */
|
|
23
|
+
module_data_id: number;
|
|
24
|
+
/** 关联 data_variant_rule.id */
|
|
25
|
+
data_variant_rule_id: number;
|
|
26
|
+
/** 命中策略后覆盖到商品上的字段 */
|
|
27
|
+
data: Record<string, any>;
|
|
28
|
+
created_at: string | null;
|
|
29
|
+
updated_at: string | null;
|
|
30
|
+
deleted_at: string | null;
|
|
31
|
+
}
|
|
12
32
|
/**
|
|
13
33
|
* 商品基本信息接口
|
|
14
34
|
*/
|
|
@@ -214,6 +234,8 @@ export interface ProductData {
|
|
|
214
234
|
bundle_group_count: number;
|
|
215
235
|
/** 选项组数量 */
|
|
216
236
|
option_group_count: number;
|
|
237
|
+
/** 智能定价变体列表,/product/query with dataVariants 返回 */
|
|
238
|
+
data_variants?: ProductDataVariant[];
|
|
217
239
|
/** 服务时长 */
|
|
218
240
|
service_times?: any;
|
|
219
241
|
}
|
|
@@ -26,7 +26,7 @@ export declare class ProductList extends BaseModule implements Module {
|
|
|
26
26
|
* const products = await productList.getAddTimeProducts({ schedule_date: '2026-06-16' });
|
|
27
27
|
*/
|
|
28
28
|
getAddTimeProducts(params?: ProductListLoadProductsParams): Promise<any>;
|
|
29
|
-
loadProducts({ category_ids, product_ids, collection, menu_list_ids, customer_id: paramsCustomerId, with_count, schedule_datetime, schedule_date, cacheId, with_schedule, extension_type, status, }?: ProductListLoadProductsParams, options?: {
|
|
29
|
+
loadProducts({ category_ids, product_ids, collection, menu_list_ids, customer_id: paramsCustomerId, with_count, schedule_datetime, schedule_date, cacheId, with_schedule, extension_type, status, strategy_context, }?: ProductListLoadProductsParams, options?: {
|
|
30
30
|
callback?: (result: any) => void;
|
|
31
31
|
subscriberId?: string;
|
|
32
32
|
}): Promise<any>;
|
|
@@ -95,7 +95,8 @@ var ProductList = class extends import_BaseModule.BaseModule {
|
|
|
95
95
|
cacheId,
|
|
96
96
|
with_schedule,
|
|
97
97
|
extension_type,
|
|
98
|
-
status = "published"
|
|
98
|
+
status = "published",
|
|
99
|
+
strategy_context
|
|
99
100
|
} = {}, options) {
|
|
100
101
|
var _a, _b;
|
|
101
102
|
let userPlugin = this.core.getPlugin("user");
|
|
@@ -135,7 +136,8 @@ var ProductList = class extends import_BaseModule.BaseModule {
|
|
|
135
136
|
is_eject: 1,
|
|
136
137
|
with_schedule,
|
|
137
138
|
schedule_datetime,
|
|
138
|
-
extension_type
|
|
139
|
+
extension_type,
|
|
140
|
+
strategy_context
|
|
139
141
|
},
|
|
140
142
|
{ osServer: true, callback: options == null ? void 0 : options.callback, subscriberId: options == null ? void 0 : options.subscriberId, customToast: () => {
|
|
141
143
|
} }
|
|
@@ -12,6 +12,8 @@ export interface ProductListLoadProductsParams {
|
|
|
12
12
|
with_schedule?: number;
|
|
13
13
|
extension_type?: string[];
|
|
14
14
|
status?: string;
|
|
15
|
+
/** 智能定价条件上下文,仅影响策略命中,不参与商品集合筛选 */
|
|
16
|
+
strategy_context?: Record<string, any>;
|
|
15
17
|
}
|
|
16
18
|
export interface ProductListData {
|
|
17
19
|
list: ProductData[];
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Module, PisellCore, ModuleOptions } from '../../types';
|
|
2
2
|
import { BaseModule } from '../BaseModule';
|
|
3
|
-
import { Rules, RulesModuleAPI, DiscountResult, RulesFormSubject, UnavailableReason } from './types';
|
|
3
|
+
import { Rules, RulesModuleAPI, DiscountResult, RulesFormSubject, RulesCalcDiscountOptions, UnavailableReason } from './types';
|
|
4
4
|
import { Discount } from '../Discount/types';
|
|
5
|
-
import { SetDiscountSelectedParams } from '../../solution/ShopDiscount/types';
|
|
6
5
|
import { WindowPlugin } from '../../plugins';
|
|
7
6
|
export declare class RulesModule extends BaseModule implements Module, RulesModuleAPI {
|
|
8
7
|
protected defaultName: string;
|
|
@@ -36,7 +35,6 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
|
|
|
36
35
|
excludeDiscountListByType(discountList: Discount[], type: string): Discount[];
|
|
37
36
|
/** 手动改价场景:去掉 promotion,保留 type=product 等行内折扣 */
|
|
38
37
|
resolveDiscountListForManualOverride(discountList: Discount[]): Discount[];
|
|
39
|
-
private isItemRewardProductDiscount;
|
|
40
38
|
private getUnavailableReason;
|
|
41
39
|
calcDiscount({ discountList, productList, holders, isFormSubject, orderTotalAmount }: {
|
|
42
40
|
discountList: Discount[];
|
|
@@ -46,12 +44,7 @@ export declare class RulesModule extends BaseModule implements Module, RulesModu
|
|
|
46
44
|
}[];
|
|
47
45
|
isFormSubject: RulesFormSubject;
|
|
48
46
|
orderTotalAmount: number;
|
|
49
|
-
}, options?:
|
|
50
|
-
isSelected?: boolean;
|
|
51
|
-
discountId?: number;
|
|
52
|
-
selectedList?: SetDiscountSelectedParams[];
|
|
53
|
-
scan?: boolean;
|
|
54
|
-
}): DiscountResult;
|
|
47
|
+
}, options?: RulesCalcDiscountOptions): DiscountResult;
|
|
55
48
|
/**
|
|
56
49
|
* 检查优惠是否符合 PackageSubItemUsageRules 配置
|
|
57
50
|
* @param discount 优惠券
|
|
@@ -167,16 +167,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
167
167
|
resolveDiscountListForManualOverride(discountList) {
|
|
168
168
|
return this.excludeDiscountListByType(discountList, "promotion");
|
|
169
169
|
}
|
|
170
|
-
isItemRewardProductDiscount(product) {
|
|
171
|
-
var _a;
|
|
172
|
-
const discountList = Array.isArray(product == null ? void 0 : product.discount_list) ? product.discount_list : [];
|
|
173
|
-
return ((_a = product == null ? void 0 : product._promotion) == null ? void 0 : _a.actionType) === "ITEM_REWARD" && discountList.some(
|
|
174
|
-
(item) => {
|
|
175
|
-
var _a2, _b;
|
|
176
|
-
return (item == null ? void 0 : item.type) === "product" && ((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.source) === "promotion" && ((_b = item == null ? void 0 : item.metadata) == null ? void 0 : _b.actionType) === "ITEM_REWARD";
|
|
177
|
-
}
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
170
|
// 获取券不可用的原因
|
|
181
171
|
getUnavailableReason(discountList, productList) {
|
|
182
172
|
var _a;
|
|
@@ -219,6 +209,36 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
219
209
|
var _a;
|
|
220
210
|
const resolveIsFormSubject = (product) => typeof isFormSubject === "function" ? Boolean(isFormSubject(product)) : Boolean(isFormSubject);
|
|
221
211
|
const isEditModeAddNewProduct = productList.find((n) => n.booking_id) && productList.find((n) => !n.booking_id);
|
|
212
|
+
const reapplyBookingDiscountProductUids = new Set(
|
|
213
|
+
((options == null ? void 0 : options.reapplyBookingDiscountProductUids) || []).filter((uid) => uid !== void 0 && uid !== null && uid !== "").map(String)
|
|
214
|
+
);
|
|
215
|
+
const getOriginProductUid = (originProduct) => {
|
|
216
|
+
var _a2;
|
|
217
|
+
const uid = ((_a2 = originProduct == null ? void 0 : originProduct.metadata) == null ? void 0 : _a2.unique_identification_number) ?? (originProduct == null ? void 0 : originProduct.unique_identification_number);
|
|
218
|
+
if (uid === void 0 || uid === null || uid === "")
|
|
219
|
+
return void 0;
|
|
220
|
+
return String(uid);
|
|
221
|
+
};
|
|
222
|
+
const shouldReapplyBookingDiscount = (originProduct, selectedDiscount) => {
|
|
223
|
+
if (!selectedDiscount)
|
|
224
|
+
return false;
|
|
225
|
+
const uid = getOriginProductUid(originProduct);
|
|
226
|
+
if (!uid || !reapplyBookingDiscountProductUids.has(uid))
|
|
227
|
+
return false;
|
|
228
|
+
const discountType = selectedDiscount.tag || selectedDiscount.type;
|
|
229
|
+
return selectedDiscount.isEditMode === true && selectedDiscount.isSelected === true && ["good_pass", "discount_card", "product_discount_card"].includes(discountType);
|
|
230
|
+
};
|
|
231
|
+
const resolveReapplyEditModeDiscountPercent = (originProduct, selectedDiscount) => {
|
|
232
|
+
var _a2;
|
|
233
|
+
if (!shouldReapplyBookingDiscount(originProduct, selectedDiscount))
|
|
234
|
+
return void 0;
|
|
235
|
+
const discountType = (selectedDiscount == null ? void 0 : selectedDiscount.tag) || (selectedDiscount == null ? void 0 : selectedDiscount.type);
|
|
236
|
+
if (discountType !== "discount_card" && discountType !== "product_discount_card") {
|
|
237
|
+
return void 0;
|
|
238
|
+
}
|
|
239
|
+
const percent = Number((_a2 = selectedDiscount.discount) == null ? void 0 : _a2.percent);
|
|
240
|
+
return Number.isFinite(percent) ? percent : void 0;
|
|
241
|
+
};
|
|
222
242
|
const editModeDiscount = [];
|
|
223
243
|
const addModeDiscount = [];
|
|
224
244
|
discountList.forEach((discount) => {
|
|
@@ -242,9 +262,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
242
262
|
}
|
|
243
263
|
});
|
|
244
264
|
}
|
|
245
|
-
const filteredDiscountList = addModeDiscount.filter((discount) => {
|
|
246
|
-
return !discount.isManualSelect;
|
|
247
|
-
});
|
|
248
265
|
const hasDiscountInput = editModeDiscount.length > 0 || addModeDiscount.length > 0 || Boolean(options == null ? void 0 : options.discountId) || Boolean((_a = options == null ? void 0 : options.selectedList) == null ? void 0 : _a.length) || Boolean(options == null ? void 0 : options.scan);
|
|
249
266
|
if (!hasDiscountInput) {
|
|
250
267
|
return {
|
|
@@ -252,6 +269,14 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
252
269
|
productList
|
|
253
270
|
};
|
|
254
271
|
}
|
|
272
|
+
const canUseEditModeDiscountForReapply = (discount) => {
|
|
273
|
+
const discountType = discount.tag || discount.type;
|
|
274
|
+
return reapplyBookingDiscountProductUids.size > 0 && discount.isEditMode === true && discount.isSelected === true && ["good_pass", "discount_card", "product_discount_card"].includes(discountType);
|
|
275
|
+
};
|
|
276
|
+
const filteredDiscountList = [
|
|
277
|
+
...addModeDiscount.filter((discount) => !discount.isManualSelect),
|
|
278
|
+
...editModeDiscount.filter(canUseEditModeDiscountForReapply)
|
|
279
|
+
];
|
|
255
280
|
const flattenProductsWithBundle = (productList2) => {
|
|
256
281
|
const flattened = [];
|
|
257
282
|
productList2.forEach((originProduct) => {
|
|
@@ -475,9 +500,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
475
500
|
startDate: (_a2 = flatItem.parentProduct) == null ? void 0 : _a2.startDate
|
|
476
501
|
};
|
|
477
502
|
}
|
|
478
|
-
if (this.isItemRewardProductDiscount(product)) {
|
|
479
|
-
return false;
|
|
480
|
-
}
|
|
481
503
|
const isAvailableProduct = flatItem.type === "main" ? !((product == null ? void 0 : product.booking_id) && ((_b = product == null ? void 0 : product.discount_list) == null ? void 0 : _b.length) && ((_c = product == null ? void 0 : product.discount_list) == null ? void 0 : _c.every((d) => d.id && ["good_pass", "discount_card", "product_discount_card"].includes(d.tag || d.type)))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_e = (_d = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _d.discount_list) == null ? void 0 : _e.length) && ((_g = (_f = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _f.discount_list) == null ? void 0 : _g.every((d) => d.id)));
|
|
482
504
|
if (!isAvailableProduct) {
|
|
483
505
|
return false;
|
|
@@ -603,7 +625,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
603
625
|
};
|
|
604
626
|
originProduct = flatItem.originProduct;
|
|
605
627
|
}
|
|
606
|
-
const isItemRewardProductDiscount = this.isItemRewardProductDiscount(product);
|
|
607
628
|
addModeDiscount.forEach((discount) => {
|
|
608
629
|
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
609
630
|
const limitedData = discount == null ? void 0 : discount.limited_relation_product_data;
|
|
@@ -627,7 +648,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
627
648
|
].includes(discount2.tag || discount2.type)
|
|
628
649
|
))) : !((flatItem == null ? void 0 : flatItem.booking_id) && !!((_d = (_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.discount_list) == null ? void 0 : _d.length) && ((_f = (_e = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _e.discount_list) == null ? void 0 : _f.every((discount2) => discount2.id)));
|
|
629
650
|
const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
|
|
630
|
-
if (isAvailableProduct &&
|
|
651
|
+
if (isAvailableProduct && isLimitedProduct && timeLimit && isBundleAvailable && ((_g = discount.config) == null ? void 0 : _g.isAvailable)) {
|
|
631
652
|
(_h = discountApplicability.get(discount.id)) == null ? void 0 : _h.push(product.id);
|
|
632
653
|
const applicableProducts = discountApplicableProducts.get(discount.id) || [];
|
|
633
654
|
const discountType = discount.tag || discount.type;
|
|
@@ -750,12 +771,19 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
750
771
|
}
|
|
751
772
|
const applicableDiscounts = sortedDiscountList.filter((discount) => {
|
|
752
773
|
var _a3, _b2, _c2, _d2;
|
|
753
|
-
if (this.isItemRewardProductDiscount(product))
|
|
754
|
-
return false;
|
|
755
774
|
const discountType = discount.tag || discount.type;
|
|
775
|
+
const currentOriginUid = getOriginProductUid(originProduct);
|
|
776
|
+
const isReapplyEditModeDiscountForProduct = discount.isEditMode && reapplyBookingDiscountProductUids.size > 0 && currentOriginUid && reapplyBookingDiscountProductUids.has(String(currentOriginUid)) && discount.isSelected === true;
|
|
777
|
+
if (discount.isEditMode && reapplyBookingDiscountProductUids.size > 0) {
|
|
778
|
+
const uid = currentOriginUid;
|
|
779
|
+
if (!uid || !reapplyBookingDiscountProductUids.has(uid))
|
|
780
|
+
return false;
|
|
781
|
+
if (!discount.isSelected)
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
756
784
|
if (["good_pass", "discount_card", "product_discount_card"].includes(
|
|
757
785
|
discountType
|
|
758
|
-
)) {
|
|
786
|
+
) && !isReapplyEditModeDiscountForProduct) {
|
|
759
787
|
if (discount.config === void 0 || !((_a3 = discount == null ? void 0 : discount.config) == null ? void 0 : _a3.isAvailable)) {
|
|
760
788
|
return false;
|
|
761
789
|
}
|
|
@@ -817,7 +845,6 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
817
845
|
);
|
|
818
846
|
const selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
|
|
819
847
|
let isManualDiscount = false;
|
|
820
|
-
let isItemRewardProductDiscount = false;
|
|
821
848
|
if (flatItem.type === "main") {
|
|
822
849
|
isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : ((_g = product.discount_list) == null ? void 0 : _g.some((item) => item.type === "product")) || product.total != product.origin_total && (product.bundle || []).every(
|
|
823
850
|
(item) => {
|
|
@@ -828,8 +855,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
828
855
|
_i,
|
|
829
856
|
(item) => item.type === "product"
|
|
830
857
|
)));
|
|
831
|
-
|
|
832
|
-
if (product.inPromotion && !isItemRewardProductDiscount) {
|
|
858
|
+
if (product.inPromotion) {
|
|
833
859
|
isManualDiscount = false;
|
|
834
860
|
}
|
|
835
861
|
} else {
|
|
@@ -943,7 +969,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
943
969
|
} else {
|
|
944
970
|
let total = product.inPromotion ? ((_w = product == null ? void 0 : product._promotion) == null ? void 0 : _w.finalPrice) ?? product.origin_total ?? product.total : product.origin_total ?? product.total;
|
|
945
971
|
let main_product_selling_price = product.price;
|
|
946
|
-
if ((product.discount_list || []).some((item) => item.type === "promotion") ||
|
|
972
|
+
if ((product.discount_list || []).some((item) => item.type === "promotion") || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
|
|
947
973
|
total = product.total ?? product.origin_total;
|
|
948
974
|
main_product_selling_price = product.main_product_selling_price ?? main_product_selling_price;
|
|
949
975
|
}
|
|
@@ -951,8 +977,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
951
977
|
this.hooks.setProduct(originProduct, {
|
|
952
978
|
...isManualDiscount ? {
|
|
953
979
|
price: product.price,
|
|
954
|
-
main_product_selling_price:
|
|
955
|
-
...isItemRewardProductDiscount ? { total } : {}
|
|
980
|
+
main_product_selling_price: product.price
|
|
956
981
|
} : {
|
|
957
982
|
_id: product._id.split("___")[0] + "___" + index,
|
|
958
983
|
total,
|
|
@@ -974,7 +999,8 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
974
999
|
}
|
|
975
1000
|
return;
|
|
976
1001
|
}
|
|
977
|
-
|
|
1002
|
+
const shouldReapplyBookingDiscountForProduct = shouldReapplyBookingDiscount(originProduct, selectedDiscount);
|
|
1003
|
+
if (applicableDiscounts.length && product.booking_id && typeof selectedDiscount.isManualSelect === "undefined" && !(options == null ? void 0 : options.scan) && !isEditModeAddNewProduct && !shouldReapplyBookingDiscountForProduct) {
|
|
978
1004
|
return;
|
|
979
1005
|
}
|
|
980
1006
|
const isNeedSplit = (selectedDiscount.tag || selectedDiscount.type) === "good_pass";
|
|
@@ -1030,10 +1056,16 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1030
1056
|
let productDiscountDifference;
|
|
1031
1057
|
let discountedOptions = product.options;
|
|
1032
1058
|
let optionDiscountAmount = 0;
|
|
1059
|
+
let reapplyDiscountPercent;
|
|
1033
1060
|
if (isOrderLevel && productAllocation) {
|
|
1034
1061
|
amount = productAllocation.discountAmount;
|
|
1035
1062
|
productDiscountDifference = productAllocation.difference;
|
|
1036
1063
|
mainProductSellingPrice = Math.max(new import_decimal.default(product.price).minus(amount).toNumber(), 0);
|
|
1064
|
+
} else if (resolveReapplyEditModeDiscountPercent(originProduct, selectedDiscount2) !== void 0) {
|
|
1065
|
+
const percent = resolveReapplyEditModeDiscountPercent(originProduct, selectedDiscount2);
|
|
1066
|
+
reapplyDiscountPercent = new import_decimal.default(percent).toFixed(2);
|
|
1067
|
+
mainProductSellingPrice = new import_decimal.default(product.price || 0).mul(new import_decimal.default(100).minus(percent)).div(100).toDecimalPlaces(2).toNumber();
|
|
1068
|
+
amount = new import_decimal.default(product.price).minus(mainProductSellingPrice).toNumber();
|
|
1037
1069
|
} else {
|
|
1038
1070
|
mainProductSellingPrice = (0, import_utils.getDiscountAmount)(
|
|
1039
1071
|
selectedDiscount2,
|
|
@@ -1068,7 +1100,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
|
|
|
1068
1100
|
title: selectedDiscount2.format_title,
|
|
1069
1101
|
original_amount: product.price,
|
|
1070
1102
|
product_id: originProduct.id || originProduct.product_id,
|
|
1071
|
-
percent: selectedDiscount2.par_value,
|
|
1103
|
+
percent: reapplyDiscountPercent ?? selectedDiscount2.par_value,
|
|
1072
1104
|
discount_product_id: selectedDiscount2.product_id
|
|
1073
1105
|
},
|
|
1074
1106
|
// 前端使用的num数量,为了计算优惠金额
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Discount } from '../Discount/types';
|
|
2
|
+
import { SetDiscountSelectedParams } from '../../solution/ShopDiscount/types';
|
|
2
3
|
export declare enum UnavailableReason {
|
|
3
4
|
TimeLimit = "time_limit",
|
|
4
5
|
ProductNotApplicable = "product_not_applicable",
|
|
@@ -23,6 +24,14 @@ export interface DiscountResult {
|
|
|
23
24
|
discountList: any[];
|
|
24
25
|
}
|
|
25
26
|
export type RulesFormSubject = boolean | ((product: any) => boolean);
|
|
27
|
+
export interface RulesCalcDiscountOptions {
|
|
28
|
+
isSelected?: boolean;
|
|
29
|
+
discountId?: number;
|
|
30
|
+
selectedList?: SetDiscountSelectedParams[];
|
|
31
|
+
scan?: boolean;
|
|
32
|
+
/** Change time 重报价目标行:允许已选编辑态折扣卡重新应用到这些 booking 商品。 */
|
|
33
|
+
reapplyBookingDiscountProductUids?: string[];
|
|
34
|
+
}
|
|
26
35
|
export interface RulesModuleAPI {
|
|
27
36
|
setRulesList: (rulesList: Rules[]) => Promise<void>;
|
|
28
37
|
clear: () => Promise<void>;
|
|
@@ -34,7 +43,7 @@ export interface RulesModuleAPI {
|
|
|
34
43
|
}[];
|
|
35
44
|
isFormSubject: RulesFormSubject;
|
|
36
45
|
orderTotalAmount: number;
|
|
37
|
-
}) => DiscountResult;
|
|
46
|
+
}, options?: RulesCalcDiscountOptions) => DiscountResult;
|
|
38
47
|
}
|
|
39
48
|
type ProductDetail = {
|
|
40
49
|
isClient?: boolean;
|
package/lib/server/index.d.ts
CHANGED
|
@@ -47,6 +47,8 @@ declare class Server {
|
|
|
47
47
|
private prefixRouterGet;
|
|
48
48
|
router: Router;
|
|
49
49
|
private productQuerySubscribers;
|
|
50
|
+
/** subscriberId → 智能定价变价时间点定时器句柄(与 subscriber 分离存储,便于 clear) */
|
|
51
|
+
private productQueryScheduleTimers;
|
|
50
52
|
private orderQuerySubscribers;
|
|
51
53
|
private bookingQuerySubscribers;
|
|
52
54
|
private bookingRemoteQuerySubscribers;
|
|
@@ -210,6 +212,48 @@ declare class Server {
|
|
|
210
212
|
* 根据 subscriberId 移除商品查询订阅者
|
|
211
213
|
*/
|
|
212
214
|
removeProductQuerySubscriber(subscriberId?: string): void;
|
|
215
|
+
/**
|
|
216
|
+
* 构建商品 query 响应 data 段,附带智能定价 schedule_time_points 元数据。
|
|
217
|
+
*/
|
|
218
|
+
private buildProductQueryResultPayload;
|
|
219
|
+
/**
|
|
220
|
+
* 是否启用商品 query 订阅的 schedule 时间点定时重算。
|
|
221
|
+
* strategy_context.enable_schedule_reload === false 时关闭。
|
|
222
|
+
*/
|
|
223
|
+
private shouldScheduleProductQueryReload;
|
|
224
|
+
/**
|
|
225
|
+
* 清除指定 subscriber 的全部 schedule 定时器,防止重复 query 或 unsubscribe 后泄漏。
|
|
226
|
+
*/
|
|
227
|
+
private clearSubscriberScheduleTimers;
|
|
228
|
+
/**
|
|
229
|
+
* 从 productQueryScheduleTimers 移除已触发的 timer 引用。
|
|
230
|
+
*/
|
|
231
|
+
private removeScheduleTimerRef;
|
|
232
|
+
/**
|
|
233
|
+
* 计算 schedule 变价时间点到当前时刻的延迟(ms)。已过期返回 -1。
|
|
234
|
+
*/
|
|
235
|
+
private computeScheduleTimePointDelayMs;
|
|
236
|
+
/**
|
|
237
|
+
* 定时重算前刷新 subscriber schedule 上下文:使用执行瞬间时间,禁止沿用首次 query 的 schedule_datetime。
|
|
238
|
+
*/
|
|
239
|
+
private refreshSubscriberScheduleAtExecution;
|
|
240
|
+
/**
|
|
241
|
+
* 为 subscriber 注册智能定价 scheduleTimePoints 定时重算。
|
|
242
|
+
* 必须先 clearSubscriberScheduleTimers,再调用本方法。
|
|
243
|
+
*/
|
|
244
|
+
private scheduleSubscriberTimePointReloads;
|
|
245
|
+
/**
|
|
246
|
+
* schedule 变价时间点定时器触发:刷新 schedule_datetime 后重算并 callback。
|
|
247
|
+
*/
|
|
248
|
+
private onScheduleTimePointTimerFire;
|
|
249
|
+
/**
|
|
250
|
+
* 对单个商品 query 订阅者重算并推送(定时路径;不新建 schedule timer)。
|
|
251
|
+
*/
|
|
252
|
+
private recomputeAndNotifySubscriber;
|
|
253
|
+
/**
|
|
254
|
+
* query 完成后为 subscriber 同步 schedule 定时器(先 clear 再 schedule)。
|
|
255
|
+
*/
|
|
256
|
+
private syncProductQueryScheduleTimers;
|
|
213
257
|
/**
|
|
214
258
|
* 处理商品查询请求
|
|
215
259
|
* 存储订阅者信息,便于数据变更时推送最新结果
|
|
@@ -445,6 +489,11 @@ declare class Server {
|
|
|
445
489
|
private sumPaidOrderPayments;
|
|
446
490
|
private toAmountNumber;
|
|
447
491
|
private buildSmallTicketProductMap;
|
|
492
|
+
private collectSalesDetailProductIds;
|
|
493
|
+
private buildSalesDetailProductSnapshotMap;
|
|
494
|
+
private withProductCatalogSnapshots;
|
|
495
|
+
private withBundleCatalogSnapshots;
|
|
496
|
+
private withSalesDetailProductSnapshots;
|
|
448
497
|
private withPendingSyncProductTitles;
|
|
449
498
|
private buildProductTitleSnapshot;
|
|
450
499
|
private getProductTitleSnapshotCurrentLocale;
|
|
@@ -565,6 +614,12 @@ declare class Server {
|
|
|
565
614
|
* @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
|
|
566
615
|
*/
|
|
567
616
|
private computeProductQueryResult;
|
|
617
|
+
/**
|
|
618
|
+
* 构建商品格式化上下文。
|
|
619
|
+
*
|
|
620
|
+
* 智能定价条件使用全量 menuList/scheduleList;Product Query 顶层参数只保留筛选商品集合所需字段。
|
|
621
|
+
*/
|
|
622
|
+
private buildProductFormatterContext;
|
|
568
623
|
/**
|
|
569
624
|
* 数据变更后,遍历所有订阅者重新计算查询结果并通过 callback 推送
|
|
570
625
|
* 由 ProductsModule 的 onProductsSyncCompleted 事件触发
|