@pisell/pisellos 2.1.162 → 2.1.163
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/index.d.ts +1 -0
- package/dist/index.js +3 -0
- 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/index.js +9 -0
- package/dist/modules/Discount/index.d.ts +5 -2
- package/dist/modules/Discount/index.js +21 -1
- package/dist/modules/Discount/types.d.ts +4 -0
- package/dist/modules/Order/index.d.ts +1 -0
- package/dist/modules/Order/index.js +18 -6
- package/dist/modules/Order/types.d.ts +2 -0
- package/dist/modules/ProductList/index.d.ts +3 -1
- package/dist/modules/ProductList/index.js +22 -11
- package/dist/modules/Schedule/getDateIsInSchedule.js +5 -0
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/ScanOrder/index.js +1 -1
- package/dist/solution/ShopDiscount/index.js +16 -15
- package/dist/solution/VenueBooking/index.d.ts +23 -3
- package/dist/solution/VenueBooking/index.js +267 -168
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/dist/solution/VenueBooking/utils/dateSummary.js +12 -25
- package/dist/solution/VenueBooking/utils/slotMerge.d.ts +0 -6
- package/dist/solution/VenueBooking/utils/slotMerge.js +3 -9
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +70 -0
- package/dist/solution/VenueBooking/utils/smartPricing.js +233 -0
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +2 -0
- package/dist/solution/VenueBooking/utils/timeSlot.js +9 -4
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -0
- 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/modules/Discount/index.d.ts +5 -2
- package/lib/modules/Discount/index.js +11 -1
- package/lib/modules/Discount/types.d.ts +4 -0
- package/lib/modules/Order/index.d.ts +1 -0
- package/lib/modules/Order/index.js +11 -1
- package/lib/modules/Order/types.d.ts +2 -0
- package/lib/modules/ProductList/index.d.ts +3 -1
- package/lib/modules/ProductList/index.js +45 -39
- package/lib/modules/Schedule/getDateIsInSchedule.js +4 -0
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/ScanOrder/index.js +1 -1
- package/lib/solution/ShopDiscount/index.js +3 -2
- package/lib/solution/VenueBooking/index.d.ts +23 -3
- package/lib/solution/VenueBooking/index.js +164 -69
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/lib/solution/VenueBooking/utils/dateSummary.js +5 -10
- package/lib/solution/VenueBooking/utils/slotMerge.d.ts +0 -6
- package/lib/solution/VenueBooking/utils/slotMerge.js +3 -4
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +70 -0
- package/lib/solution/VenueBooking/utils/smartPricing.js +180 -0
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +2 -0
- package/lib/solution/VenueBooking/utils/timeSlot.js +7 -3
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@ export declare class ProductList extends BaseModule implements Module {
|
|
|
11
11
|
constructor(name?: string, version?: string);
|
|
12
12
|
initialize(core: PisellCore, options: any): Promise<void>;
|
|
13
13
|
storeChange(path?: string, value?: any): Promise<void>;
|
|
14
|
-
loadProducts({ category_ids, product_ids, collection, menu_list_ids, customer_id: paramsCustomerId, with_count, schedule_datetime, schedule_date, cacheId, with_schedule, }: {
|
|
14
|
+
loadProducts({ category_ids, product_ids, collection, menu_list_ids, customer_id: paramsCustomerId, with_count, schedule_datetime, schedule_date, cacheId, with_schedule, with_extra, }: {
|
|
15
15
|
category_ids?: number[];
|
|
16
16
|
product_ids?: number[];
|
|
17
17
|
collection?: number | string[];
|
|
@@ -22,6 +22,8 @@ export declare class ProductList extends BaseModule implements Module {
|
|
|
22
22
|
menu_list_ids?: number[];
|
|
23
23
|
with_count?: string[];
|
|
24
24
|
with_schedule?: number;
|
|
25
|
+
/** 追加到默认 with 字段(如 dataVariants) */
|
|
26
|
+
with_extra?: string[];
|
|
25
27
|
}): Promise<any>;
|
|
26
28
|
loadProductsPrice({ ids, customer_id, schedule_date, channel, }: {
|
|
27
29
|
ids?: number[];
|
|
@@ -59,7 +59,8 @@ var ProductList = class extends import_BaseModule.BaseModule {
|
|
|
59
59
|
schedule_datetime,
|
|
60
60
|
schedule_date,
|
|
61
61
|
cacheId,
|
|
62
|
-
with_schedule
|
|
62
|
+
with_schedule,
|
|
63
|
+
with_extra = []
|
|
63
64
|
}) {
|
|
64
65
|
var _a;
|
|
65
66
|
let userPlugin = this.core.getPlugin("user");
|
|
@@ -69,44 +70,49 @@ var ProductList = class extends import_BaseModule.BaseModule {
|
|
|
69
70
|
} catch (error) {
|
|
70
71
|
console.error(error);
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
73
|
+
try {
|
|
74
|
+
const productsData = await this.request.post(
|
|
75
|
+
`/product/query`,
|
|
76
|
+
{
|
|
77
|
+
open_quotation: 1,
|
|
78
|
+
open_bundle: 0,
|
|
79
|
+
exclude_extension_type: [
|
|
80
|
+
"product_party",
|
|
81
|
+
"product_event",
|
|
82
|
+
"product_series_event",
|
|
83
|
+
"product_package_ticket",
|
|
84
|
+
"ticket",
|
|
85
|
+
"event_item"
|
|
86
|
+
],
|
|
87
|
+
with: ["category", "collection", "resourceRelation", ...with_extra],
|
|
88
|
+
status: "published",
|
|
89
|
+
num: 500,
|
|
90
|
+
skip: 1,
|
|
91
|
+
customer_id,
|
|
92
|
+
category_ids,
|
|
93
|
+
ids: product_ids,
|
|
94
|
+
collection,
|
|
95
|
+
front_end_cache_id: cacheId,
|
|
96
|
+
with_count,
|
|
97
|
+
// client_schedule_ids: schedule_ids,
|
|
98
|
+
schedule_date,
|
|
99
|
+
schedule_datetime,
|
|
100
|
+
// application_code: this.otherParams?.channel === 'online_store' ? 'online-store' : this.otherParams?.channel,
|
|
101
|
+
application_code: "online-store",
|
|
102
|
+
with_schedule,
|
|
103
|
+
is_eject: 1,
|
|
104
|
+
menu_list_ids,
|
|
105
|
+
open_deposit: 1
|
|
106
|
+
},
|
|
107
|
+
{ useCache: true, customToast: () => {
|
|
108
|
+
} }
|
|
109
|
+
);
|
|
110
|
+
const sortedList = (productsData.data.list || []).slice().sort((a, b) => Number(b.sort) - Number(a.sort));
|
|
111
|
+
this.addProduct(sortedList);
|
|
112
|
+
return sortedList;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
return error;
|
|
115
|
+
}
|
|
110
116
|
}
|
|
111
117
|
async loadProductsPrice({
|
|
112
118
|
ids = [],
|
|
@@ -34,6 +34,10 @@ __export(getDateIsInSchedule_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(getDateIsInSchedule_exports);
|
|
36
36
|
var import_dayjs = __toESM(require("dayjs"));
|
|
37
|
+
var import_isSameOrAfter = __toESM(require("dayjs/plugin/isSameOrAfter"));
|
|
38
|
+
var import_isSameOrBefore = __toESM(require("dayjs/plugin/isSameOrBefore"));
|
|
39
|
+
import_dayjs.default.extend(import_isSameOrAfter.default);
|
|
40
|
+
import_dayjs.default.extend(import_isSameOrBefore.default);
|
|
37
41
|
var getDateIsInSchedule = (dateTime, scheduleList) => {
|
|
38
42
|
if (!dateTime || !scheduleList || scheduleList.length === 0) {
|
|
39
43
|
return false;
|
|
@@ -310,7 +310,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
310
310
|
date: string;
|
|
311
311
|
status: string;
|
|
312
312
|
week: string;
|
|
313
|
-
weekNum: 0 |
|
|
313
|
+
weekNum: 0 | 1 | 5 | 4 | 2 | 3 | 6;
|
|
314
314
|
}[]>;
|
|
315
315
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
316
316
|
private getScheduleDataByIds;
|
|
@@ -329,7 +329,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
329
329
|
count: number;
|
|
330
330
|
left: number;
|
|
331
331
|
summaryCount: number;
|
|
332
|
-
status: "
|
|
332
|
+
status: "sold_out" | "lots_of_space" | "filling_up_fast";
|
|
333
333
|
}[];
|
|
334
334
|
/**
|
|
335
335
|
* 找到多个资源的公共可用时间段
|
|
@@ -563,7 +563,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
563
563
|
...tempOrder.metadata || {},
|
|
564
564
|
shop_service_data: {
|
|
565
565
|
...(tempOrder.metadata || {}).shop_service_data || {},
|
|
566
|
-
service_type: ((_a = this.otherParams) == null ? void 0 : _a.businessCode) === "dine_in" ? "dine_in" : "
|
|
566
|
+
service_type: ((_a = this.otherParams) == null ? void 0 : _a.businessCode) === "dine_in" ? "dine_in" : "",
|
|
567
567
|
pickup_reference_mode: mode
|
|
568
568
|
}
|
|
569
569
|
};
|
|
@@ -511,7 +511,7 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
511
511
|
try {
|
|
512
512
|
const orderId = this.store.orderId;
|
|
513
513
|
const customerId = params.customerId || ((_a = this.getCustomer()) == null ? void 0 : _a.id);
|
|
514
|
-
const
|
|
514
|
+
const prepareConfig = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
|
|
515
515
|
customer_id: customerId,
|
|
516
516
|
action: orderId ? "edit" : "create",
|
|
517
517
|
with_good_pass: 1,
|
|
@@ -520,11 +520,12 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
|
|
|
520
520
|
request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
521
521
|
...orderId ? { order_id: orderId } : {}
|
|
522
522
|
}));
|
|
523
|
+
const goodPassList = (prepareConfig == null ? void 0 : prepareConfig.discountList) || [];
|
|
523
524
|
const scanDiscount = (_c = this.getDiscountList()) == null ? void 0 : _c.filter(
|
|
524
525
|
(item) => item.isScan
|
|
525
526
|
);
|
|
526
527
|
const scanDiscountIds = scanDiscount.map((n) => n.id);
|
|
527
|
-
const newGoodPassList = goodPassList
|
|
528
|
+
const newGoodPassList = goodPassList.filter((n) => !scanDiscountIds.includes(n.id));
|
|
528
529
|
const newDiscountList = [...scanDiscount, ...newGoodPassList || []];
|
|
529
530
|
this.store.originalDiscountList = newDiscountList;
|
|
530
531
|
await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(newDiscountList));
|
|
@@ -3,6 +3,7 @@ import { BaseModule } from '../../modules/BaseModule';
|
|
|
3
3
|
import { VenueBookingAddLogParams, VenueBookingSlotConfig, VenueDateSummaryItem, VenueSlotSelection, VenueTimeSlotGrid } from './types';
|
|
4
4
|
import type { ScanOrderOrderProduct, ScanOrderOrderProductIdentity } from '../ScanOrder/types';
|
|
5
5
|
import type { UpdateProductInOrderParams } from '../../modules/Order/types';
|
|
6
|
+
import type { ScheduleItem } from '../../modules/Schedule/types';
|
|
6
7
|
import type { OpenDataAvailabilityResult } from '../../modules/OpenData';
|
|
7
8
|
import type { ProductData } from '../../modules/Product/types';
|
|
8
9
|
import { type CartItemSummary, type PaxInfo, type QuantityCheckResult, type QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
|
|
@@ -40,6 +41,10 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
|
|
|
40
41
|
private productsLoaded;
|
|
41
42
|
private loadOpenDataConfigInFlight;
|
|
42
43
|
private static readonly OPEN_DATA_CACHE_TTL;
|
|
44
|
+
/** 按日期缓存 slot 智能定价 Map,避免同周重复 resolveProducts */
|
|
45
|
+
private slotPriceMapCache;
|
|
46
|
+
/** loadProducts 后缓存的全量商品(venue + addon),供分段算价复用 */
|
|
47
|
+
private smartPricingProductCatalog;
|
|
43
48
|
private getLoggerContext;
|
|
44
49
|
private safeStringify;
|
|
45
50
|
private pickErrorMessage;
|
|
@@ -68,6 +73,22 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
|
|
|
68
73
|
passed: boolean | null;
|
|
69
74
|
failures: QuantityCheckResult[];
|
|
70
75
|
};
|
|
76
|
+
/** 清除 slot 价格分段缓存(商品重载 / 登录后 customerId 变化时调用) */
|
|
77
|
+
private clearSlotPriceMapCache;
|
|
78
|
+
/** 读取当前登录 customerId */
|
|
79
|
+
private resolveCustomerIdForSmartPricing;
|
|
80
|
+
private resolveAvailableWalletIdsForSmartPricing;
|
|
81
|
+
/** 读取 schedule 全量列表,供智能定价 schedule_match 使用 */
|
|
82
|
+
private getScheduleListForSmartPricing;
|
|
83
|
+
/** 构建智能定价上下文,对齐 OS Server buildProductFormatterContext */
|
|
84
|
+
private buildSmartPricingContext;
|
|
85
|
+
/** venue + addon 全量商品,供智能定价评估 */
|
|
86
|
+
private getAllProductsForSmartPricing;
|
|
87
|
+
private getSlotPriceMapCacheKey;
|
|
88
|
+
/**
|
|
89
|
+
* 按 schedule 分段构建 slot 价格 Map,带实例级缓存。
|
|
90
|
+
*/
|
|
91
|
+
private buildSlotPriceMapForDate;
|
|
71
92
|
loadAllProducts(): Promise<{
|
|
72
93
|
venueProducts: ProductData[];
|
|
73
94
|
addonProducts: ProductData[];
|
|
@@ -140,8 +161,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
|
|
|
140
161
|
setSlotConfig(config: Partial<VenueBookingSlotConfig>): void;
|
|
141
162
|
getSlotConfig(): VenueBookingSlotConfig;
|
|
142
163
|
loadSchedules(): Promise<void>;
|
|
143
|
-
|
|
144
|
-
getScheduleListByIds(ids: number[]): import("../../modules/Schedule/types").ScheduleItem[];
|
|
164
|
+
getScheduleListByIds(ids: number[]): ScheduleItem[];
|
|
145
165
|
getTempOrder(): import("./types").ScanOrderTempOrder | null;
|
|
146
166
|
updateTempOrderNote(note: string): string;
|
|
147
167
|
updateTempOrderContactsInfo(contactsInfo: any[]): any[];
|
|
@@ -149,7 +169,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
|
|
|
149
169
|
onCustomerLogin(params: {
|
|
150
170
|
customerId: number;
|
|
151
171
|
}): Promise<void>;
|
|
152
|
-
private
|
|
172
|
+
private recalculateOrderPricesFromSmartPricing;
|
|
153
173
|
scanCode(code: string, customerId?: number): Promise<{
|
|
154
174
|
isAvailable: boolean;
|
|
155
175
|
discountList: import("../../modules/Discount").Discount[];
|
|
@@ -50,6 +50,7 @@ var import_resource = require("./utils/resource");
|
|
|
50
50
|
var import_timeSlot = require("./utils/timeSlot");
|
|
51
51
|
var import_dateSummary = require("./utils/dateSummary");
|
|
52
52
|
var import_slotMerge = require("./utils/slotMerge");
|
|
53
|
+
var import_smartPricing = require("./utils/smartPricing");
|
|
53
54
|
var import_utils3 = require("../../modules/Order/utils");
|
|
54
55
|
var import_Order = require("../../modules/Order");
|
|
55
56
|
var import_types4 = require("../RegisterAndLogin/types");
|
|
@@ -110,6 +111,10 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
110
111
|
this.loadAllProductsInFlight = null;
|
|
111
112
|
this.productsLoaded = false;
|
|
112
113
|
this.loadOpenDataConfigInFlight = null;
|
|
114
|
+
/** 按日期缓存 slot 智能定价 Map,避免同周重复 resolveProducts */
|
|
115
|
+
this.slotPriceMapCache = /* @__PURE__ */ new Map();
|
|
116
|
+
/** loadProducts 后缓存的全量商品(venue + addon),供分段算价复用 */
|
|
117
|
+
this.smartPricingProductCatalog = [];
|
|
113
118
|
}
|
|
114
119
|
getLoggerContext() {
|
|
115
120
|
return {
|
|
@@ -298,16 +303,11 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
298
303
|
}
|
|
299
304
|
this.customerLoginRefreshIdInFlight = params.customerId;
|
|
300
305
|
const refreshTask = (async () => {
|
|
301
|
-
var _a;
|
|
302
|
-
if (this.store.quotation) {
|
|
303
|
-
await this.store.quotation.loadQuotations({
|
|
304
|
-
channel: (_a = this.otherParams) == null ? void 0 : _a.channel
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
this.recalculateOrderPricesFromQuotation();
|
|
308
306
|
await this.store.order.loadDiscountConfig({
|
|
309
307
|
customerId: params.customerId
|
|
310
308
|
});
|
|
309
|
+
this.clearSlotPriceMapCache();
|
|
310
|
+
this.recalculateOrderPricesFromSmartPricing();
|
|
311
311
|
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
312
312
|
this.store.order.persistTempOrder();
|
|
313
313
|
await this.refreshItemRuleQuantityLimits();
|
|
@@ -326,7 +326,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
328
|
async initialize(core, options = {}) {
|
|
329
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i
|
|
329
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
330
330
|
this.logMethodStart("initialize");
|
|
331
331
|
this.core = core;
|
|
332
332
|
this.initializeOptions = options || {};
|
|
@@ -462,10 +462,6 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
462
462
|
await this.loadRuntimeConfigs();
|
|
463
463
|
if (this.store.schedule) {
|
|
464
464
|
await this.store.schedule.loadAllSchedule();
|
|
465
|
-
this.injectScheduleResolverToQuotation();
|
|
466
|
-
(_k = this.store.quotation) == null ? void 0 : _k.loadQuotations({
|
|
467
|
-
channel: (_j = this.otherParams) == null ? void 0 : _j.channel
|
|
468
|
-
});
|
|
469
465
|
}
|
|
470
466
|
await this.refreshItemRuleQuantityLimits();
|
|
471
467
|
this.store.status = "ready";
|
|
@@ -541,6 +537,93 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
541
537
|
getCartValidation() {
|
|
542
538
|
return this.store.cartValidation || { passed: null, failures: [] };
|
|
543
539
|
}
|
|
540
|
+
/** 清除 slot 价格分段缓存(商品重载 / 登录后 customerId 变化时调用) */
|
|
541
|
+
clearSlotPriceMapCache() {
|
|
542
|
+
this.slotPriceMapCache.clear();
|
|
543
|
+
}
|
|
544
|
+
/** 读取当前登录 customerId */
|
|
545
|
+
resolveCustomerIdForSmartPricing() {
|
|
546
|
+
var _a, _b, _c;
|
|
547
|
+
try {
|
|
548
|
+
const userPlugin = (_a = this.core) == null ? void 0 : _a.getPlugin("user");
|
|
549
|
+
const customerId = Number((_c = (_b = userPlugin == null ? void 0 : userPlugin.get) == null ? void 0 : _b.call(userPlugin)) == null ? void 0 : _c.id);
|
|
550
|
+
return Number.isFinite(customerId) && customerId > 0 ? customerId : void 0;
|
|
551
|
+
} catch {
|
|
552
|
+
return void 0;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
resolveAvailableWalletIdsForSmartPricing() {
|
|
556
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
557
|
+
const orderWalletIds = (_b = (_a = this.store.order) == null ? void 0 : _a.getAvailableWalletIds) == null ? void 0 : _b.call(_a);
|
|
558
|
+
const fallbackWalletIds = ((_c = this.otherParams) == null ? void 0 : _c.available_wallet_ids) || ((_d = this.otherParams) == null ? void 0 : _d.availableWalletIds) || ((_f = (_e = this.otherParams) == null ? void 0 : _e.strategy_context) == null ? void 0 : _f.available_wallet_ids) || ((_h = (_g = this.otherParams) == null ? void 0 : _g.strategy_context) == null ? void 0 : _h.availableWalletIds);
|
|
559
|
+
const source = Array.isArray(orderWalletIds) && orderWalletIds.length ? orderWalletIds : fallbackWalletIds;
|
|
560
|
+
if (!Array.isArray(source))
|
|
561
|
+
return [];
|
|
562
|
+
const ids = source.map((item) => Number(item)).filter((item) => Number.isFinite(item) && item > 0);
|
|
563
|
+
return Array.from(new Set(ids));
|
|
564
|
+
}
|
|
565
|
+
/** 读取 schedule 全量列表,供智能定价 schedule_match 使用 */
|
|
566
|
+
getScheduleListForSmartPricing() {
|
|
567
|
+
var _a;
|
|
568
|
+
const scheduleModule = this.store.schedule;
|
|
569
|
+
const list = (_a = scheduleModule == null ? void 0 : scheduleModule.store) == null ? void 0 : _a.scheduleList;
|
|
570
|
+
return Array.isArray(list) ? list : [];
|
|
571
|
+
}
|
|
572
|
+
/** 构建智能定价上下文,对齐 OS Server buildProductFormatterContext */
|
|
573
|
+
buildSmartPricingContext(customerId) {
|
|
574
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
575
|
+
const evaluator = (_b = (_a = this.core) == null ? void 0 : _a.context) == null ? void 0 : _b.dataVariantEvaluator;
|
|
576
|
+
return {
|
|
577
|
+
evaluator,
|
|
578
|
+
scheduleList: this.getScheduleListForSmartPricing(),
|
|
579
|
+
menuList: ((_c = this.otherParams) == null ? void 0 : _c.menuList) || ((_e = (_d = this.otherParams) == null ? void 0 : _d.openData) == null ? void 0 : _e.menuList) || [],
|
|
580
|
+
customerId: customerId ?? this.resolveCustomerIdForSmartPricing(),
|
|
581
|
+
availableWalletIds: this.resolveAvailableWalletIdsForSmartPricing(),
|
|
582
|
+
channel: (_f = this.otherParams) == null ? void 0 : _f.channel,
|
|
583
|
+
businessCode: (_g = this.otherParams) == null ? void 0 : _g.businessCode,
|
|
584
|
+
orderType: ((_h = this.otherParams) == null ? void 0 : _h.orderType) || ((_i = this.otherParams) == null ? void 0 : _i.type),
|
|
585
|
+
strategy_context: (_j = this.otherParams) == null ? void 0 : _j.strategy_context
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
/** venue + addon 全量商品,供智能定价评估 */
|
|
589
|
+
getAllProductsForSmartPricing() {
|
|
590
|
+
if (this.smartPricingProductCatalog.length) {
|
|
591
|
+
return this.smartPricingProductCatalog;
|
|
592
|
+
}
|
|
593
|
+
const venueList = this.getVenueProducts();
|
|
594
|
+
const addonList = this.getAddonProductsList();
|
|
595
|
+
return [...venueList, ...addonList];
|
|
596
|
+
}
|
|
597
|
+
getSlotPriceMapCacheKey(date, context) {
|
|
598
|
+
return [
|
|
599
|
+
date,
|
|
600
|
+
context.customerId ?? "",
|
|
601
|
+
(context.availableWalletIds || []).join(","),
|
|
602
|
+
context.channel ?? "",
|
|
603
|
+
context.businessCode ?? ""
|
|
604
|
+
].join("|");
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* 按 schedule 分段构建 slot 价格 Map,带实例级缓存。
|
|
608
|
+
*/
|
|
609
|
+
buildSlotPriceMapForDate(date, config, productIds) {
|
|
610
|
+
const context = this.buildSmartPricingContext();
|
|
611
|
+
const cacheKey = this.getSlotPriceMapCacheKey(date, context);
|
|
612
|
+
const cached = this.slotPriceMapCache.get(cacheKey);
|
|
613
|
+
if (cached)
|
|
614
|
+
return cached;
|
|
615
|
+
const timeLabels = (0, import_timeSlot.generateTimeLabels)(config);
|
|
616
|
+
const slotPriceMap = (0, import_smartPricing.buildSlotPriceMapByScheduleSegments)({
|
|
617
|
+
products: this.getAllProductsForSmartPricing(),
|
|
618
|
+
productIds,
|
|
619
|
+
date,
|
|
620
|
+
timeLabels,
|
|
621
|
+
config,
|
|
622
|
+
context
|
|
623
|
+
});
|
|
624
|
+
this.slotPriceMapCache.set(cacheKey, slotPriceMap);
|
|
625
|
+
return slotPriceMap;
|
|
626
|
+
}
|
|
544
627
|
// ─── 场地商品 & 附加商品 ───
|
|
545
628
|
async loadAllProducts() {
|
|
546
629
|
if (this.loadAllProductsInFlight)
|
|
@@ -569,9 +652,18 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
569
652
|
menu_list_ids: menuListIds,
|
|
570
653
|
cacheId: this.cacheId,
|
|
571
654
|
schedule_date: (0, import_dayjs.default)().format("YYYY-MM-DD"),
|
|
572
|
-
schedule_datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
655
|
+
schedule_datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
|
|
656
|
+
with_extra: ["dataVariants"]
|
|
573
657
|
});
|
|
574
|
-
const
|
|
658
|
+
const rawList = Array.isArray(allProducts) ? allProducts : [];
|
|
659
|
+
let list = rawList;
|
|
660
|
+
this.smartPricingProductCatalog = rawList.slice();
|
|
661
|
+
list = (0, import_smartPricing.formatProductsWithDataVariant)(
|
|
662
|
+
list,
|
|
663
|
+
this.buildSmartPricingContext(),
|
|
664
|
+
(0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
665
|
+
);
|
|
666
|
+
this.clearSlotPriceMapCache();
|
|
575
667
|
const venueList = list.filter((p) => p.duration != null);
|
|
576
668
|
const addonList = list.filter((p) => p.duration == null);
|
|
577
669
|
const venueStore = (_c = this.store.venueProducts) == null ? void 0 : _c.store;
|
|
@@ -752,29 +844,24 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
752
844
|
config: this.baseSlotConfig,
|
|
753
845
|
rawResources: this.store.rawResourceData,
|
|
754
846
|
resourceProductMap: this.resourceProductMap,
|
|
755
|
-
|
|
756
|
-
|
|
847
|
+
resolveConfig: (date) => this.resolveSlotConfigForDate(date),
|
|
848
|
+
buildSlotPriceMap: (date, config, productIds) => this.buildSlotPriceMapForDate(date, config, productIds)
|
|
757
849
|
});
|
|
758
850
|
}
|
|
759
851
|
getTimeSlotGrid(date) {
|
|
760
852
|
const resolvedSlotConfig = this.syncOperatingHoursToSlotConfig(date);
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
];
|
|
768
|
-
const timeLabels = (0, import_timeSlot.generateTimeLabels)(resolvedSlotConfig);
|
|
769
|
-
const timePoints = timeLabels.map((label) => `${date} ${label}`);
|
|
770
|
-
quotationPriceMap = this.store.quotation.buildProductPriceMap({ productIds, timePoints });
|
|
771
|
-
}
|
|
853
|
+
const productIds = [
|
|
854
|
+
...new Set(
|
|
855
|
+
[...this.resourceProductMap.values()].flat().map((m) => m.productId)
|
|
856
|
+
)
|
|
857
|
+
];
|
|
858
|
+
const slotPriceMap = productIds.length ? this.buildSlotPriceMapForDate(date, resolvedSlotConfig, productIds) : void 0;
|
|
772
859
|
return (0, import_timeSlot.buildTimeSlotGrid)({
|
|
773
860
|
date,
|
|
774
861
|
config: resolvedSlotConfig,
|
|
775
862
|
rawResources: this.store.rawResourceData,
|
|
776
863
|
resourceProductMap: this.resourceProductMap,
|
|
777
|
-
|
|
864
|
+
slotPriceMap
|
|
778
865
|
});
|
|
779
866
|
}
|
|
780
867
|
// ─── 时间槽订单操作 ───
|
|
@@ -1059,8 +1146,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1059
1146
|
booking_uid: bookingUuid,
|
|
1060
1147
|
price_breakdown: (0, import_slotMerge.buildPriceBreakdown)({
|
|
1061
1148
|
group,
|
|
1062
|
-
productId: mapping.productId
|
|
1063
|
-
quotation: this.store.quotation
|
|
1149
|
+
productId: mapping.productId
|
|
1064
1150
|
})
|
|
1065
1151
|
},
|
|
1066
1152
|
_origin: {
|
|
@@ -1153,20 +1239,12 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1153
1239
|
if (!this.store.schedule)
|
|
1154
1240
|
throw new Error("schedule 模块未初始化");
|
|
1155
1241
|
await this.store.schedule.loadAllSchedule();
|
|
1156
|
-
this.injectScheduleResolverToQuotation();
|
|
1157
1242
|
this.logMethodSuccess("loadSchedules");
|
|
1158
1243
|
} catch (error) {
|
|
1159
1244
|
this.logMethodError("loadSchedules", error);
|
|
1160
1245
|
throw error;
|
|
1161
1246
|
}
|
|
1162
1247
|
}
|
|
1163
|
-
injectScheduleResolverToQuotation() {
|
|
1164
|
-
if (this.store.quotation && this.store.schedule) {
|
|
1165
|
-
this.store.quotation.setScheduleResolver(
|
|
1166
|
-
(id) => this.store.schedule.getScheduleListByIds([id])[0]
|
|
1167
|
-
);
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
1248
|
getScheduleListByIds(ids) {
|
|
1171
1249
|
if (!this.store.schedule)
|
|
1172
1250
|
return [];
|
|
@@ -1205,14 +1283,16 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1205
1283
|
throw error;
|
|
1206
1284
|
}
|
|
1207
1285
|
}
|
|
1208
|
-
|
|
1286
|
+
recalculateOrderPricesFromSmartPricing() {
|
|
1209
1287
|
var _a, _b;
|
|
1210
|
-
if (!this.store.order
|
|
1288
|
+
if (!this.store.order)
|
|
1211
1289
|
return;
|
|
1212
1290
|
const tempOrder = this.store.order.getTempOrder();
|
|
1213
1291
|
if (!((_a = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _a.length))
|
|
1214
1292
|
return;
|
|
1215
1293
|
const now = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
1294
|
+
const catalog = this.getAllProductsForSmartPricing();
|
|
1295
|
+
const context = this.buildSmartPricingContext();
|
|
1216
1296
|
for (const product of tempOrder.products) {
|
|
1217
1297
|
if ((_b = product.metadata) == null ? void 0 : _b.venue_booking) {
|
|
1218
1298
|
const mappings = this.resourceProductMap.get(product.metadata.resource_id);
|
|
@@ -1225,34 +1305,49 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1225
1305
|
product,
|
|
1226
1306
|
this.store.slotConfig.slotDurationMinutes
|
|
1227
1307
|
);
|
|
1228
|
-
const
|
|
1229
|
-
...slot,
|
|
1230
|
-
|
|
1231
|
-
|
|
1308
|
+
const uniqueDates = [
|
|
1309
|
+
...new Set(slots.map((slot) => (0, import_dayjs.default)(slot.startTime).format("YYYY-MM-DD")))
|
|
1310
|
+
];
|
|
1311
|
+
const slotPriceMaps = /* @__PURE__ */ new Map();
|
|
1312
|
+
for (const slotDate of uniqueDates) {
|
|
1313
|
+
slotPriceMaps.set(
|
|
1314
|
+
slotDate,
|
|
1315
|
+
this.buildSlotPriceMapForDate(slotDate, this.store.slotConfig, [mapping.productId])
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
const updatedSlots = slots.map((slot) => {
|
|
1319
|
+
const slotDate = (0, import_dayjs.default)(slot.startTime).format("YYYY-MM-DD");
|
|
1320
|
+
const slotPriceMap = slotPriceMaps.get(slotDate);
|
|
1321
|
+
return {
|
|
1322
|
+
...slot,
|
|
1232
1323
|
productId: mapping.productId,
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1324
|
+
price: slotPriceMap ? (0, import_smartPricing.getSlotPriceFromMap)({
|
|
1325
|
+
slotPriceMap,
|
|
1326
|
+
productId: mapping.productId,
|
|
1327
|
+
slotStartTime: slot.startTime,
|
|
1328
|
+
fallbackPrice: mapping.price
|
|
1329
|
+
}) : mapping.price
|
|
1330
|
+
};
|
|
1331
|
+
});
|
|
1236
1332
|
const merged = (0, import_slotMerge.mergeConsecutiveSlots)(updatedSlots);
|
|
1237
1333
|
if (merged.length === 1) {
|
|
1238
1334
|
product.selling_price = merged[0].totalPrice;
|
|
1239
1335
|
product.original_price = merged[0].totalPrice;
|
|
1240
1336
|
product.metadata.price_breakdown = (0, import_slotMerge.buildPriceBreakdown)({
|
|
1241
1337
|
group: merged[0],
|
|
1242
|
-
productId: mapping.productId
|
|
1243
|
-
quotation: this.store.quotation
|
|
1338
|
+
productId: mapping.productId
|
|
1244
1339
|
});
|
|
1245
1340
|
}
|
|
1246
1341
|
} else if (product.product_id != null) {
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1342
|
+
const smartPrice = (0, import_smartPricing.getPriceForProductAtDatetime)({
|
|
1343
|
+
products: catalog,
|
|
1344
|
+
context,
|
|
1345
|
+
productId: Number(product.product_id),
|
|
1346
|
+
datetime: now,
|
|
1347
|
+
fallbackPrice: product.selling_price
|
|
1251
1348
|
});
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
product.original_price = quotationPrice;
|
|
1255
|
-
}
|
|
1349
|
+
product.selling_price = smartPrice;
|
|
1350
|
+
product.original_price = smartPrice;
|
|
1256
1351
|
}
|
|
1257
1352
|
}
|
|
1258
1353
|
}
|
|
@@ -1438,7 +1533,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1438
1533
|
}
|
|
1439
1534
|
}
|
|
1440
1535
|
async addProductToOrder(product) {
|
|
1441
|
-
var _a;
|
|
1536
|
+
var _a, _b;
|
|
1442
1537
|
this.logMethodStart("addProductToOrder", {
|
|
1443
1538
|
product_id: product.product_id,
|
|
1444
1539
|
product_variant_id: product.product_variant_id
|
|
@@ -1446,18 +1541,18 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
|
|
|
1446
1541
|
try {
|
|
1447
1542
|
if (!this.store.order)
|
|
1448
1543
|
throw new Error("order 模块未初始化");
|
|
1449
|
-
if (!((_a = product.metadata) == null ? void 0 : _a.venue_booking) &&
|
|
1450
|
-
const
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1544
|
+
if (!((_a = product.metadata) == null ? void 0 : _a.venue_booking) && product.product_id != null) {
|
|
1545
|
+
const smartPrice = (0, import_smartPricing.getPriceForProductAtDatetime)({
|
|
1546
|
+
products: this.getAllProductsForSmartPricing(),
|
|
1547
|
+
context: this.buildSmartPricingContext(),
|
|
1548
|
+
productId: Number(product.product_id),
|
|
1549
|
+
datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
|
|
1550
|
+
fallbackPrice: product.selling_price
|
|
1454
1551
|
});
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
product.original_price = product.selling_price;
|
|
1460
|
-
}
|
|
1552
|
+
product.selling_price = smartPrice;
|
|
1553
|
+
product.original_price = smartPrice;
|
|
1554
|
+
} else if (product.selling_price != null && !((_b = product.metadata) == null ? void 0 : _b.venue_booking)) {
|
|
1555
|
+
product.original_price = product.selling_price;
|
|
1461
1556
|
}
|
|
1462
1557
|
const products = await this.store.order.addProductToOrder(product);
|
|
1463
1558
|
await this.refreshItemRuleQuantityLimits();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { VenueBookingSlotConfig, VenueResourceRawData, VenueDateSummaryItem, ResourceProductMapping } from '../types';
|
|
2
|
-
import type { QuotationModule } from '../../../modules/Quotation';
|
|
3
2
|
export declare function buildDateRangeSummary(params: {
|
|
4
3
|
startDate: string;
|
|
5
4
|
endDate: string;
|
|
6
5
|
config: VenueBookingSlotConfig;
|
|
7
6
|
rawResources: VenueResourceRawData[];
|
|
8
7
|
resourceProductMap: Map<number | string, ResourceProductMapping[]>;
|
|
9
|
-
quotationModule?: QuotationModule;
|
|
10
8
|
resolveConfig?: (date: string) => VenueBookingSlotConfig;
|
|
9
|
+
/** 按日期构建 slot 智能定价 Map */
|
|
10
|
+
buildSlotPriceMap?: (date: string, config: VenueBookingSlotConfig, productIds: number[]) => Map<string, string | null>;
|
|
11
11
|
}): VenueDateSummaryItem[];
|
|
@@ -41,28 +41,23 @@ function buildDateRangeSummary(params) {
|
|
|
41
41
|
config,
|
|
42
42
|
rawResources,
|
|
43
43
|
resourceProductMap,
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
resolveConfig,
|
|
45
|
+
buildSlotPriceMap
|
|
46
46
|
} = params;
|
|
47
47
|
const result = [];
|
|
48
|
-
const productIds =
|
|
48
|
+
const productIds = buildSlotPriceMap ? [...new Set([...resourceProductMap.values()].flat().map((m) => m.productId))] : [];
|
|
49
49
|
let cursor = (0, import_dayjs.default)(startDate);
|
|
50
50
|
const end = (0, import_dayjs.default)(endDate);
|
|
51
51
|
while (!cursor.isAfter(end)) {
|
|
52
52
|
const date = cursor.format("YYYY-MM-DD");
|
|
53
53
|
const effectiveConfig = (resolveConfig == null ? void 0 : resolveConfig(date)) || config;
|
|
54
|
-
|
|
55
|
-
if (quotationModule && productIds.length) {
|
|
56
|
-
const timeLabels = (0, import_timeSlot.generateTimeLabels)(effectiveConfig);
|
|
57
|
-
const timePoints = timeLabels.map((label) => `${date} ${label}`);
|
|
58
|
-
quotationPriceMap = quotationModule.buildProductPriceMap({ productIds, timePoints });
|
|
59
|
-
}
|
|
54
|
+
const slotPriceMap = buildSlotPriceMap && productIds.length ? buildSlotPriceMap(date, effectiveConfig, productIds) : void 0;
|
|
60
55
|
const grid = (0, import_timeSlot.buildTimeSlotGrid)({
|
|
61
56
|
date,
|
|
62
57
|
config: effectiveConfig,
|
|
63
58
|
rawResources,
|
|
64
59
|
resourceProductMap,
|
|
65
|
-
|
|
60
|
+
slotPriceMap
|
|
66
61
|
});
|
|
67
62
|
let totalSlots = 0;
|
|
68
63
|
let availableSlots = 0;
|