@pisell/pisellos 0.10.50 → 0.10.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/model/strategy/adapter/promotion/index.js +0 -9
- package/dist/modules/FulfillmentTiming/index.d.ts +11 -0
- package/dist/modules/FulfillmentTiming/index.js +407 -0
- package/dist/modules/FulfillmentTiming/types.d.ts +67 -0
- package/dist/modules/FulfillmentTiming/types.js +1 -0
- package/dist/modules/OpenData/types.d.ts +6 -0
- package/dist/modules/Order/index.d.ts +18 -1
- package/dist/modules/Order/index.js +322 -195
- package/dist/modules/Order/pickupTiming.d.ts +46 -0
- package/dist/modules/Order/pickupTiming.js +53 -0
- package/dist/modules/Order/types.d.ts +11 -1
- package/dist/modules/Order/utils.d.ts +10 -0
- package/dist/modules/Order/utils.js +145 -85
- package/dist/modules/Rules/index.js +3 -2
- package/dist/modules/Schedule/index.d.ts +8 -0
- package/dist/modules/Schedule/index.js +134 -37
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +1 -0
- package/dist/server/modules/order/index.d.ts +8 -0
- package/dist/server/modules/order/index.js +506 -453
- package/dist/server/modules/order/types.d.ts +1 -0
- package/dist/server/utils/small-ticket.js +165 -94
- package/dist/solution/BaseSales/index.d.ts +24 -0
- package/dist/solution/BaseSales/index.js +1231 -1037
- package/dist/solution/BaseSales/pickupTiming.d.ts +43 -0
- package/dist/solution/BaseSales/pickupTiming.js +589 -0
- package/dist/solution/BaseSales/utils/parseSalesResponse.js +3 -0
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +2 -2
- package/dist/solution/BookingTicket/utils/cartView.js +3 -1
- package/dist/solution/UnifiedBookingSales/index.d.ts +13 -4
- package/dist/solution/UnifiedBookingSales/index.js +873 -708
- package/lib/modules/FulfillmentTiming/index.d.ts +11 -0
- package/lib/modules/FulfillmentTiming/index.js +359 -0
- package/lib/modules/FulfillmentTiming/types.d.ts +67 -0
- package/lib/modules/FulfillmentTiming/types.js +5 -0
- package/lib/modules/OpenData/types.d.ts +6 -0
- package/lib/modules/Order/index.d.ts +18 -1
- package/lib/modules/Order/index.js +101 -3
- package/lib/modules/Order/pickupTiming.d.ts +46 -0
- package/lib/modules/Order/pickupTiming.js +61 -0
- package/lib/modules/Order/types.d.ts +11 -1
- package/lib/modules/Order/utils.d.ts +10 -0
- package/lib/modules/Order/utils.js +58 -4
- package/lib/modules/Rules/index.js +3 -2
- package/lib/modules/Schedule/index.d.ts +8 -0
- package/lib/modules/Schedule/index.js +64 -11
- package/lib/modules/index.d.ts +1 -0
- package/lib/modules/index.js +11 -0
- package/lib/server/modules/order/index.d.ts +8 -0
- package/lib/server/modules/order/index.js +19 -0
- package/lib/server/modules/order/types.d.ts +1 -0
- package/lib/server/utils/small-ticket.js +86 -22
- package/lib/solution/BaseSales/index.d.ts +24 -0
- package/lib/solution/BaseSales/index.js +109 -1
- package/lib/solution/BaseSales/pickupTiming.d.ts +43 -0
- package/lib/solution/BaseSales/pickupTiming.js +269 -0
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +3 -0
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +2 -2
- package/lib/solution/BookingTicket/utils/cartView.js +3 -1
- package/lib/solution/UnifiedBookingSales/index.d.ts +13 -4
- package/lib/solution/UnifiedBookingSales/index.js +130 -46
- package/package.json +1 -1
|
@@ -4,10 +4,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.OrderModule = void 0;
|
|
7
|
+
Object.defineProperty(exports, "isFulfillmentTimingBooking", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _pickupTiming.isFulfillmentTimingBooking;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
7
13
|
var _BaseModule = require("../BaseModule");
|
|
8
14
|
var _types = require("./types");
|
|
9
15
|
var _utils = require("./utils");
|
|
10
16
|
var _utils2 = require("../Product/utils");
|
|
17
|
+
var _pickupTiming = require("./pickupTiming");
|
|
11
18
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
12
19
|
var _availability = require("../Discount/availability");
|
|
13
20
|
var _osPrivatePayload = require("../../utils/os-private-payload");
|
|
@@ -130,6 +137,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
130
137
|
sessionStorageRestoreRecord = null;
|
|
131
138
|
/** 只允许当前订单最新的 prepare/config 请求回写客户资产态。 */
|
|
132
139
|
customerWalletPrepareConfigEpoch = 0;
|
|
140
|
+
/** Payment 可能早于 prepare/config 返回;先按实例 ID 暂存卡号等待 Snapshot。 */
|
|
141
|
+
pointCardSnapshotCodeCandidates = new Map();
|
|
133
142
|
salesSummaryModuleName;
|
|
134
143
|
rulesHooksOverride;
|
|
135
144
|
moduleHooksOverride;
|
|
@@ -1159,17 +1168,55 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1159
1168
|
}
|
|
1160
1169
|
clearCustomerWalletRuntimeState() {
|
|
1161
1170
|
this.customerWalletPrepareConfigEpoch += 1;
|
|
1171
|
+
this.pointCardSnapshotCodeCandidates.clear();
|
|
1162
1172
|
this.store.availableWalletIds = [];
|
|
1163
1173
|
this.store.virtualCurrencyList = [];
|
|
1164
1174
|
}
|
|
1175
|
+
rememberPointCardSnapshotCodeCandidates(value) {
|
|
1176
|
+
(0, _utils.collectPointCardSnapshotCodeCandidates)(value).forEach(({
|
|
1177
|
+
id,
|
|
1178
|
+
code
|
|
1179
|
+
}) => {
|
|
1180
|
+
if (!this.pointCardSnapshotCodeCandidates.has(id)) {
|
|
1181
|
+
this.pointCardSnapshotCodeCandidates.set(id, code);
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
getRememberedPointCardSnapshotCodeCandidates() {
|
|
1186
|
+
return [...this.pointCardSnapshotCodeCandidates].map(([id, code]) => ({
|
|
1187
|
+
id,
|
|
1188
|
+
code
|
|
1189
|
+
}));
|
|
1190
|
+
}
|
|
1191
|
+
getPointCardSnapshotOrderIdentityKey(identity) {
|
|
1192
|
+
if (identity?.externalSaleNumber) {
|
|
1193
|
+
return `external:${identity.externalSaleNumber}`;
|
|
1194
|
+
}
|
|
1195
|
+
if (identity?.orderId !== undefined && identity.orderId !== null) {
|
|
1196
|
+
return `order:${identity.orderId}`;
|
|
1197
|
+
}
|
|
1198
|
+
if (identity?.localId) return `local:${identity.localId}`;
|
|
1199
|
+
if (identity?.orderNumber) return `number:${identity.orderNumber}`;
|
|
1200
|
+
return '';
|
|
1201
|
+
}
|
|
1202
|
+
isPointCardSnapshotMergeContextCurrent(context) {
|
|
1203
|
+
if (!context) return true;
|
|
1204
|
+
if (context.customerId !== undefined && String(context.customerId ?? '') !== String(this.store.tempOrder?.customer_id ?? '')) {
|
|
1205
|
+
return false;
|
|
1206
|
+
}
|
|
1207
|
+
const expectedOrderKey = this.getPointCardSnapshotOrderIdentityKey(context.orderIdentity);
|
|
1208
|
+
return !expectedOrderKey || expectedOrderKey === this.getPointCardSnapshotOrderIdentityKey(this.getOrderIdentity());
|
|
1209
|
+
}
|
|
1165
1210
|
writeCustomerWalletSnapshotsFromPrepareConfig(params) {
|
|
1166
1211
|
const tempOrder = this.store.tempOrder;
|
|
1167
1212
|
if (!tempOrder) return;
|
|
1168
1213
|
if (String(tempOrder.customer_id ?? '') !== String(params.customerId)) return;
|
|
1214
|
+
const currentOrderMetaList = (0, _utils.normalizeOrderMetaList)(tempOrder.order_meta_list);
|
|
1169
1215
|
const virtualCurrencyList = Array.isArray(params.virtualCurrencyList) ? params.virtualCurrencyList : [];
|
|
1216
|
+
const snapshotsWithExistingCodes = (0, _utils.mergePointCardSnapshotCodes)(params.availableWalletPassList, currentOrderMetaList?.point_cards_snapshot);
|
|
1170
1217
|
tempOrder.order_meta_list = {
|
|
1171
|
-
...(
|
|
1172
|
-
point_cards_snapshot: (0, _utils.
|
|
1218
|
+
...(currentOrderMetaList || {}),
|
|
1219
|
+
point_cards_snapshot: (0, _utils.mergePointCardSnapshotCodes)(snapshotsWithExistingCodes, this.getRememberedPointCardSnapshotCodeCandidates()),
|
|
1173
1220
|
virtual_currency_snapshot: (0, _utils.buildVirtualCurrencySnapshotFromList)(virtualCurrencyList)
|
|
1174
1221
|
};
|
|
1175
1222
|
this.store.availableWalletIds = [...params.availableWalletIds];
|
|
@@ -1177,6 +1224,31 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1177
1224
|
this.persistTempOrder();
|
|
1178
1225
|
this.saveDraftInBackground();
|
|
1179
1226
|
}
|
|
1227
|
+
|
|
1228
|
+
/**
|
|
1229
|
+
* 将 Payment WalletPass 返回的实例 code 回填到当前订单 Snapshot。
|
|
1230
|
+
* 这里只按资产 ID 补空值,不新增卡、不覆盖 prepare/config 冻结的余额。
|
|
1231
|
+
*/
|
|
1232
|
+
mergePointCardSnapshotCodes(walletPassList, context) {
|
|
1233
|
+
const tempOrder = this.store.tempOrder;
|
|
1234
|
+
const currentOrderMetaList = (0, _utils.normalizeOrderMetaList)(tempOrder?.order_meta_list);
|
|
1235
|
+
const currentSnapshots = currentOrderMetaList?.point_cards_snapshot || [];
|
|
1236
|
+
if (!tempOrder || !this.isPointCardSnapshotMergeContextCurrent(context)) {
|
|
1237
|
+
return currentSnapshots;
|
|
1238
|
+
}
|
|
1239
|
+
this.rememberPointCardSnapshotCodeCandidates(walletPassList);
|
|
1240
|
+
if (!currentSnapshots.length) return currentSnapshots;
|
|
1241
|
+
const nextSnapshots = (0, _utils.mergePointCardSnapshotCodes)(currentSnapshots, this.getRememberedPointCardSnapshotCodeCandidates());
|
|
1242
|
+
const hasChanged = nextSnapshots.some((snapshot, index) => snapshot.code !== currentSnapshots[index]?.code);
|
|
1243
|
+
if (!hasChanged) return currentSnapshots;
|
|
1244
|
+
tempOrder.order_meta_list = {
|
|
1245
|
+
...(currentOrderMetaList || {}),
|
|
1246
|
+
point_cards_snapshot: nextSnapshots
|
|
1247
|
+
};
|
|
1248
|
+
this.persistTempOrder();
|
|
1249
|
+
this.saveDraftInBackground();
|
|
1250
|
+
return nextSnapshots;
|
|
1251
|
+
}
|
|
1180
1252
|
createExternalSaleNumber() {
|
|
1181
1253
|
const timestamp = (0, _dayjs.default)().format('YYYYMMDDHHmmssSSS');
|
|
1182
1254
|
const random6 = String(Math.floor(Math.random() * 1000000)).padStart(6, '0');
|
|
@@ -2208,6 +2280,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2208
2280
|
const bookingByBookingUid = new Map();
|
|
2209
2281
|
bookings.forEach(booking => {
|
|
2210
2282
|
if (!booking || typeof booking !== 'object') return;
|
|
2283
|
+
if ((0, _pickupTiming.isFulfillmentTimingBooking)(booking)) return;
|
|
2211
2284
|
const productUid = booking.product_uid || booking.metadata?.product_uid;
|
|
2212
2285
|
if (productUid !== undefined && productUid !== null && String(productUid) !== '') {
|
|
2213
2286
|
bookingByProductUid.set(String(productUid), booking);
|
|
@@ -2258,6 +2331,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2258
2331
|
let baseHolder = null;
|
|
2259
2332
|
const seen = new Set();
|
|
2260
2333
|
for (const booking of tempOrder.bookings || []) {
|
|
2334
|
+
if ((0, _pickupTiming.isFulfillmentTimingBooking)(booking)) continue;
|
|
2261
2335
|
const holder = booking?.holder && typeof booking.holder === 'object' ? booking.holder : null;
|
|
2262
2336
|
if (!baseHolder && holder) {
|
|
2263
2337
|
baseHolder = holder;
|
|
@@ -2298,7 +2372,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2298
2372
|
* this.syncTempOrderHolderFromBookings(tempOrder);
|
|
2299
2373
|
*/
|
|
2300
2374
|
syncTempOrderHolderFromBookings(tempOrder) {
|
|
2301
|
-
const bookings = tempOrder.bookings || [];
|
|
2375
|
+
const bookings = (tempOrder.bookings || []).filter(booking => !(0, _pickupTiming.isFulfillmentTimingBooking)(booking));
|
|
2302
2376
|
const hasHolderSource = bookings.some(booking => {
|
|
2303
2377
|
return booking?.holder !== undefined || booking?.metadata?.holder_id !== undefined;
|
|
2304
2378
|
});
|
|
@@ -2323,6 +2397,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2323
2397
|
const bookingUid = product?.booking_uid || product?.metadata?.booking_uid;
|
|
2324
2398
|
if (!productUid && !bookingUid) return;
|
|
2325
2399
|
tempOrder.bookings = (tempOrder.bookings || []).filter(booking => {
|
|
2400
|
+
if ((0, _pickupTiming.isFulfillmentTimingBooking)(booking)) return true;
|
|
2326
2401
|
const currentBookingUid = this.getBookingUniqueIdentificationNumber(booking);
|
|
2327
2402
|
if (bookingUid && currentBookingUid === String(bookingUid)) return false;
|
|
2328
2403
|
if (productUid && String(booking?.product_uid || '') === String(productUid)) return false;
|
|
@@ -2736,10 +2811,33 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
2736
2811
|
});
|
|
2737
2812
|
}
|
|
2738
2813
|
updateTempOrderServiceType(serviceType) {
|
|
2814
|
+
if (serviceType !== 'pick_up') {
|
|
2815
|
+
const tempOrder = this.ensureTempOrder();
|
|
2816
|
+
tempOrder.bookings = (tempOrder.bookings || []).filter(booking => !(0, _pickupTiming.isFulfillmentTimingBooking)(booking));
|
|
2817
|
+
}
|
|
2739
2818
|
return this.updateTempOrderShopServiceData({
|
|
2740
2819
|
service_type: serviceType
|
|
2741
2820
|
});
|
|
2742
2821
|
}
|
|
2822
|
+
getPickupTimingBooking() {
|
|
2823
|
+
return (this.store.tempOrder?.bookings || []).find(_pickupTiming.isFulfillmentTimingBooking) || null;
|
|
2824
|
+
}
|
|
2825
|
+
setPickupTimingBooking(input) {
|
|
2826
|
+
const tempOrder = this.ensureTempOrder();
|
|
2827
|
+
const bookings = tempOrder.bookings || [];
|
|
2828
|
+
const firstIndex = bookings.findIndex(_pickupTiming.isFulfillmentTimingBooking);
|
|
2829
|
+
const nextBooking = (0, _pickupTiming.buildPickupTimingBooking)(input, bookings[firstIndex]);
|
|
2830
|
+
// Keep the first row's identity and position; repair duplicate marked rows only.
|
|
2831
|
+
tempOrder.bookings = firstIndex === -1 ? [...bookings, nextBooking] : bookings.flatMap((booking, index) => index === firstIndex ? [nextBooking] : (0, _pickupTiming.isFulfillmentTimingBooking)(booking) ? [] : [booking]);
|
|
2832
|
+
this.notifyTempOrderChanged();
|
|
2833
|
+
return nextBooking;
|
|
2834
|
+
}
|
|
2835
|
+
clearPickupTimingBooking() {
|
|
2836
|
+
const tempOrder = this.store.tempOrder;
|
|
2837
|
+
if (!tempOrder?.bookings?.some(_pickupTiming.isFulfillmentTimingBooking)) return;
|
|
2838
|
+
tempOrder.bookings = tempOrder.bookings.filter(booking => !(0, _pickupTiming.isFulfillmentTimingBooking)(booking));
|
|
2839
|
+
this.notifyTempOrderChanged();
|
|
2840
|
+
}
|
|
2743
2841
|
updateTempOrderContactsInfo(contactsInfo) {
|
|
2744
2842
|
const tempOrder = this.ensureTempOrder();
|
|
2745
2843
|
tempOrder.contacts_info = contactsInfo && typeof contactsInfo === 'object' && !Array.isArray(contactsInfo) ? contactsInfo : null;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type PickupTimingSelectionMode = 'asap' | 'scheduled';
|
|
2
|
+
export type PickupTimingSource = 'asap' | 'schedule' | 'pos_manual';
|
|
3
|
+
export interface PickupTimingBookingInput {
|
|
4
|
+
mode: PickupTimingSelectionMode;
|
|
5
|
+
source: PickupTimingSource;
|
|
6
|
+
/** Store-local calendar date and minute; the caller validates availability. */
|
|
7
|
+
date: string;
|
|
8
|
+
time: string;
|
|
9
|
+
/** Absolute timestamp disambiguates a repeated local minute at a DST change. */
|
|
10
|
+
instant?: string;
|
|
11
|
+
timezone?: string;
|
|
12
|
+
frozen?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface PickupTimingBookingMetadata {
|
|
15
|
+
unique_identification_number: string;
|
|
16
|
+
is_fulfillment_timing: true;
|
|
17
|
+
fulfillment_timing: {
|
|
18
|
+
method: 'pick_up';
|
|
19
|
+
mode: PickupTimingSelectionMode;
|
|
20
|
+
source: PickupTimingSource;
|
|
21
|
+
instant?: string;
|
|
22
|
+
timezone?: string;
|
|
23
|
+
frozen?: boolean;
|
|
24
|
+
};
|
|
25
|
+
[key: string]: any;
|
|
26
|
+
}
|
|
27
|
+
export interface PickupTimingBooking {
|
|
28
|
+
schedule_id: number | string;
|
|
29
|
+
start_date: string;
|
|
30
|
+
end_date: string;
|
|
31
|
+
start_time: string;
|
|
32
|
+
end_time: string;
|
|
33
|
+
select_date: string;
|
|
34
|
+
duration: 0;
|
|
35
|
+
is_all: 0;
|
|
36
|
+
sub_type: 'minutes';
|
|
37
|
+
like_status: string;
|
|
38
|
+
resources: [];
|
|
39
|
+
metadata: PickupTimingBookingMetadata;
|
|
40
|
+
schedule_event_id?: number | string;
|
|
41
|
+
[key: string]: any;
|
|
42
|
+
}
|
|
43
|
+
/** The explicit marker is the only authority; unlinked ordinary bookings remain ordinary. */
|
|
44
|
+
export declare function isFulfillmentTimingBooking(booking: unknown): boolean;
|
|
45
|
+
/** Update an independent pickup appointment without changing its persisted row identity. */
|
|
46
|
+
export declare function buildPickupTimingBooking(input: PickupTimingBookingInput, existing?: Record<string, any> | null): PickupTimingBooking;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildPickupTimingBooking = buildPickupTimingBooking;
|
|
7
|
+
exports.isFulfillmentTimingBooking = isFulfillmentTimingBooking;
|
|
8
|
+
var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
|
|
9
|
+
/** The explicit marker is the only authority; unlinked ordinary bookings remain ordinary. */
|
|
10
|
+
function isFulfillmentTimingBooking(booking) {
|
|
11
|
+
return booking?.metadata?.is_fulfillment_timing === true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Update an independent pickup appointment without changing its persisted row identity. */
|
|
15
|
+
function buildPickupTimingBooking(input, existing) {
|
|
16
|
+
const booking = {
|
|
17
|
+
...(existing || {})
|
|
18
|
+
};
|
|
19
|
+
const metadata = {
|
|
20
|
+
...(booking.metadata || {})
|
|
21
|
+
};
|
|
22
|
+
// A fulfillment appointment never becomes a product/resource/holder purchase line.
|
|
23
|
+
for (const key of ['product_uid', 'product', 'holder', 'holder_id', 'collect_pax', 'capacity']) {
|
|
24
|
+
delete booking[key];
|
|
25
|
+
delete metadata[key];
|
|
26
|
+
}
|
|
27
|
+
delete metadata.booking_uid;
|
|
28
|
+
return {
|
|
29
|
+
...booking,
|
|
30
|
+
schedule_id: booking.schedule_id || 0,
|
|
31
|
+
start_date: input.date,
|
|
32
|
+
end_date: input.date,
|
|
33
|
+
start_time: input.time,
|
|
34
|
+
end_time: input.time,
|
|
35
|
+
select_date: input.date,
|
|
36
|
+
duration: 0,
|
|
37
|
+
is_all: 0,
|
|
38
|
+
sub_type: 'minutes',
|
|
39
|
+
like_status: booking.like_status || 'common',
|
|
40
|
+
resources: [],
|
|
41
|
+
metadata: {
|
|
42
|
+
...metadata,
|
|
43
|
+
unique_identification_number: String(metadata.unique_identification_number || (0, _orderCollectionIdentity.createUuidV4)()),
|
|
44
|
+
is_fulfillment_timing: true,
|
|
45
|
+
fulfillment_timing: {
|
|
46
|
+
method: 'pick_up',
|
|
47
|
+
mode: input.mode,
|
|
48
|
+
source: input.source,
|
|
49
|
+
...(input.instant !== undefined ? {
|
|
50
|
+
instant: input.instant
|
|
51
|
+
} : {}),
|
|
52
|
+
...(input.timezone !== undefined ? {
|
|
53
|
+
timezone: input.timezone
|
|
54
|
+
} : {}),
|
|
55
|
+
...(input.frozen !== undefined ? {
|
|
56
|
+
frozen: input.frozen
|
|
57
|
+
} : {})
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -7,9 +7,10 @@ import type { SubmitPayloadEnhancer } from './utils';
|
|
|
7
7
|
import type { PaymentItem } from '../Payment/types';
|
|
8
8
|
import type { ICustomer } from '../AccountList/types';
|
|
9
9
|
import type { OrderProductDiscountItem } from '../../server/modules/order/types';
|
|
10
|
+
import type { PickupTimingBooking, PickupTimingBookingInput } from './pickupTiming';
|
|
10
11
|
export type { OrderProductDiscountItem } from '../../server/modules/order/types';
|
|
11
12
|
export type PickupReferenceMode = 'counter_pickup' | 'table_service';
|
|
12
|
-
export type ShopServiceType = 'dine_in' | 'takeaway';
|
|
13
|
+
export type ShopServiceType = 'dine_in' | 'takeaway' | 'pick_up' | 'delivery';
|
|
13
14
|
export interface ShopServiceData {
|
|
14
15
|
pickup_reference_mode?: PickupReferenceMode;
|
|
15
16
|
service_type?: ShopServiceType | '';
|
|
@@ -199,10 +200,15 @@ export interface PointCardSnapshotItem {
|
|
|
199
200
|
id: number | string;
|
|
200
201
|
tag: 'point_card';
|
|
201
202
|
product_id?: number | string;
|
|
203
|
+
code?: string;
|
|
202
204
|
product_name: string;
|
|
203
205
|
par_value: string;
|
|
204
206
|
used_par_value: string;
|
|
205
207
|
}
|
|
208
|
+
export interface PointCardSnapshotMergeContext {
|
|
209
|
+
customerId?: number | string | null;
|
|
210
|
+
orderIdentity?: OrderIdentitySnapshot | null;
|
|
211
|
+
}
|
|
206
212
|
export interface VirtualCurrencySnapshotItem {
|
|
207
213
|
id: number | string;
|
|
208
214
|
tag: 'virtual_currency';
|
|
@@ -858,6 +864,9 @@ export interface OrderModuleAPI {
|
|
|
858
864
|
updateTempOrderCustomer: (customer: UpdateTempOrderCustomerInput) => OrderSnapshot['customer'];
|
|
859
865
|
updateTempOrderPickupReferenceMode: (mode: PickupReferenceMode) => ShopServiceData;
|
|
860
866
|
updateTempOrderServiceType: (serviceType: ShopServiceType) => ShopServiceData;
|
|
867
|
+
getPickupTimingBooking: () => PickupTimingBooking | null;
|
|
868
|
+
setPickupTimingBooking: (input: PickupTimingBookingInput) => PickupTimingBooking;
|
|
869
|
+
clearPickupTimingBooking: () => void;
|
|
861
870
|
updateTempOrderBuzzer: (buzzer: string) => string;
|
|
862
871
|
updateTempOrderContactsInfo: (contactsInfo: Record<string, any> | null) => Record<string, any> | null;
|
|
863
872
|
addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions) => Promise<OrderProduct[]>;
|
|
@@ -975,6 +984,7 @@ export interface OrderModuleAPI {
|
|
|
975
984
|
getDiscountList: () => Discount[];
|
|
976
985
|
getAvailableWalletIds: () => number[];
|
|
977
986
|
getCustomerWalletPrepareConfigEpoch: () => number;
|
|
987
|
+
mergePointCardSnapshotCodes: (walletPassList: unknown, context?: PointCardSnapshotMergeContext) => PointCardSnapshotItem[];
|
|
978
988
|
applyDiscount: () => void;
|
|
979
989
|
/**
|
|
980
990
|
* 注入促销评估器。
|
|
@@ -18,6 +18,16 @@ export interface OrderProductsDepositSummary {
|
|
|
18
18
|
import type { WindowPlugin } from '../../plugins';
|
|
19
19
|
export declare function normalizePointCardSnapshotItem(value: unknown): PointCardSnapshotItem | null;
|
|
20
20
|
export declare function buildPointCardSnapshotFromWalletPassList(value: unknown): PointCardSnapshotItem[];
|
|
21
|
+
export declare function collectPointCardSnapshotCodeCandidates(value: unknown): Array<{
|
|
22
|
+
id: string;
|
|
23
|
+
code: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Payment 的 WalletPass 列表包含实例 code,而 prepare/config 通常只提供
|
|
27
|
+
* 卡名称和余额。按实例 ID 仅补齐 Snapshot 缺失的 code,避免后到的运行态
|
|
28
|
+
* 数据覆盖下单时已经冻结的卡名称和余额。
|
|
29
|
+
*/
|
|
30
|
+
export declare function mergePointCardSnapshotCodes(snapshotsValue: unknown, walletPassesValue: unknown): PointCardSnapshotItem[];
|
|
21
31
|
export declare function normalizeVirtualCurrencySnapshotItem(value: unknown): VirtualCurrencySnapshotItem | null;
|
|
22
32
|
export declare function buildVirtualCurrencySnapshotFromList(value: unknown): VirtualCurrencySnapshotItem[];
|
|
23
33
|
export declare function normalizeOrderMetaList(value: unknown): OrderMetaList | undefined;
|
|
@@ -14,6 +14,7 @@ exports.buildSubmitPayload = buildSubmitPayload;
|
|
|
14
14
|
exports.buildVirtualCurrencySnapshotFromList = buildVirtualCurrencySnapshotFromList;
|
|
15
15
|
exports.calculateOrderProductsDeposit = calculateOrderProductsDeposit;
|
|
16
16
|
exports.clearTempOrderHolderAssignments = clearTempOrderHolderAssignments;
|
|
17
|
+
exports.collectPointCardSnapshotCodeCandidates = collectPointCardSnapshotCodeCandidates;
|
|
17
18
|
exports.composeLinePrice = composeLinePrice;
|
|
18
19
|
exports.createDefaultOrderRulesHooks = createDefaultOrderRulesHooks;
|
|
19
20
|
exports.createDefaultTempOrder = createDefaultTempOrder;
|
|
@@ -66,6 +67,7 @@ Object.defineProperty(exports, "mergeManualProductDiscountIntoList", {
|
|
|
66
67
|
}
|
|
67
68
|
});
|
|
68
69
|
exports.mergeOrderProductDisplayFields = mergeOrderProductDisplayFields;
|
|
70
|
+
exports.mergePointCardSnapshotCodes = mergePointCardSnapshotCodes;
|
|
69
71
|
exports.mergeRelationForms = void 0;
|
|
70
72
|
exports.normalizeBookingIsAll = normalizeBookingIsAll;
|
|
71
73
|
exports.normalizeBookingSubType = normalizeBookingSubType;
|
|
@@ -133,6 +135,7 @@ var _utils = require("../Holder/utils");
|
|
|
133
135
|
var _utils2 = require("../../solution/ScanOrder/utils");
|
|
134
136
|
var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
|
|
135
137
|
var _salesNotes = require("./salesNotes");
|
|
138
|
+
var _pickupTiming = require("./pickupTiming");
|
|
136
139
|
var _manualProductDiscount = require("./utils/manualProductDiscount");
|
|
137
140
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
138
141
|
_dayjs.default.extend(_customParseFormat.default);
|
|
@@ -165,6 +168,10 @@ function normalizePointCardSnapshotItem(value) {
|
|
|
165
168
|
if (productId !== undefined) {
|
|
166
169
|
snapshot.product_id = productId;
|
|
167
170
|
}
|
|
171
|
+
const code = normalizeSnapshotScalar(value.code);
|
|
172
|
+
if (code !== undefined) {
|
|
173
|
+
snapshot.code = String(code).trim();
|
|
174
|
+
}
|
|
168
175
|
return snapshot;
|
|
169
176
|
}
|
|
170
177
|
function buildPointCardSnapshotFromWalletPassList(value) {
|
|
@@ -175,6 +182,46 @@ function buildPointCardSnapshotFromWalletPassList(value) {
|
|
|
175
182
|
return result;
|
|
176
183
|
}, []);
|
|
177
184
|
}
|
|
185
|
+
function collectPointCardSnapshotCodeCandidates(value) {
|
|
186
|
+
if (!Array.isArray(value)) return [];
|
|
187
|
+
const codeById = new Map();
|
|
188
|
+
value.forEach(item => {
|
|
189
|
+
if (!isPlainObject(item)) return;
|
|
190
|
+
const id = normalizeSnapshotScalar(item.id ?? item.voucher_id);
|
|
191
|
+
const code = normalizeSnapshotScalar(item.code);
|
|
192
|
+
if (id === undefined || code === undefined) return;
|
|
193
|
+
const identity = String(id).trim();
|
|
194
|
+
const normalizedCode = String(code).trim();
|
|
195
|
+
if (!identity || !normalizedCode || codeById.has(identity)) return;
|
|
196
|
+
codeById.set(identity, normalizedCode);
|
|
197
|
+
});
|
|
198
|
+
return [...codeById].map(([id, code]) => ({
|
|
199
|
+
id,
|
|
200
|
+
code
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Payment 的 WalletPass 列表包含实例 code,而 prepare/config 通常只提供
|
|
206
|
+
* 卡名称和余额。按实例 ID 仅补齐 Snapshot 缺失的 code,避免后到的运行态
|
|
207
|
+
* 数据覆盖下单时已经冻结的卡名称和余额。
|
|
208
|
+
*/
|
|
209
|
+
function mergePointCardSnapshotCodes(snapshotsValue, walletPassesValue) {
|
|
210
|
+
const snapshots = buildPointCardSnapshotFromWalletPassList(snapshotsValue);
|
|
211
|
+
if (!snapshots.length || !Array.isArray(walletPassesValue)) return snapshots;
|
|
212
|
+
const codeById = new Map(collectPointCardSnapshotCodeCandidates(walletPassesValue).map(({
|
|
213
|
+
id,
|
|
214
|
+
code
|
|
215
|
+
}) => [id, code]));
|
|
216
|
+
return snapshots.map(snapshot => {
|
|
217
|
+
if (snapshot.code) return snapshot;
|
|
218
|
+
const code = codeById.get(String(snapshot.id).trim());
|
|
219
|
+
return code ? {
|
|
220
|
+
...snapshot,
|
|
221
|
+
code
|
|
222
|
+
} : snapshot;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
178
225
|
function normalizeSnapshotNameMap(value) {
|
|
179
226
|
if (typeof value === 'string' || typeof value === 'number') {
|
|
180
227
|
const normalizedText = String(value).trim();
|
|
@@ -1251,7 +1298,7 @@ function normalizeSubmitProduct(product, formatOptions = {}) {
|
|
|
1251
1298
|
payment_price: formatOptions.virtualSettlementMode ? virtualPrice : submitProduct.payment_price ?? submitProduct.selling_price
|
|
1252
1299
|
};
|
|
1253
1300
|
}
|
|
1254
|
-
const SUBMIT_BOOKING_METADATA_WHITELIST = ['unique_identification_number', 'collect_pax', 'capacity', 'holder_id', 'resource_select_type', 'holder'];
|
|
1301
|
+
const SUBMIT_BOOKING_METADATA_WHITELIST = ['unique_identification_number', 'collect_pax', 'capacity', 'holder_id', 'resource_select_type', 'holder', 'is_fulfillment_timing', 'fulfillment_timing'];
|
|
1255
1302
|
function normalizeBookingIsAll(booking) {
|
|
1256
1303
|
return booking.is_all === true || booking.is_all === 1 || booking.is_all === '1' || booking.is_all === 'true' ? 1 : 0;
|
|
1257
1304
|
}
|
|
@@ -1270,7 +1317,9 @@ function normalizeSubmitBooking(booking) {
|
|
|
1270
1317
|
cleanMetadata[key] = rawMetadata[key];
|
|
1271
1318
|
}
|
|
1272
1319
|
}
|
|
1273
|
-
if (cleanMetadata.holder_id === undefined
|
|
1320
|
+
if (cleanMetadata.holder_id === undefined && !(0, _pickupTiming.isFulfillmentTimingBooking)(booking)) {
|
|
1321
|
+
cleanMetadata.holder_id = null;
|
|
1322
|
+
}
|
|
1274
1323
|
const bookingRecord = booking;
|
|
1275
1324
|
const startDate = bookingRecord.start_date;
|
|
1276
1325
|
const shouldRestoreSelectDate = bookingRecord.select_date === undefined || bookingRecord.select_date === null || bookingRecord.select_date === '';
|
|
@@ -1282,6 +1331,10 @@ function normalizeSubmitBooking(booking) {
|
|
|
1282
1331
|
} : {}),
|
|
1283
1332
|
is_all: normalizeBookingIsAll(bookingRecord),
|
|
1284
1333
|
sub_type: normalizeBookingSubType(bookingRecord),
|
|
1334
|
+
...((0, _pickupTiming.isFulfillmentTimingBooking)(booking) ? {
|
|
1335
|
+
like_status: bookingRecord.like_status || 'common',
|
|
1336
|
+
schedule_id: bookingRecord.schedule_id || 0
|
|
1337
|
+
} : {}),
|
|
1285
1338
|
metadata: cleanMetadata
|
|
1286
1339
|
};
|
|
1287
1340
|
}
|
|
@@ -1367,6 +1420,7 @@ function hasBoundBookingResource(bookings) {
|
|
|
1367
1420
|
if (!Array.isArray(bookings)) return false;
|
|
1368
1421
|
return bookings.some(booking => {
|
|
1369
1422
|
if (!booking || typeof booking !== 'object') return false;
|
|
1423
|
+
if ((0, _pickupTiming.isFulfillmentTimingBooking)(booking)) return false;
|
|
1370
1424
|
if (Number(booking.parent_id) === 0) return false;
|
|
1371
1425
|
const resources = booking.resources;
|
|
1372
1426
|
if (!Array.isArray(resources)) return false;
|
|
@@ -1402,7 +1456,7 @@ function resolveSubmitOrderType(params) {
|
|
|
1402
1456
|
return 'table-order';
|
|
1403
1457
|
}
|
|
1404
1458
|
if (currentType) return currentType;
|
|
1405
|
-
if (Array.isArray(bookings) && bookings.
|
|
1459
|
+
if (Array.isArray(bookings) && bookings.some(booking => !(0, _pickupTiming.isFulfillmentTimingBooking)(booking))) {
|
|
1406
1460
|
return businessCode === 'dine_in' ? 'table-order' : 'appointment_booking';
|
|
1407
1461
|
}
|
|
1408
1462
|
return 'virtual';
|
|
@@ -1487,7 +1541,7 @@ function buildSubmitPayload(params) {
|
|
|
1487
1541
|
delivery_type: tempOrder.delivery_type || 'nil',
|
|
1488
1542
|
schedule_date: scheduleDate,
|
|
1489
1543
|
// created_at: tempOrder.created_at || formatDateTime(now), 和后端协定这个字段先不提交到接口
|
|
1490
|
-
bookings: (tempOrder.bookings || []).filter(booking => Number(booking.parent_id) !== 0).map(booking => normalizeSubmitBooking(booking)),
|
|
1544
|
+
bookings: (tempOrder.bookings || []).filter(booking => (0, _pickupTiming.isFulfillmentTimingBooking)(booking) || Number(booking.parent_id) !== 0).map(booking => normalizeSubmitBooking(booking)),
|
|
1491
1545
|
payments: tempOrder.payments || [],
|
|
1492
1546
|
relation_forms: tempOrder.relation_forms || [],
|
|
1493
1547
|
// contacts: tempOrder.contacts || [],
|
|
@@ -1187,11 +1187,12 @@ class RulesModule extends _BaseModule.BaseModule {
|
|
|
1187
1187
|
});
|
|
1188
1188
|
const appliedEntitlementPass = options?.scan || options?.preserveEntitlementSelection === false ? undefined : applicableDiscounts.find(discount => (0, _entitlementPass.isEntitlementPass)(discount) && discount.isSelected === true && appliedWalletDiscountIds.has(String(discount.id)));
|
|
1189
1189
|
|
|
1190
|
-
//
|
|
1190
|
+
// 次卡内部按本次手选/扫码、当前行已应用、默认排序选择。
|
|
1191
1191
|
const scannedSelectedDiscountCard = applicableDiscounts.find(n => n.isScan && n.isSelected && !(0, _entitlementPass.isFullCoveragePass)(n));
|
|
1192
1192
|
const selectedDiscountCard = explicitlySelectedDiscountCard || appliedDiscountCard || scannedSelectedDiscountCard;
|
|
1193
1193
|
const selectedEntitlementPass = (explicitlySelectedDiscount && (0, _entitlementPass.isEntitlementPass)(explicitlySelectedDiscount) ? explicitlySelectedDiscount : undefined) || applicableDiscounts.find(discount => (0, _entitlementPass.isEntitlementPass)(discount) && preferredEntitlementPassIds.has(String(discount.id))) || appliedEntitlementPass || applicableDiscounts.find(discount => (0, _entitlementPass.isEntitlementPass)(discount));
|
|
1194
|
-
|
|
1194
|
+
// 手选优先;普通重算保留当前折扣卡,扫码和最优选择仍使用原有优先级。
|
|
1195
|
+
const selectedDiscount = explicitlySelectedDiscount || (options?.preserveEntitlementSelection !== false && preferredEntitlementPassIds.size === 0 ? appliedDiscountCard : undefined) || selectedEntitlementPass || selectedDiscountCard || applicableDiscounts[0];
|
|
1195
1196
|
// 实际次数分配必须使用同一顺序,避免选中状态切换后仍将次数分配给默认卡。
|
|
1196
1197
|
const prioritizedApplicableDiscounts = selectedDiscount && (0, _entitlementPass.isFullCoveragePass)(selectedDiscount) ? [selectedDiscount, ...applicableDiscounts.filter(discount => {
|
|
1197
1198
|
return (0, _entitlementPass.isFullCoveragePass)(discount) && String(discount.id) !== String(selectedDiscount.id);
|
|
@@ -10,6 +10,10 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
|
|
|
10
10
|
private openCache;
|
|
11
11
|
private fatherModule;
|
|
12
12
|
private hasLoadedScheduleList;
|
|
13
|
+
private scheduleListPromise;
|
|
14
|
+
private scheduleListRequestVersion;
|
|
15
|
+
private scheduleCatalogScope;
|
|
16
|
+
private otherParams;
|
|
13
17
|
constructor(name?: string, version?: string);
|
|
14
18
|
initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
|
|
15
19
|
/**
|
|
@@ -19,6 +23,9 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
|
|
|
19
23
|
* scheduleModule.updateOtherParams({ openCache: true, cacheId: 'cache-2' });
|
|
20
24
|
*/
|
|
21
25
|
updateOtherParams(params: Record<string, any>): void;
|
|
26
|
+
private syncScheduleCatalogScope;
|
|
27
|
+
private resetScheduleCatalog;
|
|
28
|
+
destroy(): void;
|
|
22
29
|
/**
|
|
23
30
|
* 加载当前店铺下所有 schedule
|
|
24
31
|
*
|
|
@@ -27,6 +34,7 @@ export declare class ScheduleModule extends BaseModule implements Module, Schedu
|
|
|
27
34
|
loadAllSchedule(options?: {
|
|
28
35
|
useCache?: boolean;
|
|
29
36
|
}): Promise<void>;
|
|
37
|
+
private loadScheduleCatalog;
|
|
30
38
|
setScheduleList(list: ScheduleItem[]): void;
|
|
31
39
|
private syncScheduleMap;
|
|
32
40
|
getScheduleList(): ScheduleItem[];
|
|
@@ -24,10 +24,15 @@ class ScheduleModule extends _BaseModule.BaseModule {
|
|
|
24
24
|
openCache = false;
|
|
25
25
|
fatherModule;
|
|
26
26
|
hasLoadedScheduleList = false;
|
|
27
|
+
scheduleListPromise = null;
|
|
28
|
+
scheduleListRequestVersion = 0;
|
|
29
|
+
scheduleCatalogScope = '';
|
|
30
|
+
otherParams = {};
|
|
27
31
|
constructor(name, version) {
|
|
28
32
|
super(name, version);
|
|
29
33
|
}
|
|
30
34
|
async initialize(core, options) {
|
|
35
|
+
this.resetScheduleCatalog();
|
|
31
36
|
this.core = core;
|
|
32
37
|
|
|
33
38
|
// 获取依赖的插件
|
|
@@ -40,8 +45,9 @@ class ScheduleModule extends _BaseModule.BaseModule {
|
|
|
40
45
|
// this.state = { ...this.state, ...options.initialState }
|
|
41
46
|
// }
|
|
42
47
|
this.store = options?.store;
|
|
48
|
+
this.updateOtherParams(options.otherParams || {});
|
|
43
49
|
if (options.initialState) {
|
|
44
|
-
this.store.scheduleList = options.initialState.scheduleList;
|
|
50
|
+
this.store.scheduleList = options.initialState.scheduleList || [];
|
|
45
51
|
this.syncScheduleMap();
|
|
46
52
|
this.store.availabilityDateList = options.initialState.availabilityDateList;
|
|
47
53
|
this.hasLoadedScheduleList = Array.isArray(options.initialState.scheduleList);
|
|
@@ -51,13 +57,6 @@ class ScheduleModule extends _BaseModule.BaseModule {
|
|
|
51
57
|
this.store.availabilityDateList = [];
|
|
52
58
|
this.hasLoadedScheduleList = false;
|
|
53
59
|
}
|
|
54
|
-
if (options.otherParams?.cacheId) {
|
|
55
|
-
this.openCache = options.otherParams.openCache;
|
|
56
|
-
this.cacheId = options.otherParams.cacheId;
|
|
57
|
-
}
|
|
58
|
-
if (options.otherParams?.fatherModule) {
|
|
59
|
-
this.fatherModule = options.otherParams.fatherModule;
|
|
60
|
-
}
|
|
61
60
|
}
|
|
62
61
|
|
|
63
62
|
/**
|
|
@@ -68,9 +67,34 @@ class ScheduleModule extends _BaseModule.BaseModule {
|
|
|
68
67
|
*/
|
|
69
68
|
updateOtherParams(params) {
|
|
70
69
|
const otherParams = params || {};
|
|
70
|
+
this.otherParams = {
|
|
71
|
+
...otherParams
|
|
72
|
+
};
|
|
71
73
|
this.openCache = otherParams.openCache ?? false;
|
|
72
74
|
this.cacheId = otherParams.cacheId;
|
|
73
75
|
this.fatherModule = otherParams.fatherModule;
|
|
76
|
+
this.syncScheduleCatalogScope();
|
|
77
|
+
}
|
|
78
|
+
syncScheduleCatalogScope() {
|
|
79
|
+
const context = this.core?.context;
|
|
80
|
+
const shopId = typeof context?.getData === 'function' ? context.getData('shop_id') : context?.shop_id;
|
|
81
|
+
const params = this.otherParams;
|
|
82
|
+
const scope = JSON.stringify([this.cacheId, this.fatherModule, params.businessCode ?? params.business_code, params.channel, params.platform, params.businessTimezone, shopId].map(value => String(value ?? '').trim()));
|
|
83
|
+
if (scope !== this.scheduleCatalogScope) {
|
|
84
|
+
this.resetScheduleCatalog();
|
|
85
|
+
this.scheduleCatalogScope = scope;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
resetScheduleCatalog() {
|
|
89
|
+
this.scheduleListRequestVersion += 1;
|
|
90
|
+
this.scheduleListPromise = null;
|
|
91
|
+
this.hasLoadedScheduleList = false;
|
|
92
|
+
this.store.scheduleList = [];
|
|
93
|
+
this.store.map = new Map();
|
|
94
|
+
}
|
|
95
|
+
destroy() {
|
|
96
|
+
this.resetScheduleCatalog();
|
|
97
|
+
super.destroy();
|
|
74
98
|
}
|
|
75
99
|
|
|
76
100
|
/**
|
|
@@ -79,14 +103,40 @@ class ScheduleModule extends _BaseModule.BaseModule {
|
|
|
79
103
|
* @memberof ScheduleModule
|
|
80
104
|
*/
|
|
81
105
|
async loadAllSchedule(options = {}) {
|
|
82
|
-
|
|
106
|
+
this.syncScheduleCatalogScope();
|
|
107
|
+
const useCache = options.useCache ?? true;
|
|
108
|
+
if (useCache) {
|
|
109
|
+
if (this.scheduleListPromise) return this.scheduleListPromise;
|
|
110
|
+
if (this.hasLoadedScheduleList) return;
|
|
111
|
+
}
|
|
112
|
+
const requestVersion = ++this.scheduleListRequestVersion;
|
|
113
|
+
const promise = this.loadScheduleCatalog(useCache, requestVersion);
|
|
114
|
+
this.scheduleListPromise = promise;
|
|
115
|
+
try {
|
|
116
|
+
await promise;
|
|
117
|
+
} finally {
|
|
118
|
+
if (this.scheduleListPromise === promise) {
|
|
119
|
+
this.scheduleListPromise = null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async loadScheduleCatalog(useCache, requestVersion) {
|
|
124
|
+
const response = await this.request.get(`/schedule`, {
|
|
83
125
|
num: 999
|
|
84
126
|
}, {
|
|
85
|
-
useCache
|
|
127
|
+
useCache
|
|
86
128
|
});
|
|
87
|
-
|
|
129
|
+
if (response.code !== undefined && Number(response.code) !== 200 || response.status === false || typeof response.status === 'number' && response.status >= 400 || response.success === false) {
|
|
130
|
+
throw new Error(response.message || 'Schedule catalog request failed');
|
|
131
|
+
}
|
|
132
|
+
this.syncScheduleCatalogScope();
|
|
133
|
+
// A refresh or a different runtime may have superseded this request.
|
|
134
|
+
if (requestVersion === this.scheduleListRequestVersion) {
|
|
135
|
+
this.setScheduleList(response.data?.list || []);
|
|
136
|
+
}
|
|
88
137
|
}
|
|
89
138
|
setScheduleList(list) {
|
|
139
|
+
this.syncScheduleCatalogScope();
|
|
90
140
|
this.store.scheduleList = list;
|
|
91
141
|
this.syncScheduleMap();
|
|
92
142
|
this.hasLoadedScheduleList = true;
|
|
@@ -95,9 +145,11 @@ class ScheduleModule extends _BaseModule.BaseModule {
|
|
|
95
145
|
this.store.map = new Map((this.store.scheduleList || []).map(schedule => [Number(schedule.id), schedule]));
|
|
96
146
|
}
|
|
97
147
|
getScheduleList() {
|
|
148
|
+
this.syncScheduleCatalogScope();
|
|
98
149
|
return this.store.scheduleList || [];
|
|
99
150
|
}
|
|
100
151
|
isScheduleListLoaded() {
|
|
152
|
+
this.syncScheduleCatalogScope();
|
|
101
153
|
return this.hasLoadedScheduleList;
|
|
102
154
|
}
|
|
103
155
|
async loadScheduleAvailableDate({
|
|
@@ -149,6 +201,7 @@ class ScheduleModule extends _BaseModule.BaseModule {
|
|
|
149
201
|
return dates;
|
|
150
202
|
}
|
|
151
203
|
getScheduleListByIds(ids) {
|
|
204
|
+
this.syncScheduleCatalogScope();
|
|
152
205
|
const idSet = new Set(ids.map(id => String(id)));
|
|
153
206
|
if (this.store.map instanceof Map && this.store.map.size > 0) {
|
|
154
207
|
return ids.map(id => this.store.map.get(Number(id))).filter(Boolean);
|