@pisell/pisellos 0.10.66 → 0.10.68
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/solution/BaseSales/index.js +14 -8
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +24 -1
- package/dist/solution/BookingTicket/index.js +509 -256
- package/dist/solution/UnifiedBookingSales/index.js +1 -1
- package/lib/solution/BaseSales/index.js +3 -1
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +24 -1
- package/lib/solution/BookingTicket/index.js +115 -0
- package/lib/solution/UnifiedBookingSales/index.js +1 -1
- package/package.json +1 -1
|
@@ -2152,7 +2152,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
|
|
|
2152
2152
|
(_this$store$customer = this.store.customer) === null || _this$store$customer === void 0 || (_this$store$customer$ = _this$store$customer.setSelectedCustomer) === null || _this$store$customer$ === void 0 || _this$store$customer$.call(_this$store$customer, authenticatedCustomer);
|
|
2153
2153
|
this.setOrderCustomer(authenticatedCustomer);
|
|
2154
2154
|
_context8.next = 15;
|
|
2155
|
-
return Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh()]);
|
|
2155
|
+
return Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh(), this.waitForOrderCustomerContactInfo()]);
|
|
2156
2156
|
case 15:
|
|
2157
2157
|
return _context8.abrupt("return", true);
|
|
2158
2158
|
case 16:
|
|
@@ -1918,8 +1918,10 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1918
1918
|
}
|
|
1919
1919
|
async validateContactInfo() {
|
|
1920
1920
|
const order = this.getTempOrder();
|
|
1921
|
-
const identity = order?._extend?.localId || order?.external_sale_number || order?.order_id || order;
|
|
1922
1921
|
const customerId = order?.customer_id;
|
|
1922
|
+
// Missing customer IDs and the reserved Walk-In IDs do not require contact info.
|
|
1923
|
+
if (!Number.isFinite(Number(customerId)) || Number(customerId) <= 1) return;
|
|
1924
|
+
const identity = order?._extend?.localId || order?.external_sale_number || order?.order_id || order;
|
|
1923
1925
|
const config = await this.getContactInfoConfig();
|
|
1924
1926
|
const current = this.getTempOrder();
|
|
1925
1927
|
if (identity !== (current?._extend?.localId || current?.external_sale_number || current?.order_id || current) || customerId !== current?.customer_id) {
|
|
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
326
326
|
date: string;
|
|
327
327
|
status: string;
|
|
328
328
|
week: string;
|
|
329
|
-
weekNum: 0 |
|
|
329
|
+
weekNum: 0 | 6 | 5 | 1 | 2 | 3 | 4;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -32,6 +32,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
32
32
|
private orderCustomerDiscountRefreshCustomerId;
|
|
33
33
|
private orderCustomerDiscountRefreshTarget;
|
|
34
34
|
private orderCustomerPromotionRefreshInFlight;
|
|
35
|
+
private orderCustomerContactRequest;
|
|
35
36
|
private readonly customerResolveRequests;
|
|
36
37
|
protected loadOpenDataInFlight: Promise<OpenDataConfig> | null;
|
|
37
38
|
protected loadOpenDataInFlightTarget: string | null;
|
|
@@ -276,6 +277,16 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
276
277
|
setOrderCustomer(customer: ICustomer | null, options?: {
|
|
277
278
|
source?: OrderCustomerChangePayload['source'];
|
|
278
279
|
}): void;
|
|
280
|
+
private resetOrderCustomerContactInfo;
|
|
281
|
+
/** Explicit edits, including clearing the contact, must win over a pending default. */
|
|
282
|
+
updateTempOrderContactsInfo(contact: Record<string, any> | null): Record<string, any> | null;
|
|
283
|
+
private getCustomerContactScope;
|
|
284
|
+
private getCustomerContactOrderKey;
|
|
285
|
+
replaceTempOrder(...args: Parameters<BaseSalesImpl['replaceTempOrder']>): Promise<import("../../modules/Order/types").OrderTempOrder>;
|
|
286
|
+
private applyDefaultOrderCustomerContactInfo;
|
|
287
|
+
private prefillOrderCustomerContactInfo;
|
|
288
|
+
protected waitForOrderCustomerContactInfo(): Promise<void>;
|
|
289
|
+
validateContactInfo(): Promise<void>;
|
|
279
290
|
/**
|
|
280
291
|
* 读取 tempOrder 上的下单客户协议字段;customer_id 缺失时返回 null。
|
|
281
292
|
*/
|
|
@@ -468,7 +479,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
468
479
|
* 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
|
|
469
480
|
* 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
|
|
470
481
|
*/
|
|
471
|
-
decideAddProduct(item: any, options?: Partial<AddProductDecideContext>):
|
|
482
|
+
decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
|
|
483
|
+
action: "reloadCatalog";
|
|
484
|
+
} | {
|
|
485
|
+
action: "add";
|
|
486
|
+
cacheItem: any;
|
|
487
|
+
} | {
|
|
488
|
+
action: "requiresDetail";
|
|
489
|
+
payload: AddProductRequiresDetailPayload;
|
|
490
|
+
} | {
|
|
491
|
+
action: "requiresBookingEdit";
|
|
492
|
+
cacheItem: any;
|
|
493
|
+
payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
|
|
494
|
+
};
|
|
472
495
|
/** 规格弹窗 callback 后的第二段决策。 */
|
|
473
496
|
decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
|
|
474
497
|
/**
|
|
@@ -40,6 +40,7 @@ var _bookingStatus = require("./utils/bookingStatus");
|
|
|
40
40
|
var _resolveBestAddTimePlan = require("./utils/resolveBestAddTimePlan");
|
|
41
41
|
var _utils = require("../../modules/Order/utils");
|
|
42
42
|
var _contactInfo = require("../../modules/OpenData/contactInfo");
|
|
43
|
+
var _platform = require("../../utils/platform");
|
|
43
44
|
var _lodashEs = require("lodash-es");
|
|
44
45
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
45
46
|
const OPEN_DATA_SECTION_CODES = ['sale', 'reservation', 'fulfillment', 'menu', 'workflow', 'documents'];
|
|
@@ -164,6 +165,7 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
164
165
|
orderCustomerDiscountRefreshCustomerId = null;
|
|
165
166
|
orderCustomerDiscountRefreshTarget = null;
|
|
166
167
|
orderCustomerPromotionRefreshInFlight = null;
|
|
168
|
+
orderCustomerContactRequest = null;
|
|
167
169
|
customerResolveRequests = new Map();
|
|
168
170
|
loadOpenDataInFlight = null;
|
|
169
171
|
loadOpenDataInFlightTarget = null;
|
|
@@ -1028,9 +1030,15 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1028
1030
|
this.hasManualDiscountSelection = false;
|
|
1029
1031
|
}
|
|
1030
1032
|
if (!customerUnchanged && options?.source !== 'detailHydrate') {
|
|
1033
|
+
this.resetOrderCustomerContactInfo();
|
|
1031
1034
|
this.store.order.updateTempOrderContactsInfo((0, _lodashEs.cloneDeep)((0, _contactInfo.extractCustomerContactInfo)(customer)));
|
|
1032
1035
|
}
|
|
1033
1036
|
this.store.order.setOrderCustomer(patch, customer);
|
|
1037
|
+
if (options?.source === 'detailHydrate') {
|
|
1038
|
+
this.orderCustomerContactRequest = null;
|
|
1039
|
+
} else {
|
|
1040
|
+
this.prefillOrderCustomerContactInfo(customer, !customerUnchanged);
|
|
1041
|
+
}
|
|
1034
1042
|
const snapshotAfterOrderSet = this.store.order.getOrderCustomerSnapshot();
|
|
1035
1043
|
if (customerUnchanged) {
|
|
1036
1044
|
// hydrate 后 customer_id 已存在但 _extend.customerSnapshot 仍为空时,
|
|
@@ -1063,6 +1071,105 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1063
1071
|
this.orderCustomerPromotionRefreshInFlight = null;
|
|
1064
1072
|
});
|
|
1065
1073
|
}
|
|
1074
|
+
resetOrderCustomerContactInfo() {
|
|
1075
|
+
this.orderCustomerContactRequest = null;
|
|
1076
|
+
const order = this.getTempOrder();
|
|
1077
|
+
if (order?._extend) delete order._extend.contactInfoEdited;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/** Explicit edits, including clearing the contact, must win over a pending default. */
|
|
1081
|
+
updateTempOrderContactsInfo(contact) {
|
|
1082
|
+
const order = this.store.order.ensureTempOrder();
|
|
1083
|
+
order._extend || (order._extend = {});
|
|
1084
|
+
order._extend.contactInfoEdited = true;
|
|
1085
|
+
this.orderCustomerContactRequest = null;
|
|
1086
|
+
return super.updateTempOrderContactsInfo(contact);
|
|
1087
|
+
}
|
|
1088
|
+
getCustomerContactScope() {
|
|
1089
|
+
return JSON.stringify([this.getPickupTimingScope(), this.otherParams?.channel, this.otherParams?.shop_id, this.otherParams?.tenantId]);
|
|
1090
|
+
}
|
|
1091
|
+
getCustomerContactOrderKey() {
|
|
1092
|
+
const order = this.getTempOrder();
|
|
1093
|
+
// Cart mutations can replace the object without changing the order.
|
|
1094
|
+
const identity = order?.external_sale_number || order?.request_unique_idempotency_token || order?._extend?.localId || order?.order_id;
|
|
1095
|
+
return identity ? JSON.stringify([identity, order?.order_id]) : order;
|
|
1096
|
+
}
|
|
1097
|
+
async replaceTempOrder(...args) {
|
|
1098
|
+
this.orderCustomerContactRequest = null;
|
|
1099
|
+
return super.replaceTempOrder(...args);
|
|
1100
|
+
}
|
|
1101
|
+
async applyDefaultOrderCustomerContactInfo(contact) {
|
|
1102
|
+
this.store.order.updateTempOrderContactsInfo((0, _lodashEs.cloneDeep)(contact));
|
|
1103
|
+
// Metadata may finish after promotion/discount refresh; publish the updated cart explicitly.
|
|
1104
|
+
await this.effectsEmit('onTempOrderReplaced', {
|
|
1105
|
+
tempOrder: this.getTempOrder()
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1108
|
+
prefillOrderCustomerContactInfo(customer, customerChanged) {
|
|
1109
|
+
const order = this.getTempOrder();
|
|
1110
|
+
const customerId = Number(order?.customer_id);
|
|
1111
|
+
if (!order || !Number.isInteger(customerId) || customerId <= 1 || order.contacts_info != null || order._extend?.contactInfoEdited) return;
|
|
1112
|
+
// A restored new cart may already have its customer ID. Existing sales keep their snapshot,
|
|
1113
|
+
// even when it is empty; only an explicit customer switch replaces it.
|
|
1114
|
+
if (!customerChanged && order.order_id && !String(order.order_id).startsWith('local_order')) return;
|
|
1115
|
+
const contact = (0, _contactInfo.extractCustomerContactInfo)(customer);
|
|
1116
|
+
if (contact) {
|
|
1117
|
+
this.orderCustomerContactRequest = null;
|
|
1118
|
+
void this.applyDefaultOrderCustomerContactInfo(contact);
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
// A relation explicitly returned as null is authoritative. Only a missing relation needs fetching.
|
|
1122
|
+
if (customer.contacts_info !== undefined) return;
|
|
1123
|
+
const userPlatform = (0, _platform.isCustomerUserPlatform)(this.otherParams?.platform);
|
|
1124
|
+
const getAuthenticatedCustomerId = () => Number(this.core?.getPlugin?.('user')?.get?.()?.id);
|
|
1125
|
+
if (userPlatform && getAuthenticatedCustomerId() !== customerId) return;
|
|
1126
|
+
const scope = this.getCustomerContactScope();
|
|
1127
|
+
const orderKey = this.getCustomerContactOrderKey();
|
|
1128
|
+
const previous = this.orderCustomerContactRequest;
|
|
1129
|
+
if (previous?.orderKey === orderKey && previous.customerId === customerId && previous.scope === scope) return;
|
|
1130
|
+
const pending = {
|
|
1131
|
+
orderKey,
|
|
1132
|
+
customerId,
|
|
1133
|
+
scope,
|
|
1134
|
+
promise: Promise.resolve()
|
|
1135
|
+
};
|
|
1136
|
+
this.orderCustomerContactRequest = pending;
|
|
1137
|
+
const loadContact = async () => {
|
|
1138
|
+
if (userPlatform) {
|
|
1139
|
+
// Same endpoint as BookingByStep.getContactInfo; the PC/H5 host adds /h5 and login headers.
|
|
1140
|
+
const result = await this.request.get('/customer/metadata', {
|
|
1141
|
+
key: 'contacts_info'
|
|
1142
|
+
});
|
|
1143
|
+
if (result?.code !== 200 || result?.status === false) throw new Error('Customer contact lookup failed');
|
|
1144
|
+
return (0, _contactInfo.isContactRecord)(result.data) ? result.data : null;
|
|
1145
|
+
}
|
|
1146
|
+
// POS and physical Kiosk share the /shop request plugin and current-shop customer resolver.
|
|
1147
|
+
const resolved = await this.resolveCustomerById(customerId);
|
|
1148
|
+
return Number(resolved?.id) === customerId ? (0, _contactInfo.extractCustomerContactInfo)(resolved) : null;
|
|
1149
|
+
};
|
|
1150
|
+
pending.promise = loadContact().then(async value => {
|
|
1151
|
+
const current = this.getTempOrder();
|
|
1152
|
+
if (this.orderCustomerContactRequest !== pending || this.getCustomerContactOrderKey() !== orderKey || Number(current?.customer_id) !== customerId || scope !== this.getCustomerContactScope() || current?._extend?.contactInfoEdited || current?.contacts_info != null || userPlatform && getAuthenticatedCustomerId() !== customerId) return;
|
|
1153
|
+
if (value) await this.applyDefaultOrderCustomerContactInfo(value);
|
|
1154
|
+
}).catch(() => {
|
|
1155
|
+
// A failed default does not prevent manual entry; a subsequent sync can retry.
|
|
1156
|
+
if (this.orderCustomerContactRequest === pending) this.orderCustomerContactRequest = null;
|
|
1157
|
+
console.warn('[BookingTicket] Failed to load saved customer contact information');
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
waitForOrderCustomerContactInfo() {
|
|
1161
|
+
return this.orderCustomerContactRequest?.promise ?? Promise.resolve();
|
|
1162
|
+
}
|
|
1163
|
+
async validateContactInfo() {
|
|
1164
|
+
const orderKey = this.getCustomerContactOrderKey();
|
|
1165
|
+
const customerId = this.getTempOrder()?.customer_id;
|
|
1166
|
+
const scope = this.getCustomerContactScope();
|
|
1167
|
+
await this.waitForOrderCustomerContactInfo();
|
|
1168
|
+
if (this.getCustomerContactOrderKey() !== orderKey || this.getTempOrder()?.customer_id !== customerId || this.getCustomerContactScope() !== scope) {
|
|
1169
|
+
throw new Error('The order changed. Please try again.');
|
|
1170
|
+
}
|
|
1171
|
+
await super.validateContactInfo();
|
|
1172
|
+
}
|
|
1066
1173
|
|
|
1067
1174
|
/**
|
|
1068
1175
|
* 读取 tempOrder 上的下单客户协议字段;customer_id 缺失时返回 null。
|
|
@@ -1082,6 +1189,8 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1082
1189
|
* 清空下单客户(协议字段 + snapshot)。
|
|
1083
1190
|
*/
|
|
1084
1191
|
clearOrderCustomer(options) {
|
|
1192
|
+
this.orderCustomerContactRequest = null;
|
|
1193
|
+
if (!options?.preserveContactInfo) this.resetOrderCustomerContactInfo();
|
|
1085
1194
|
if (!options?.preserveContactInfo) this.store.order.updateTempOrderContactsInfo(null);
|
|
1086
1195
|
this.store.order.clearOrderCustomer();
|
|
1087
1196
|
this.discountConfigCacheKey = null;
|
|
@@ -1902,6 +2011,11 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1902
2011
|
async setOtherParams(params, {
|
|
1903
2012
|
cover = false
|
|
1904
2013
|
} = {}) {
|
|
2014
|
+
const nextParams = cover ? params : {
|
|
2015
|
+
...this.otherParams,
|
|
2016
|
+
...params
|
|
2017
|
+
};
|
|
2018
|
+
if (['businessCode', 'business_code', 'channel', 'platform', 'shop_id', 'tenantId', 'cacheId'].some(key => nextParams?.[key] !== this.otherParams?.[key])) this.orderCustomerContactRequest = null;
|
|
1905
2019
|
await super.setOtherParams(params, {
|
|
1906
2020
|
cover
|
|
1907
2021
|
});
|
|
@@ -2017,6 +2131,7 @@ class BookingTicketImpl extends _BaseSales.BaseSalesImpl {
|
|
|
2017
2131
|
* 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。
|
|
2018
2132
|
*/
|
|
2019
2133
|
async destroy() {
|
|
2134
|
+
this.orderCustomerContactRequest = null;
|
|
2020
2135
|
await super.destroy();
|
|
2021
2136
|
try {
|
|
2022
2137
|
this.scan?.removeAllListeners();
|
|
@@ -1718,7 +1718,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
|
|
|
1718
1718
|
}
|
|
1719
1719
|
this.store.customer?.setSelectedCustomer?.(authenticatedCustomer);
|
|
1720
1720
|
this.setOrderCustomer(authenticatedCustomer);
|
|
1721
|
-
await Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh()]);
|
|
1721
|
+
await Promise.all([this.refreshDiscountConfigAfterOrderCustomerChange(authenticatedCustomerId), this.waitForOrderCustomerPromotionRefresh(), this.waitForOrderCustomerContactInfo()]);
|
|
1722
1722
|
return true;
|
|
1723
1723
|
}
|
|
1724
1724
|
isAuthenticatedCustomerUserPlatform() {
|