@pisell/pisellos 2.3.85 → 2.3.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/Order/index.js +17 -16
- package/dist/modules/Order/types.d.ts +1 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.js +154 -64
- package/dist/server/modules/order/index.d.ts +8 -0
- package/dist/server/modules/order/index.js +251 -215
- package/dist/solution/BaseSales/index.d.ts +3 -0
- package/dist/solution/BaseSales/index.js +127 -82
- package/dist/solution/BookingTicket/index.js +5 -2
- package/dist/solution/UnifiedBookingSales/index.js +19 -4
- package/lib/modules/Order/index.js +8 -7
- package/lib/modules/Order/types.d.ts +1 -0
- package/lib/server/index.d.ts +4 -0
- package/lib/server/index.js +83 -2
- package/lib/server/modules/order/index.d.ts +8 -0
- package/lib/server/modules/order/index.js +23 -0
- package/lib/solution/BaseSales/index.d.ts +3 -0
- package/lib/solution/BaseSales/index.js +35 -4
- package/lib/solution/BookingTicket/index.js +5 -2
- package/lib/solution/UnifiedBookingSales/index.js +14 -0
- package/package.json +1 -1
|
@@ -3794,6 +3794,13 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3794
3794
|
}
|
|
3795
3795
|
this.store.syncState = 'submitting';
|
|
3796
3796
|
const paymentSyncIdempotencyToken = this.buildPaymentSyncIdempotencyToken(tempOrder, effectivePayments);
|
|
3797
|
+
const enhancePayload = (payload, ctx) => {
|
|
3798
|
+
const enhancedPayload = params.enhancePayload ? params.enhancePayload(payload, ctx) : payload;
|
|
3799
|
+
return {
|
|
3800
|
+
...enhancedPayload,
|
|
3801
|
+
request_unique_idempotency_token: paymentSyncIdempotencyToken
|
|
3802
|
+
};
|
|
3803
|
+
};
|
|
3797
3804
|
const submitParams = {
|
|
3798
3805
|
payments: effectivePayments,
|
|
3799
3806
|
paymentStatus,
|
|
@@ -3801,13 +3808,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
3801
3808
|
businessCode: params.businessCode,
|
|
3802
3809
|
channel: params.channel,
|
|
3803
3810
|
confirmPendingVoucherPayments: true,
|
|
3804
|
-
enhancePayload
|
|
3805
|
-
const nextPayload = {
|
|
3806
|
-
...payload,
|
|
3807
|
-
request_unique_idempotency_token: paymentSyncIdempotencyToken
|
|
3808
|
-
};
|
|
3809
|
-
return nextPayload;
|
|
3810
|
-
}
|
|
3811
|
+
enhancePayload
|
|
3811
3812
|
};
|
|
3812
3813
|
const submitResult = params.checkoutSyncTaskEnabled === false ? await this.submitTempOrderAsync(submitParams) : await this.submitTempOrder(submitParams);
|
|
3813
3814
|
return {
|
|
@@ -608,6 +608,7 @@ export interface SyncPaymentsToOrderParams {
|
|
|
608
608
|
businessCode?: string;
|
|
609
609
|
channel?: string;
|
|
610
610
|
confirmPendingVoucherPayments?: boolean;
|
|
611
|
+
enhancePayload?: SubmitPayloadEnhancer;
|
|
611
612
|
}
|
|
612
613
|
export interface SyncPaymentsToOrderResult<T = any> {
|
|
613
614
|
isFullyPaid: boolean;
|
package/lib/server/index.d.ts
CHANGED
|
@@ -511,6 +511,10 @@ declare class Server {
|
|
|
511
511
|
private buildCheckoutTaskIdempotencyKey;
|
|
512
512
|
private isBlankCheckoutValue;
|
|
513
513
|
private isLocalCheckoutOrderId;
|
|
514
|
+
private applyCheckoutFulfillmentBuzzer;
|
|
515
|
+
private buildCheckoutResourceIdentifierBuzzer;
|
|
516
|
+
private getCheckoutResourceIdentifier;
|
|
517
|
+
private stringifyCheckoutResourceIdentifier;
|
|
514
518
|
private normalizeCheckoutSubmitData;
|
|
515
519
|
private ensureCheckoutOrderNumbers;
|
|
516
520
|
private dispatchCheckoutSyncTask;
|
package/lib/server/index.js
CHANGED
|
@@ -40,6 +40,8 @@ Object.keys(_modules).forEach(function (key) {
|
|
|
40
40
|
});
|
|
41
41
|
});
|
|
42
42
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
43
|
+
const OS_FULFILLMENT_REF_MODE_FIELD = '_os_fulfillment_ref_mode';
|
|
44
|
+
|
|
43
45
|
// 重新导出类型供外部使用
|
|
44
46
|
|
|
45
47
|
/** 商品查询订阅者 */
|
|
@@ -624,7 +626,8 @@ class Server {
|
|
|
624
626
|
title
|
|
625
627
|
} = params;
|
|
626
628
|
const normalizedData = await this.normalizeCheckoutSubmitData(params.data, title);
|
|
627
|
-
const
|
|
629
|
+
const numberedData = await this.ensureCheckoutOrderNumbers(normalizedData, title);
|
|
630
|
+
const checkoutData = this.applyCheckoutFulfillmentBuzzer(numberedData, title);
|
|
628
631
|
const remoteCheckoutData = this.buildRemoteCheckoutData(checkoutData, title);
|
|
629
632
|
if (!this.app?.request?.post) {
|
|
630
633
|
throw new Error('app.request 不可用');
|
|
@@ -693,6 +696,7 @@ class Server {
|
|
|
693
696
|
const next = (0, _lodashEs.cloneDeep)(this.omitCheckoutSyncMode(data));
|
|
694
697
|
if (!next || typeof next !== 'object') return next;
|
|
695
698
|
const record = next;
|
|
699
|
+
delete record[OS_FULFILLMENT_REF_MODE_FIELD];
|
|
696
700
|
if (!Array.isArray(record.payments)) return next;
|
|
697
701
|
const originalPayments = record.payments;
|
|
698
702
|
const filteredPayments = originalPayments.filter(payment => !(0, _paymentUtils.isPendingOrderPayment)(payment));
|
|
@@ -3379,6 +3383,82 @@ class Server {
|
|
|
3379
3383
|
isLocalCheckoutOrderId(orderId) {
|
|
3380
3384
|
return typeof orderId === 'string' && orderId.startsWith('LOCAL_');
|
|
3381
3385
|
}
|
|
3386
|
+
applyCheckoutFulfillmentBuzzer(data, title) {
|
|
3387
|
+
if (!data || typeof data !== 'object') return data;
|
|
3388
|
+
const next = {
|
|
3389
|
+
...data
|
|
3390
|
+
};
|
|
3391
|
+
const refMode = String(next[OS_FULFILLMENT_REF_MODE_FIELD] || '').trim();
|
|
3392
|
+
delete next[OS_FULFILLMENT_REF_MODE_FIELD];
|
|
3393
|
+
if (!refMode) return next;
|
|
3394
|
+
if (refMode === 'manual_input') {
|
|
3395
|
+
this.logInfo(`${title}: fulfillment ref mode 保留手动 buzzer`, {
|
|
3396
|
+
fulfillment_ref_mode: refMode,
|
|
3397
|
+
has_buzzer: !this.isBlankCheckoutValue(next.buzzer)
|
|
3398
|
+
});
|
|
3399
|
+
return next;
|
|
3400
|
+
}
|
|
3401
|
+
if (refMode === 'resource_identifier') {
|
|
3402
|
+
next.buzzer = this.buildCheckoutResourceIdentifierBuzzer(next.bookings);
|
|
3403
|
+
} else if (refMode === 'sale_number') {
|
|
3404
|
+
next.buzzer = this.isBlankCheckoutValue(next.shop_order_number) ? '' : String(next.shop_order_number);
|
|
3405
|
+
} else if (refMode === 'short_number') {
|
|
3406
|
+
next.buzzer = this.isBlankCheckoutValue(next.shop_full_order_number) ? '' : String(next.shop_full_order_number);
|
|
3407
|
+
} else {
|
|
3408
|
+
this.logWarning(`${title}: 未识别的 fulfillment ref mode,跳过 buzzer 自动填充`, {
|
|
3409
|
+
fulfillment_ref_mode: refMode
|
|
3410
|
+
});
|
|
3411
|
+
return next;
|
|
3412
|
+
}
|
|
3413
|
+
this.logInfo(`${title}: fulfillment ref mode 已填充 buzzer`, {
|
|
3414
|
+
fulfillment_ref_mode: refMode,
|
|
3415
|
+
buzzer: next.buzzer
|
|
3416
|
+
});
|
|
3417
|
+
return next;
|
|
3418
|
+
}
|
|
3419
|
+
buildCheckoutResourceIdentifierBuzzer(bookings) {
|
|
3420
|
+
if (!Array.isArray(bookings)) return '';
|
|
3421
|
+
const values = [];
|
|
3422
|
+
const seen = new Set();
|
|
3423
|
+
const visitResource = resource => {
|
|
3424
|
+
const identifier = this.getCheckoutResourceIdentifier(resource);
|
|
3425
|
+
if (identifier && !seen.has(identifier)) {
|
|
3426
|
+
seen.add(identifier);
|
|
3427
|
+
values.push(identifier);
|
|
3428
|
+
}
|
|
3429
|
+
if (Array.isArray(resource?.children)) {
|
|
3430
|
+
resource.children.forEach(visitResource);
|
|
3431
|
+
}
|
|
3432
|
+
};
|
|
3433
|
+
bookings.forEach(booking => {
|
|
3434
|
+
if (Array.isArray(booking?.resources)) {
|
|
3435
|
+
booking.resources.forEach(visitResource);
|
|
3436
|
+
}
|
|
3437
|
+
});
|
|
3438
|
+
return values.join(',');
|
|
3439
|
+
}
|
|
3440
|
+
getCheckoutResourceIdentifier(resource) {
|
|
3441
|
+
if (!resource || typeof resource !== 'object') return '';
|
|
3442
|
+
const candidates = [resource.main_field, resource.name, resource.title, resource.metadata?.resource_name, resource.metadata?.name, resource.relation_id, resource.id];
|
|
3443
|
+
for (const candidate of candidates) {
|
|
3444
|
+
const value = this.stringifyCheckoutResourceIdentifier(candidate);
|
|
3445
|
+
if (value) return value;
|
|
3446
|
+
}
|
|
3447
|
+
return '';
|
|
3448
|
+
}
|
|
3449
|
+
stringifyCheckoutResourceIdentifier(value) {
|
|
3450
|
+
if (value === undefined || value === null) return '';
|
|
3451
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
3452
|
+
return String(value).trim();
|
|
3453
|
+
}
|
|
3454
|
+
if (typeof value !== 'object' || Array.isArray(value)) return '';
|
|
3455
|
+
const localeCandidates = [value.original, value.auto, value.en, value['zh-CN'], value.zh_CN, value['zh-HK'], value.zh_HK];
|
|
3456
|
+
for (const candidate of localeCandidates) {
|
|
3457
|
+
const normalized = this.stringifyCheckoutResourceIdentifier(candidate);
|
|
3458
|
+
if (normalized) return normalized;
|
|
3459
|
+
}
|
|
3460
|
+
return '';
|
|
3461
|
+
}
|
|
3382
3462
|
async normalizeCheckoutSubmitData(data, title) {
|
|
3383
3463
|
if (!data || typeof data !== 'object') return data;
|
|
3384
3464
|
const next = {
|
|
@@ -3936,7 +4016,8 @@ class Server {
|
|
|
3936
4016
|
});
|
|
3937
4017
|
}
|
|
3938
4018
|
const normalizedData = await this.normalizeCheckoutSubmitData(data, title);
|
|
3939
|
-
const
|
|
4019
|
+
const numberedData = await this.ensureCheckoutOrderNumbers(normalizedData, title);
|
|
4020
|
+
const checkoutData = this.applyCheckoutFulfillmentBuzzer(numberedData, title);
|
|
3940
4021
|
const pendingResult = await this.handlePendingSyncCheckoutOrder({
|
|
3941
4022
|
backendPath,
|
|
3942
4023
|
data: checkoutData,
|
|
@@ -20,6 +20,8 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
20
20
|
private storage;
|
|
21
21
|
private orderSQLiteSaveQueue; /** 按 storageKey 记录最近一次 SQLite 写入来源与时间,用于去重 */
|
|
22
22
|
private recentSqliteWriteByStorageKey;
|
|
23
|
+
/** 最近一次清理过期 SQLite 去重记录的时间,避免每次写入都遍历 Map */
|
|
24
|
+
private lastRecentSqliteWriteCleanupAtMs;
|
|
23
25
|
/** 最近一次 SSE 全量拉取完成时间 */
|
|
24
26
|
private lastServerFullFetchAtMs;
|
|
25
27
|
constructor(name?: string, version?: string);
|
|
@@ -58,6 +60,12 @@ export declare class OrderModule extends BaseModule implements Module {
|
|
|
58
60
|
*/
|
|
59
61
|
private mergeAuthoritativeOrderCollection;
|
|
60
62
|
private reconcileOverwriteOrderCollections;
|
|
63
|
+
/**
|
|
64
|
+
* 惰性清理已经超过去重窗口的 SQLite 写入记录。
|
|
65
|
+
*
|
|
66
|
+
* 清理频率与去重窗口一致,既限制 Map 长期增长,也不会移除仍参与去重的记录。
|
|
67
|
+
*/
|
|
68
|
+
private cleanupExpiredRecentSqliteWrites;
|
|
61
69
|
/**
|
|
62
70
|
* 记录订单最近一次 SQLite 写入,供 pubsub 回声去重使用。
|
|
63
71
|
*
|
|
@@ -57,6 +57,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
57
57
|
storage;
|
|
58
58
|
orderSQLiteSaveQueue = Promise.resolve(); /** 按 storageKey 记录最近一次 SQLite 写入来源与时间,用于去重 */
|
|
59
59
|
recentSqliteWriteByStorageKey = new Map();
|
|
60
|
+
/** 最近一次清理过期 SQLite 去重记录的时间,避免每次写入都遍历 Map */
|
|
61
|
+
lastRecentSqliteWriteCleanupAtMs = 0;
|
|
60
62
|
/** 最近一次 SSE 全量拉取完成时间 */
|
|
61
63
|
lastServerFullFetchAtMs = 0;
|
|
62
64
|
constructor(name, version) {
|
|
@@ -292,6 +294,24 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
292
294
|
return this.normalizeOrderCollectionsForIngress((0, _orderCollectionIdentity.applyOrderCollectionUidRemaps)(reconciled, uidRemaps), 'overwriteExistingOrder.reconciled');
|
|
293
295
|
}
|
|
294
296
|
|
|
297
|
+
/**
|
|
298
|
+
* 惰性清理已经超过去重窗口的 SQLite 写入记录。
|
|
299
|
+
*
|
|
300
|
+
* 清理频率与去重窗口一致,既限制 Map 长期增长,也不会移除仍参与去重的记录。
|
|
301
|
+
*/
|
|
302
|
+
cleanupExpiredRecentSqliteWrites(now) {
|
|
303
|
+
const elapsedSinceCleanup = now - this.lastRecentSqliteWriteCleanupAtMs;
|
|
304
|
+
if (this.lastRecentSqliteWriteCleanupAtMs > 0 && elapsedSinceCleanup >= 0 && elapsedSinceCleanup < ORDER_SQLITE_DEDUPE_MS) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
for (const [storageKey, recentWrite] of this.recentSqliteWriteByStorageKey) {
|
|
308
|
+
if (now - recentWrite.ts >= ORDER_SQLITE_DEDUPE_MS) {
|
|
309
|
+
this.recentSqliteWriteByStorageKey.delete(storageKey);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
this.lastRecentSqliteWriteCleanupAtMs = now;
|
|
313
|
+
}
|
|
314
|
+
|
|
295
315
|
/**
|
|
296
316
|
* 记录订单最近一次 SQLite 写入,供 pubsub 回声去重使用。
|
|
297
317
|
*
|
|
@@ -300,6 +320,7 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
300
320
|
*/
|
|
301
321
|
recordRecentSqliteWrite(source, orders) {
|
|
302
322
|
const now = Date.now();
|
|
323
|
+
this.cleanupExpiredRecentSqliteWrites(now);
|
|
303
324
|
for (const order of orders) {
|
|
304
325
|
const storageKey = this.getOrderStorageKey(order);
|
|
305
326
|
if (!storageKey) continue;
|
|
@@ -1264,6 +1285,8 @@ class OrderModule extends _BaseModule.BaseModule {
|
|
|
1264
1285
|
}
|
|
1265
1286
|
this.isProcessingSyncBatch = false;
|
|
1266
1287
|
this.pendingSyncMessages = [];
|
|
1288
|
+
this.recentSqliteWriteByStorageKey.clear();
|
|
1289
|
+
this.lastRecentSqliteWriteCleanupAtMs = 0;
|
|
1267
1290
|
if (this.orderDataSource?.destroy) this.orderDataSource.destroy();
|
|
1268
1291
|
super.destroy();
|
|
1269
1292
|
}
|
|
@@ -151,6 +151,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
151
151
|
private getAuthoritativeBundleUnitPrice;
|
|
152
152
|
private mergeProductForPriceQuery;
|
|
153
153
|
protected getSubmitOrderSalesChannel(): string | undefined;
|
|
154
|
+
private getFulfillmentRefModeConfigs;
|
|
155
|
+
private getFulfillmentRefMode;
|
|
156
|
+
private buildSubmitPayloadEnhancerWithFulfillmentRefMode;
|
|
154
157
|
/**
|
|
155
158
|
* 工厂入口:根据子模块名实例化对应模块。
|
|
156
159
|
* 默认使用 BookingByStep 公共 `createModule`。子类若需引入额外类型(如 customer),
|
|
@@ -36,6 +36,7 @@ var _transformBaseProductToOrderProduct = require("./utils/transformBaseProductT
|
|
|
36
36
|
var _quotationPrice = require("./utils/quotationPrice");
|
|
37
37
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
38
38
|
const SERVER_ORDER_CHANGED_EVENT = 'order:onOrdersChanged';
|
|
39
|
+
const OS_FULFILLMENT_REF_MODE_FIELD = '_os_fulfillment_ref_mode';
|
|
39
40
|
const WALLET_PAYMENT_CODE_BY_TAG = {
|
|
40
41
|
product_voucher: 'PRODUCTVOUCHER',
|
|
41
42
|
gift_card: 'GIFTCARD',
|
|
@@ -1041,6 +1042,30 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1041
1042
|
getSubmitOrderSalesChannel() {
|
|
1042
1043
|
return this.otherParams?.channel;
|
|
1043
1044
|
}
|
|
1045
|
+
getFulfillmentRefModeConfigs() {
|
|
1046
|
+
const candidates = [this.otherParams?.openData, this.otherParams?.dineInConfig, this.store?.openData?.getOpenData?.()];
|
|
1047
|
+
return candidates.filter(candidate => candidate && typeof candidate === 'object' && !Array.isArray(candidate));
|
|
1048
|
+
}
|
|
1049
|
+
getFulfillmentRefMode() {
|
|
1050
|
+
for (const config of this.getFulfillmentRefModeConfigs()) {
|
|
1051
|
+
const mode = config['fulfillment.fulfillment_ref_mode'];
|
|
1052
|
+
if (mode === undefined || mode === null) continue;
|
|
1053
|
+
const normalized = String(mode).trim();
|
|
1054
|
+
if (normalized) return normalized;
|
|
1055
|
+
}
|
|
1056
|
+
return undefined;
|
|
1057
|
+
}
|
|
1058
|
+
buildSubmitPayloadEnhancerWithFulfillmentRefMode(enhancePayload) {
|
|
1059
|
+
const fulfillmentRefMode = this.getFulfillmentRefMode();
|
|
1060
|
+
if (!fulfillmentRefMode) return enhancePayload;
|
|
1061
|
+
return (payload, ctx) => {
|
|
1062
|
+
const enhancedPayload = enhancePayload ? enhancePayload(payload, ctx) : payload;
|
|
1063
|
+
return {
|
|
1064
|
+
...enhancedPayload,
|
|
1065
|
+
[OS_FULFILLMENT_REF_MODE_FIELD]: fulfillmentRefMode
|
|
1066
|
+
};
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1044
1069
|
|
|
1045
1070
|
/**
|
|
1046
1071
|
* 工厂入口:根据子模块名实例化对应模块。
|
|
@@ -2018,6 +2043,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2018
2043
|
// this.store.order.persistTempOrder();
|
|
2019
2044
|
const inferredPaymentStatus = this.getSubmitPaymentStatus(params?.paymentStatus);
|
|
2020
2045
|
const smallTicketDataFlag = params?.smallTicketDataFlag ?? this.getDefaultCheckoutSmallTicketDataFlag();
|
|
2046
|
+
const enhancePayload = this.buildSubmitPayloadEnhancerWithFulfillmentRefMode(params?.enhancePayload);
|
|
2021
2047
|
const submitParams = {
|
|
2022
2048
|
cacheId: this.cacheId,
|
|
2023
2049
|
platform: this.otherParams?.platform,
|
|
@@ -2037,8 +2063,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2037
2063
|
...(params?.confirmPendingVoucherPayments !== undefined ? {
|
|
2038
2064
|
confirmPendingVoucherPayments: params.confirmPendingVoucherPayments
|
|
2039
2065
|
} : {}),
|
|
2040
|
-
...(
|
|
2041
|
-
enhancePayload
|
|
2066
|
+
...(enhancePayload !== undefined ? {
|
|
2067
|
+
enhancePayload
|
|
2042
2068
|
} : {})
|
|
2043
2069
|
};
|
|
2044
2070
|
return this.shouldUseCheckoutSyncTask() ? this.store.order.submitTempOrder(submitParams) : this.store.order.submitTempOrderAsync(submitParams);
|
|
@@ -2064,6 +2090,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2064
2090
|
}
|
|
2065
2091
|
const inferredPaymentStatus = this.getSubmitPaymentStatus(params?.paymentStatus);
|
|
2066
2092
|
const smallTicketDataFlag = params?.smallTicketDataFlag ?? this.getDefaultCheckoutSmallTicketDataFlag();
|
|
2093
|
+
const enhancePayload = this.buildSubmitPayloadEnhancerWithFulfillmentRefMode(params?.enhancePayload);
|
|
2067
2094
|
const submitParams = {
|
|
2068
2095
|
cacheId: this.cacheId,
|
|
2069
2096
|
platform: this.otherParams?.platform,
|
|
@@ -2083,8 +2110,8 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2083
2110
|
...(params?.confirmPendingVoucherPayments !== undefined ? {
|
|
2084
2111
|
confirmPendingVoucherPayments: params.confirmPendingVoucherPayments
|
|
2085
2112
|
} : {}),
|
|
2086
|
-
...(
|
|
2087
|
-
enhancePayload
|
|
2113
|
+
...(enhancePayload !== undefined ? {
|
|
2114
|
+
enhancePayload
|
|
2088
2115
|
} : {})
|
|
2089
2116
|
};
|
|
2090
2117
|
return this.store.order.submitTempOrderAsync(submitParams);
|
|
@@ -2157,6 +2184,7 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2157
2184
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
2158
2185
|
const businessCode = params.businessCode ?? this.otherParams?.businessCode ?? this.otherParams?.business_code;
|
|
2159
2186
|
const channel = params.channel ?? this.getSubmitOrderSalesChannel();
|
|
2187
|
+
const enhancePayload = this.buildSubmitPayloadEnhancerWithFulfillmentRefMode(params.enhancePayload);
|
|
2160
2188
|
const syncParams = {
|
|
2161
2189
|
...params,
|
|
2162
2190
|
checkoutSyncTaskEnabled: this.shouldUseCheckoutSyncTask(),
|
|
@@ -2165,6 +2193,9 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
2165
2193
|
} : {}),
|
|
2166
2194
|
...(channel !== undefined ? {
|
|
2167
2195
|
channel
|
|
2196
|
+
} : {}),
|
|
2197
|
+
...(enhancePayload !== undefined ? {
|
|
2198
|
+
enhancePayload
|
|
2168
2199
|
} : {})
|
|
2169
2200
|
};
|
|
2170
2201
|
const syncState = this.store.order.getOrderSyncState();
|
|
@@ -275,7 +275,10 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
275
275
|
const prefix = this.normalizeIdPrefix(openDataConfig?.['sale.short_number_prefix'], '');
|
|
276
276
|
const shopOrderPrefix = this.normalizeIdPrefix(openDataConfig?.['sale.sale_number_prefix'], '');
|
|
277
277
|
const resetReceiptSequenceDaily = typeof openDataConfig?.['sale.short_number_daily_reset'] === 'boolean' ? openDataConfig?.['sale.short_number_daily_reset'] : false;
|
|
278
|
-
const operatingDayBoundary = this.getAppData('operating_day_boundary')
|
|
278
|
+
const operatingDayBoundary = this.getAppData('operating_day_boundary') || {
|
|
279
|
+
"type": "start_time",
|
|
280
|
+
"time": "00:00"
|
|
281
|
+
};
|
|
279
282
|
const deviceId = await this.getShortNumberOrDeviceId();
|
|
280
283
|
this.setPaymentNumberDevicePrefix(deviceId);
|
|
281
284
|
const businessCode = this.getBookingTicketBusinessCode();
|
|
@@ -293,7 +296,7 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
293
296
|
padReceiptSequence: false,
|
|
294
297
|
receiptSequenceLength,
|
|
295
298
|
resetReceiptSequenceDaily,
|
|
296
|
-
receiptSequenceResetTime: operatingDayBoundary
|
|
299
|
+
receiptSequenceResetTime: operatingDayBoundary?.time,
|
|
297
300
|
receiptSequenceStart,
|
|
298
301
|
shopOrderPrefix
|
|
299
302
|
}
|
|
@@ -986,6 +986,7 @@ const POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cu
|
|
|
986
986
|
// as missing_resource at group level. Structural validation below still
|
|
987
987
|
// rejects a genuinely missing selection.
|
|
988
988
|
'missing_resource']);
|
|
989
|
+
const POS_NO_RESOURCE_ID = 0;
|
|
989
990
|
function matchesForcedSelectionGroup(selection, group) {
|
|
990
991
|
const hasGroupId = typeof selection.requirementGroupId === 'string' && selection.requirementGroupId.trim().length > 0;
|
|
991
992
|
const hasFormId = selection.formId !== undefined && selection.formId !== null;
|
|
@@ -1066,6 +1067,19 @@ function buildPosForcedAvailabilityAssignments(params) {
|
|
|
1066
1067
|
return;
|
|
1067
1068
|
}
|
|
1068
1069
|
selectedResourceIds.forEach(resourceId => {
|
|
1070
|
+
if (sameAvailabilityId(resourceId, POS_NO_RESOURCE_ID)) {
|
|
1071
|
+
assignments.push({
|
|
1072
|
+
productId: product.id,
|
|
1073
|
+
resourceId: POS_NO_RESOURCE_ID,
|
|
1074
|
+
formId: group.formId ?? selection.formId,
|
|
1075
|
+
startAt: candidate.bookingStartAt || candidate.startAt,
|
|
1076
|
+
endAt: candidate.bookingEndAt || candidate.endAt,
|
|
1077
|
+
capacityRequired: Math.max(1, partySize),
|
|
1078
|
+
scheduleId: candidate.primaryScheduleRef?.scheduleId,
|
|
1079
|
+
timeSlotId: candidate.primaryScheduleRef?.timeSlotId
|
|
1080
|
+
});
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1069
1083
|
const resource = resources.find(item => sameAvailabilityId(item.id, resourceId));
|
|
1070
1084
|
const belongsToGroup = Boolean(resource && !(group.formId !== undefined && resource.formId !== undefined && !sameAvailabilityId(group.formId, resource.formId)) && !(group.resourceIds?.length && !group.resourceIds.some(id => sameAvailabilityId(id, resourceId))));
|
|
1071
1085
|
if (!resource || !belongsToGroup) {
|