@pisell/pisellos 2.2.293 → 2.2.295
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/itemRule/adapter.d.ts +1 -4
- package/dist/model/strategy/adapter/itemRule/adapter.js +35 -135
- package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +1 -8
- package/dist/model/strategy/adapter/itemRule/evaluator.js +1 -25
- package/dist/model/strategy/adapter/itemRule/type.d.ts +0 -44
- package/dist/model/strategy/adapter/itemRule/type.js +1 -19
- package/dist/modules/Order/index.d.ts +3 -18
- package/dist/modules/Order/index.js +485 -885
- package/dist/modules/Order/types.d.ts +5 -91
- package/dist/modules/Order/types.js +0 -5
- package/dist/modules/Order/utils.js +10 -22
- package/dist/modules/ProductList/index.d.ts +1 -2
- package/dist/modules/ProductList/index.js +20 -100
- package/dist/modules/ProductList/types.d.ts +0 -10
- package/dist/server/index.d.ts +0 -6
- package/dist/server/index.js +3 -43
- package/dist/solution/BaseSales/index.d.ts +1 -9
- package/dist/solution/BaseSales/index.js +706 -894
- package/dist/solution/BookingByStep/index.d.ts +2 -2
- package/dist/solution/BookingTicket/utils/orderCustomer.js +2 -3
- package/dist/solution/RegisterAndLogin/config.d.ts +3 -9
- package/dist/solution/RegisterAndLogin/config.js +40 -95
- package/dist/solution/RegisterAndLogin/index.js +1 -4
- package/dist/solution/ScanOrder/index.d.ts +0 -1
- package/dist/solution/ScanOrder/index.js +27 -31
- package/dist/solution/ScanOrder/utils.d.ts +0 -1
- package/dist/solution/ScanOrder/utils.js +0 -2
- package/dist/solution/UnifiedBookingSales/index.d.ts +4 -17
- package/dist/solution/UnifiedBookingSales/index.js +489 -755
- package/dist/solution/UnifiedBookingSales/types.d.ts +1 -14
- package/dist/solution/VenueBooking/index.d.ts +0 -1
- package/dist/solution/VenueBooking/index.js +4 -8
- package/lib/model/strategy/adapter/itemRule/adapter.d.ts +1 -4
- package/lib/model/strategy/adapter/itemRule/adapter.js +4 -73
- package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +1 -8
- package/lib/model/strategy/adapter/itemRule/evaluator.js +1 -23
- package/lib/model/strategy/adapter/itemRule/type.d.ts +0 -44
- package/lib/model/strategy/adapter/itemRule/type.js +1 -19
- package/lib/model/strategy/adapter/promotion/index.js +46 -1
- package/lib/modules/Order/index.d.ts +3 -18
- package/lib/modules/Order/index.js +28 -325
- package/lib/modules/Order/types.d.ts +5 -91
- package/lib/modules/Order/types.js +0 -4
- package/lib/modules/Order/utils.js +1 -13
- package/lib/modules/ProductList/index.d.ts +1 -2
- package/lib/modules/ProductList/index.js +2 -47
- package/lib/modules/ProductList/types.d.ts +0 -10
- package/lib/server/index.d.ts +0 -6
- package/lib/server/index.js +3 -37
- package/lib/solution/BaseSales/index.d.ts +1 -9
- package/lib/solution/BaseSales/index.js +1 -105
- package/lib/solution/BookingByStep/index.d.ts +2 -2
- package/lib/solution/BookingTicket/utils/orderCustomer.js +1 -2
- package/lib/solution/RegisterAndLogin/config.d.ts +3 -9
- package/lib/solution/RegisterAndLogin/config.js +8 -49
- package/lib/solution/RegisterAndLogin/index.js +1 -4
- package/lib/solution/ScanOrder/index.d.ts +0 -1
- package/lib/solution/ScanOrder/index.js +1 -5
- package/lib/solution/ScanOrder/utils.d.ts +0 -1
- package/lib/solution/ScanOrder/utils.js +0 -1
- package/lib/solution/UnifiedBookingSales/index.d.ts +4 -17
- package/lib/solution/UnifiedBookingSales/index.js +6 -128
- package/lib/solution/UnifiedBookingSales/types.d.ts +1 -14
- package/lib/solution/VenueBooking/index.d.ts +0 -1
- package/lib/solution/VenueBooking/index.js +1 -5
- package/package.json +1 -1
- package/dist/modules/Order/salesNotes.d.ts +0 -31
- package/dist/modules/Order/salesNotes.js +0 -492
- package/lib/modules/Order/salesNotes.d.ts +0 -31
- package/lib/modules/Order/salesNotes.js +0 -382
|
@@ -126,7 +126,6 @@ var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
|
126
126
|
var _utils = require("../Holder/utils");
|
|
127
127
|
var _utils2 = require("../../solution/ScanOrder/utils");
|
|
128
128
|
var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
|
|
129
|
-
var _salesNotes = require("./salesNotes");
|
|
130
129
|
var _manualProductDiscount = require("./utils/manualProductDiscount");
|
|
131
130
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
132
131
|
/**
|
|
@@ -1129,7 +1128,6 @@ function createDefaultTempOrder(params) {
|
|
|
1129
1128
|
request_unique_idempotency_token: '',
|
|
1130
1129
|
vouchers: [],
|
|
1131
1130
|
products: [],
|
|
1132
|
-
notes: [],
|
|
1133
1131
|
bookings: [],
|
|
1134
1132
|
payments: [],
|
|
1135
1133
|
surcharges: [],
|
|
@@ -1139,11 +1137,7 @@ function createDefaultTempOrder(params) {
|
|
|
1139
1137
|
holder: null,
|
|
1140
1138
|
metadata: {},
|
|
1141
1139
|
_extend: {
|
|
1142
|
-
productsByUid: {}
|
|
1143
|
-
salesNotesState: {
|
|
1144
|
-
loaded: true,
|
|
1145
|
-
dirty: false
|
|
1146
|
-
}
|
|
1140
|
+
productsByUid: {}
|
|
1147
1141
|
}
|
|
1148
1142
|
};
|
|
1149
1143
|
}
|
|
@@ -1224,7 +1218,6 @@ function buildSubmitPayload(params) {
|
|
|
1224
1218
|
total_refund_amount: _totalRefundAmount,
|
|
1225
1219
|
create_date: _createDate,
|
|
1226
1220
|
holder_id: _holderId,
|
|
1227
|
-
notes: _notes,
|
|
1228
1221
|
...tempOrderRest
|
|
1229
1222
|
} = tempOrder;
|
|
1230
1223
|
const resolvedBusinessCode = businessCode ?? tempOrder.business_code;
|
|
@@ -1282,11 +1275,6 @@ function buildSubmitPayload(params) {
|
|
|
1282
1275
|
...rest
|
|
1283
1276
|
};
|
|
1284
1277
|
})(),
|
|
1285
|
-
...(tempOrder._extend?.salesNotesState?.dirty ? {
|
|
1286
|
-
notes: (0, _salesNotes.encodeSalesNotes)(tempOrder.notes || [], {
|
|
1287
|
-
allowUnresolvedOrderTarget: true
|
|
1288
|
-
})
|
|
1289
|
-
} : {}),
|
|
1290
1278
|
products: (tempOrder.products || []).map(product => normalizeSubmitProduct(product))
|
|
1291
1279
|
};
|
|
1292
1280
|
if (!enhance) return payload;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Module, PisellCore } from '../../types';
|
|
2
2
|
import { BaseModule } from '../BaseModule';
|
|
3
|
-
import { ProductListLoadProductsParams
|
|
3
|
+
import { ProductListLoadProductsParams } from './types';
|
|
4
4
|
import { ProductData } from '../Product/types';
|
|
5
5
|
export * from './types';
|
|
6
6
|
export declare class ProductList extends BaseModule implements Module {
|
|
@@ -52,7 +52,6 @@ export declare class ProductList extends BaseModule implements Module {
|
|
|
52
52
|
getRawProductPriceSources(ids: number[]): Map<number, ProductData>;
|
|
53
53
|
getProducts(): Promise<ProductData[]>;
|
|
54
54
|
getProduct(id: number): Promise<ProductData | undefined>;
|
|
55
|
-
queryProducts(params?: ProductListStoreQueryParams): Promise<ProductData[]>;
|
|
56
55
|
getProductByIds(ids: number[]): Promise<ProductData[] | undefined>;
|
|
57
56
|
addProduct(products: ProductData[]): Promise<void>;
|
|
58
57
|
selectProducts(products: ProductData[]): Promise<void>;
|
|
@@ -25,15 +25,6 @@ Object.keys(_types).forEach(function (key) {
|
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
28
|
-
function normalizeQuerySet(values) {
|
|
29
|
-
if (!Array.isArray(values) || values.length === 0) return null;
|
|
30
|
-
const normalized = values.map(value => String(value ?? '').trim()).filter(Boolean);
|
|
31
|
-
return normalized.length ? new Set(normalized) : null;
|
|
32
|
-
}
|
|
33
|
-
function matchesAny(values, querySet) {
|
|
34
|
-
if (!querySet) return true;
|
|
35
|
-
return values.some(value => querySet.has(String(value ?? '').trim()));
|
|
36
|
-
}
|
|
37
28
|
class ProductList extends _BaseModule.BaseModule {
|
|
38
29
|
defaultName = 'productList';
|
|
39
30
|
defaultVersion = '1.0.0';
|
|
@@ -290,46 +281,10 @@ class ProductList extends _BaseModule.BaseModule {
|
|
|
290
281
|
const product = this.store.list.find(product => product.id === id);
|
|
291
282
|
return product ? (0, _lodashEs.cloneDeep)(product) : undefined;
|
|
292
283
|
}
|
|
293
|
-
async queryProducts(params = {}) {
|
|
294
|
-
const includeIds = normalizeQuerySet(params.includeIds);
|
|
295
|
-
const excludeIds = normalizeQuerySet(params.excludeIds);
|
|
296
|
-
const categoryIds = normalizeQuerySet(params.categoryIds);
|
|
297
|
-
const collectionIds = normalizeQuerySet(params.collectionIds);
|
|
298
|
-
const extensionTypes = normalizeQuerySet(params.extensionTypes);
|
|
299
|
-
const statuses = normalizeQuerySet(params.statuses);
|
|
300
|
-
const channelApplications = normalizeQuerySet(params.channelApplications);
|
|
301
|
-
const codeOrBarcode = typeof params.codeOrBarcode === 'string' ? params.codeOrBarcode.trim() : '';
|
|
302
|
-
const products = (this.store.list || []).filter(product => {
|
|
303
|
-
const productId = String(product.id ?? '').trim();
|
|
304
|
-
if (includeIds && !includeIds.has(productId)) return false;
|
|
305
|
-
if (excludeIds && excludeIds.has(productId)) return false;
|
|
306
|
-
if (categoryIds) {
|
|
307
|
-
const productCategoryIds = (product.categories || []).flatMap(category => [category?.id, category?.pivot?.product_category_id]);
|
|
308
|
-
if (!matchesAny(productCategoryIds, categoryIds)) return false;
|
|
309
|
-
}
|
|
310
|
-
if (collectionIds) {
|
|
311
|
-
const productCollectionIds = (product.collection || []).map(collection => collection?.id);
|
|
312
|
-
if (!matchesAny(productCollectionIds, collectionIds)) return false;
|
|
313
|
-
}
|
|
314
|
-
if (extensionTypes && !extensionTypes.has(String(product.extension_type ?? '').trim())) return false;
|
|
315
|
-
if (statuses && !statuses.has(String(product.status ?? '').trim())) return false;
|
|
316
|
-
if (channelApplications) {
|
|
317
|
-
if (!matchesAny(product.channel_application || [], channelApplications)) return false;
|
|
318
|
-
}
|
|
319
|
-
if (codeOrBarcode) {
|
|
320
|
-
const code = typeof product.code === 'string' ? product.code.trim() : '';
|
|
321
|
-
const barcode = typeof product.barcode === 'string' ? product.barcode.trim() : '';
|
|
322
|
-
if (code !== codeOrBarcode && barcode !== codeOrBarcode) return false;
|
|
323
|
-
}
|
|
324
|
-
return true;
|
|
325
|
-
});
|
|
326
|
-
return (0, _lodashEs.cloneDeep)(products);
|
|
327
|
-
}
|
|
328
284
|
async getProductByIds(ids) {
|
|
329
285
|
await this.core.effects.emit(`${this.name}:onGetProductByIds`, this.store.list);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
});
|
|
286
|
+
const products = this.store.list.filter(product => ids.includes(product.id));
|
|
287
|
+
return products;
|
|
333
288
|
}
|
|
334
289
|
async addProduct(products) {
|
|
335
290
|
// list 需要根据 id 去重
|
|
@@ -15,16 +15,6 @@ export interface ProductListLoadProductsParams {
|
|
|
15
15
|
/** 智能定价条件上下文,仅影响策略命中,不参与商品集合筛选 */
|
|
16
16
|
strategy_context?: Record<string, any>;
|
|
17
17
|
}
|
|
18
|
-
export interface ProductListStoreQueryParams {
|
|
19
|
-
includeIds?: Array<number | string>;
|
|
20
|
-
excludeIds?: Array<number | string>;
|
|
21
|
-
categoryIds?: Array<number | string>;
|
|
22
|
-
collectionIds?: Array<number | string>;
|
|
23
|
-
extensionTypes?: string[];
|
|
24
|
-
statuses?: ProductData['status'][];
|
|
25
|
-
channelApplications?: string[];
|
|
26
|
-
codeOrBarcode?: string;
|
|
27
|
-
}
|
|
28
18
|
export interface ProductListData {
|
|
29
19
|
list: ProductData[];
|
|
30
20
|
selectProducts: ProductData[];
|
package/lib/server/index.d.ts
CHANGED
|
@@ -520,12 +520,6 @@ declare class Server {
|
|
|
520
520
|
private stringifyCheckoutResourceIdentifier;
|
|
521
521
|
private normalizeCheckoutSubmitData;
|
|
522
522
|
private ensureCheckoutOrderNumbers;
|
|
523
|
-
/**
|
|
524
|
-
* Notes 允许在本地草稿阶段暂存空订单目标;checkout 的统一出口负责用最终
|
|
525
|
-
* shop_order_number 完成绑定并校验,保证后端请求、pending、设备任务和打印
|
|
526
|
-
* 都使用同一份完整快照。
|
|
527
|
-
*/
|
|
528
|
-
private finalizeCheckoutSalesNotes;
|
|
529
523
|
private dispatchCheckoutSyncTask;
|
|
530
524
|
private dispatchPrintOtherReceiptTask;
|
|
531
525
|
private buildPrintOtherReceiptIdempotencyKey;
|
package/lib/server/index.js
CHANGED
|
@@ -27,7 +27,6 @@ var _filterBookings = require("./modules/order/utils/filterBookings");
|
|
|
27
27
|
var _smallTicket = require("./utils/small-ticket");
|
|
28
28
|
var _BaseSales = require("../solution/BaseSales");
|
|
29
29
|
var _paymentUtils = require("../modules/Order/payment-utils");
|
|
30
|
-
var _salesNotes = require("../modules/Order/salesNotes");
|
|
31
30
|
var _modules = require("./modules");
|
|
32
31
|
Object.keys(_modules).forEach(function (key) {
|
|
33
32
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -3588,16 +3587,14 @@ class Server {
|
|
|
3588
3587
|
};
|
|
3589
3588
|
const needsShopOrderNumber = next.shop_order_number === undefined || next.shop_order_number === null || next.shop_order_number === '';
|
|
3590
3589
|
const needsShopFullOrderNumber = next.shop_full_order_number === undefined || next.shop_full_order_number === null || next.shop_full_order_number === '';
|
|
3591
|
-
if (!needsShopOrderNumber && !needsShopFullOrderNumber)
|
|
3592
|
-
return this.finalizeCheckoutSalesNotes(next, title);
|
|
3593
|
-
}
|
|
3590
|
+
if (!needsShopOrderNumber && !needsShopFullOrderNumber) return next;
|
|
3594
3591
|
const idGenerator = this.getIdGeneratorPlugin();
|
|
3595
3592
|
if (!idGenerator) {
|
|
3596
3593
|
this.logWarning(`${title}: idGenerator 插件不可用,无法生成订单号`, {
|
|
3597
3594
|
needsShopOrderNumber,
|
|
3598
3595
|
needsShopFullOrderNumber
|
|
3599
3596
|
});
|
|
3600
|
-
return
|
|
3597
|
+
return next;
|
|
3601
3598
|
}
|
|
3602
3599
|
try {
|
|
3603
3600
|
if (needsShopOrderNumber && idGenerator.generateShopOrderNumber) {
|
|
@@ -3619,38 +3616,7 @@ class Server {
|
|
|
3619
3616
|
error: error instanceof Error ? error.message : String(error)
|
|
3620
3617
|
});
|
|
3621
3618
|
}
|
|
3622
|
-
return
|
|
3623
|
-
}
|
|
3624
|
-
|
|
3625
|
-
/**
|
|
3626
|
-
* Notes 允许在本地草稿阶段暂存空订单目标;checkout 的统一出口负责用最终
|
|
3627
|
-
* shop_order_number 完成绑定并校验,保证后端请求、pending、设备任务和打印
|
|
3628
|
-
* 都使用同一份完整快照。
|
|
3629
|
-
*/
|
|
3630
|
-
finalizeCheckoutSalesNotes(data, title) {
|
|
3631
|
-
if (!data || typeof data !== 'object') return data;
|
|
3632
|
-
if (!Object.prototype.hasOwnProperty.call(data, 'notes')) return data;
|
|
3633
|
-
if (data.notes === undefined || data.notes === null) return data;
|
|
3634
|
-
if (!Array.isArray(data.notes)) {
|
|
3635
|
-
throw new Error('[Order Notes] checkout notes 必须为数组');
|
|
3636
|
-
}
|
|
3637
|
-
if (data.notes.length === 0) return data;
|
|
3638
|
-
const productTargetUuids = (Array.isArray(data.products) ? data.products : []).map(product => product?.metadata?.unique_identification_number ?? product?.unique_identification_number).filter(targetUuid => targetUuid !== undefined && targetUuid !== null && String(targetUuid).trim().length > 0).map(targetUuid => String(targetUuid));
|
|
3639
|
-
const shopOrderNumber = String(data.shop_order_number ?? '').trim();
|
|
3640
|
-
const notes = (0, _salesNotes.finalizeSalesNotesForCheckout)({
|
|
3641
|
-
notes: data.notes,
|
|
3642
|
-
shopOrderNumber,
|
|
3643
|
-
productTargetUuids
|
|
3644
|
-
});
|
|
3645
|
-
this.logInfo(`${title}: checkout Notes 已绑定订单号`, {
|
|
3646
|
-
shop_order_number: shopOrderNumber,
|
|
3647
|
-
note_count: notes.length
|
|
3648
|
-
});
|
|
3649
|
-
return {
|
|
3650
|
-
...data,
|
|
3651
|
-
shop_order_number: shopOrderNumber,
|
|
3652
|
-
notes
|
|
3653
|
-
};
|
|
3619
|
+
return next;
|
|
3654
3620
|
}
|
|
3655
3621
|
async dispatchCheckoutSyncTask(params) {
|
|
3656
3622
|
this.registerDeviceTaskActions();
|
|
@@ -2,7 +2,7 @@ import { Module, ModuleOptions, PisellCore } from '../../types';
|
|
|
2
2
|
import { BaseModule } from '../../modules/BaseModule';
|
|
3
3
|
import { BaseSalesOrderProduct, BaseSalesOrderProductIdentity, BaseSalesPaymentStatus, BaseSalesUpdateOrderProductQuantityParams, BaseSalesCalculateProductBookingPriceParams, BaseSalesPriceRecalculationContextChange, BaseSalesProductBookingPriceResult, BaseSalesQuotationCustomerScopeInfo, BaseSalesScanCodeResult, BaseSalesCashPaymentConfig, BaseSalesPayCashParams, BaseSalesPayCashResult, BaseSalesCommitPaymentMethodParams, BaseSalesCommitPaymentMethodResult, BaseSalesConfirmWalletPaymentResult } from './types';
|
|
4
4
|
import { OrderModule } from '../../modules/Order';
|
|
5
|
-
import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions
|
|
5
|
+
import type { AddProductBookingInput, AddProductToOrderOptions, LoadSalesDetailParams, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, OrderPaymentSource, SendCustomerPayLinkParams, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, UpdateTempOrderCustomerInput, UpdateOrderBookingParams, UpdateOrderProductParams, OrderTempOrder, OrderSummary, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions, RemoveProductsFromOrderOptions, ReplaceTempOrderOptions } from '../../modules/Order/types';
|
|
6
6
|
import type { SubmitPayloadEnhancer } from '../../modules/Order/utils';
|
|
7
7
|
import type { Discount } from '../../modules/Discount/types';
|
|
8
8
|
import { RequestPlugin, WindowPlugin } from '../../plugins';
|
|
@@ -225,20 +225,12 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
225
225
|
getOrderSyncState(): import("../../modules/Order/types").OrderSyncState;
|
|
226
226
|
getOrderAmountSnapshot(): import("../../modules/Order/types").OrderAmountSnapshot | null;
|
|
227
227
|
getTempOrderNote(): string;
|
|
228
|
-
getSalesNotes(): SalesNote[];
|
|
229
|
-
createSalesNotesMutationSnapshot(): SalesNotesMutationSnapshot;
|
|
230
|
-
restoreSalesNotesMutationSnapshot(snapshot: SalesNotesMutationSnapshot): void;
|
|
231
|
-
setSalesNote(input: SetSalesNoteInput): Promise<SalesNote>;
|
|
232
|
-
removeSalesNote(uuid: string): Promise<void>;
|
|
233
|
-
clearSalesNotes(): Promise<void>;
|
|
234
228
|
updateTempOrderNote(note: string): string;
|
|
235
229
|
updateTempOrderNote(note: string, sync: true): Promise<string>;
|
|
236
230
|
updateTempOrderNote(note: string, sync: boolean): string | Promise<string>;
|
|
237
231
|
updateRemoteOrderNote(orderId: number | string, note: string): void;
|
|
238
232
|
updateTempOrderShopDiscount(amount: string | number): string;
|
|
239
233
|
updateTempOrderDepositAmount(amount: string | number): OrderSummary;
|
|
240
|
-
setPickupReferenceMode(mode: PickupReferenceMode): ShopServiceData;
|
|
241
|
-
setServiceType(serviceType: ShopServiceType): ShopServiceData;
|
|
242
234
|
updateTempOrderContactsInfo(contactsInfo: Record<string, any> | null): Record<string, any> | null;
|
|
243
235
|
/** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化。 */
|
|
244
236
|
setEnableTempOrderPersist(enabled: boolean): void;
|
|
@@ -283,56 +283,7 @@ function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey) {
|
|
|
283
283
|
loadedValue.forEach(appendOrReplaceByUid);
|
|
284
284
|
return result;
|
|
285
285
|
}
|
|
286
|
-
|
|
287
|
-
// checkout / realtime snapshots may reorder protocol arrays or append persistence fields.
|
|
288
|
-
// Compare only the Sales Note protocol fields so a matching remote echo can acknowledge dirty state.
|
|
289
|
-
function normalizeBaseSalesNotesForComparison(value, options) {
|
|
290
|
-
if (!Array.isArray(value)) return null;
|
|
291
|
-
const unresolvedOrderTargetUuid = String(options?.unresolvedOrderTargetUuid ?? '').trim();
|
|
292
|
-
return value.map(note => {
|
|
293
|
-
if (!note || typeof note !== 'object' || Array.isArray(note)) {
|
|
294
|
-
return (0, _lodashEs.cloneDeep)(note);
|
|
295
|
-
}
|
|
296
|
-
const noteRecord = note;
|
|
297
|
-
const relations = Array.isArray(noteRecord.note_relations) ? noteRecord.note_relations.map(relation => {
|
|
298
|
-
if (!relation || typeof relation !== 'object' || Array.isArray(relation)) {
|
|
299
|
-
return (0, _lodashEs.cloneDeep)(relation);
|
|
300
|
-
}
|
|
301
|
-
const shouldResolveOrderTarget = relation.is_primary === 0 && relation.relation_type === 'related_to' && relation.target_type === 'order' && String(relation.target_uuid ?? '').trim() === '' && unresolvedOrderTargetUuid.length > 0;
|
|
302
|
-
return {
|
|
303
|
-
uuid: relation.uuid,
|
|
304
|
-
relation_type: relation.relation_type,
|
|
305
|
-
target_type: relation.target_type,
|
|
306
|
-
target_uuid: shouldResolveOrderTarget ? unresolvedOrderTargetUuid : relation.target_uuid,
|
|
307
|
-
is_primary: relation.is_primary
|
|
308
|
-
};
|
|
309
|
-
}).sort((left, right) => String(left?.uuid ?? '').localeCompare(String(right?.uuid ?? ''))) : (0, _lodashEs.cloneDeep)(noteRecord.note_relations);
|
|
310
|
-
return {
|
|
311
|
-
uuid: noteRecord.uuid,
|
|
312
|
-
note_type: noteRecord.note_type,
|
|
313
|
-
content: {
|
|
314
|
-
text: (0, _lodashEs.cloneDeep)(noteRecord.content?.text)
|
|
315
|
-
},
|
|
316
|
-
importance: noteRecord.importance,
|
|
317
|
-
note_relations: relations
|
|
318
|
-
};
|
|
319
|
-
}).sort((left, right) => String(left?.uuid ?? '').localeCompare(String(right?.uuid ?? '')));
|
|
320
|
-
}
|
|
321
|
-
function areBaseSalesNotesEquivalent(currentValue, loadedValue, options) {
|
|
322
|
-
const currentNotes = normalizeBaseSalesNotesForComparison(currentValue, {
|
|
323
|
-
unresolvedOrderTargetUuid: options?.currentOrderTargetUuid
|
|
324
|
-
});
|
|
325
|
-
const loadedNotes = normalizeBaseSalesNotesForComparison(loadedValue);
|
|
326
|
-
return currentNotes !== null && loadedNotes !== null && (0, _lodashEs.isEqual)(currentNotes, loadedNotes);
|
|
327
|
-
}
|
|
328
286
|
function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, strategy) {
|
|
329
|
-
const loadedHasSalesNotes = Object.prototype.hasOwnProperty.call(loadedRecord || {}, 'notes');
|
|
330
|
-
const hasDirtyLocalSalesNotes = currentTempOrder?._extend?.salesNotesState?.dirty === true;
|
|
331
|
-
const incomingSalesNotesMatchLocal = loadedHasSalesNotes && areBaseSalesNotesEquivalent(currentTempOrder?.notes, loadedRecord.notes, {
|
|
332
|
-
currentOrderTargetUuid: loadedRecord?.shop_order_number || currentTempOrder?.shop_order_number
|
|
333
|
-
});
|
|
334
|
-
const shouldAwaitAuthoritativeSalesNotes = strategy === 'authoritative-incoming' && hasDirtyLocalSalesNotes && (Number(loadedRecord?.need_sync) === 1 || !incomingSalesNotesMatchLocal);
|
|
335
|
-
const preserveDirtyLocalSalesNotes = hasDirtyLocalSalesNotes && (strategy === 'preserve-local' || shouldAwaitAuthoritativeSalesNotes);
|
|
336
287
|
const normalizedLoadedRecord = normalizeBaseSalesRecordCollections(loadedRecord || {}, {
|
|
337
288
|
ensureUid: false
|
|
338
289
|
});
|
|
@@ -344,12 +295,6 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, str
|
|
|
344
295
|
});
|
|
345
296
|
const uidRemaps = [];
|
|
346
297
|
const mergedRecord = (0, _lodashEs.mergeWith)(normalizedCurrentTempOrder, normalizedLoadedRecord, (currentValue, loadedValue, key) => {
|
|
347
|
-
if (key === 'notes') {
|
|
348
|
-
if (preserveDirtyLocalSalesNotes && Array.isArray(currentValue)) {
|
|
349
|
-
return (0, _lodashEs.cloneDeep)(currentValue);
|
|
350
|
-
}
|
|
351
|
-
if (Array.isArray(loadedValue)) return (0, _lodashEs.cloneDeep)(loadedValue);
|
|
352
|
-
}
|
|
353
298
|
const collectionKind = getBaseSalesOrderCollectionKind(key);
|
|
354
299
|
if (collectionKind && Array.isArray(loadedValue)) {
|
|
355
300
|
return mergeBaseSalesOrderCollection(collectionKind, Array.isArray(currentValue) ? currentValue : [], loadedValue, strategy, uidRemaps);
|
|
@@ -373,24 +318,7 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, str
|
|
|
373
318
|
return undefined;
|
|
374
319
|
});
|
|
375
320
|
delete mergedRecord.request_unique_idempotency_token;
|
|
376
|
-
|
|
377
|
-
normalizedMergedRecord._extend = {
|
|
378
|
-
...(normalizedMergedRecord._extend || {}),
|
|
379
|
-
salesNotesState: preserveDirtyLocalSalesNotes ? {
|
|
380
|
-
loaded: true,
|
|
381
|
-
dirty: true
|
|
382
|
-
} : loadedHasSalesNotes ? {
|
|
383
|
-
loaded: true,
|
|
384
|
-
dirty: normalizedLoadedRecord._extend?.salesNotesState?.dirty === true
|
|
385
|
-
} : {
|
|
386
|
-
loaded: false,
|
|
387
|
-
dirty: false
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
if (!loadedHasSalesNotes && !preserveDirtyLocalSalesNotes) {
|
|
391
|
-
delete normalizedMergedRecord.notes;
|
|
392
|
-
}
|
|
393
|
-
return normalizedMergedRecord;
|
|
321
|
+
return normalizeBaseSalesRecordCollections((0, _orderCollectionIdentity.applyOrderCollectionUidRemaps)(mergedRecord, uidRemaps));
|
|
394
322
|
}
|
|
395
323
|
function filterPendingPaymentsFromLoadedSalesDetail(sourceRecord) {
|
|
396
324
|
if (!sourceRecord || typeof sourceRecord !== 'object') return sourceRecord;
|
|
@@ -1498,30 +1426,6 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1498
1426
|
if (!this.store.order) return '';
|
|
1499
1427
|
return this.store.order.getTempOrderNote();
|
|
1500
1428
|
}
|
|
1501
|
-
getSalesNotes() {
|
|
1502
|
-
if (!this.store.order) return [];
|
|
1503
|
-
return this.store.order.getSalesNotes();
|
|
1504
|
-
}
|
|
1505
|
-
createSalesNotesMutationSnapshot() {
|
|
1506
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1507
|
-
return this.store.order.createSalesNotesMutationSnapshot();
|
|
1508
|
-
}
|
|
1509
|
-
restoreSalesNotesMutationSnapshot(snapshot) {
|
|
1510
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1511
|
-
this.store.order.restoreSalesNotesMutationSnapshot(snapshot);
|
|
1512
|
-
}
|
|
1513
|
-
async setSalesNote(input) {
|
|
1514
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1515
|
-
return this.store.order.setSalesNote(input);
|
|
1516
|
-
}
|
|
1517
|
-
async removeSalesNote(uuid) {
|
|
1518
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1519
|
-
await this.store.order.removeSalesNote(uuid);
|
|
1520
|
-
}
|
|
1521
|
-
async clearSalesNotes() {
|
|
1522
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1523
|
-
await this.store.order.clearSalesNotes();
|
|
1524
|
-
}
|
|
1525
1429
|
updateTempOrderNote(note, sync = false) {
|
|
1526
1430
|
try {
|
|
1527
1431
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
@@ -1543,14 +1447,6 @@ class BaseSalesImpl extends _BaseModule.BaseModule {
|
|
|
1543
1447
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1544
1448
|
return this.store.order.updateTempOrderDepositAmount(amount);
|
|
1545
1449
|
}
|
|
1546
|
-
setPickupReferenceMode(mode) {
|
|
1547
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1548
|
-
return this.store.order.updateTempOrderPickupReferenceMode(mode);
|
|
1549
|
-
}
|
|
1550
|
-
setServiceType(serviceType) {
|
|
1551
|
-
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1552
|
-
return this.store.order.updateTempOrderServiceType(serviceType);
|
|
1553
|
-
}
|
|
1554
1450
|
updateTempOrderContactsInfo(contactsInfo) {
|
|
1555
1451
|
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1556
1452
|
return this.store.order.updateTempOrderContactsInfo(contactsInfo);
|
|
@@ -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 | 2 | 1 | 6 | 4 | 3 | 5;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
|
|
|
345
345
|
count: number;
|
|
346
346
|
left: number;
|
|
347
347
|
summaryCount: number;
|
|
348
|
-
status: "
|
|
348
|
+
status: "lots_of_space" | "filling_up_fast" | "sold_out";
|
|
349
349
|
}[];
|
|
350
350
|
/**
|
|
351
351
|
* 找到多个资源的公共可用时间段
|
|
@@ -23,8 +23,7 @@ function resolveCustomerDisplayName(customer) {
|
|
|
23
23
|
|
|
24
24
|
/** 将 ICustomer 格式化为写入 tempOrder 的协议字段。 */
|
|
25
25
|
function formatOrderCustomerPatch(customer) {
|
|
26
|
-
const
|
|
27
|
-
const rawId = c.customer_id ?? c.customerId ?? customer.id;
|
|
26
|
+
const rawId = customer.id;
|
|
28
27
|
const numericId = typeof rawId === 'number' ? rawId : rawId !== undefined && rawId !== null && rawId !== '' ? Number(rawId) : null;
|
|
29
28
|
return {
|
|
30
29
|
customer_id: Number.isFinite(numericId) ? numericId : null,
|
|
@@ -10,11 +10,7 @@ export interface ApiConfig {
|
|
|
10
10
|
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
11
11
|
transformParams?: (params: any) => any;
|
|
12
12
|
transformResponse?: (response: any) => any;
|
|
13
|
-
options?: Record<string, any
|
|
14
|
-
}
|
|
15
|
-
export interface ApiCallerOptions {
|
|
16
|
-
baseUrl?: string;
|
|
17
|
-
shopDomain?: string;
|
|
13
|
+
options?: Record<string, any>;
|
|
18
14
|
}
|
|
19
15
|
/**
|
|
20
16
|
* 渠道配置接口
|
|
@@ -69,14 +65,12 @@ export declare function getChannelConfig(channel: string): ChannelConfig;
|
|
|
69
65
|
export declare class ApiCaller {
|
|
70
66
|
private request;
|
|
71
67
|
private config;
|
|
72
|
-
private options;
|
|
73
68
|
constructor(request: {
|
|
74
69
|
get: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
75
70
|
post: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
76
71
|
put: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
77
72
|
delete: <T = any>(url: string, options?: any) => Promise<T>;
|
|
78
|
-
}, config: ChannelConfig
|
|
79
|
-
private resolveUrl;
|
|
73
|
+
}, config: ChannelConfig);
|
|
80
74
|
/**
|
|
81
75
|
* 执行 API 调用
|
|
82
76
|
*/
|
|
@@ -90,4 +84,4 @@ export declare function createApiCaller(request: {
|
|
|
90
84
|
post: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
91
85
|
put: <T = any>(url: string, data?: any, options?: any) => Promise<T>;
|
|
92
86
|
delete: <T = any>(url: string, options?: any) => Promise<T>;
|
|
93
|
-
}, channel: string
|
|
87
|
+
}, channel: string): ApiCaller;
|
|
@@ -15,8 +15,6 @@ exports.getChannelConfig = getChannelConfig;
|
|
|
15
15
|
* API 配置接口
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
const h5CustomerAuthApiNames = new Set(['sendEmailVerificationCode', 'sendEmailLoginCode', 'sendSmsRegisterCode', 'sendEmailRegisterLink', 'verifyEmailRegistrationLink', 'emailPasswordLogin', 'emailCodeRegister', 'phoneCodeRegister', 'resendEmailRegisterLink', 'checkEmailLinkCode', 'sendSmsLoginCode', 'phoneCodeLogin', 'guestLogin', 'checkEmailExists', 'checkEmailCode', 'checkMobileCode', 'phonePasswordLogin', 'sendPasswordResetEmail', 'sendPasswordResetSms', 'sendResetPasswordLink', 'checkResetPasswordCode', 'resetPasswordByCode', 'resetPasswordByEmail', 'resetPasswordByPhone', 'verifyCode', 'register', 'login', 'oauthLogin', 'facebookLogin', 'appleLogin']);
|
|
19
|
-
|
|
20
18
|
/**
|
|
21
19
|
* 渠道配置接口
|
|
22
20
|
*/
|
|
@@ -280,31 +278,6 @@ const onlineStoreConfig = {
|
|
|
280
278
|
})
|
|
281
279
|
}
|
|
282
280
|
};
|
|
283
|
-
function withH5AuthPrefix(config) {
|
|
284
|
-
const nextConfig = {};
|
|
285
|
-
Object.entries(config).forEach(([key, apiConfig]) => {
|
|
286
|
-
if (!apiConfig.url.startsWith('/auth/')) {
|
|
287
|
-
nextConfig[key] = apiConfig;
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
nextConfig[key] = {
|
|
291
|
-
...apiConfig,
|
|
292
|
-
url: apiConfig.url.startsWith('/h5/') ? apiConfig.url : `/h5${apiConfig.url}`,
|
|
293
|
-
options: params => {
|
|
294
|
-
const {
|
|
295
|
-
withCredentials,
|
|
296
|
-
...baseOptions
|
|
297
|
-
} = (typeof apiConfig.options === 'function' ? apiConfig.options(params) : apiConfig.options) || {};
|
|
298
|
-
return {
|
|
299
|
-
...baseOptions,
|
|
300
|
-
prefix: false
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
});
|
|
305
|
-
return nextConfig;
|
|
306
|
-
}
|
|
307
|
-
const h5OnlineStoreConfig = withH5AuthPrefix(onlineStoreConfig);
|
|
308
281
|
|
|
309
282
|
/**
|
|
310
283
|
* 默认配置(通用配置)
|
|
@@ -1093,7 +1066,6 @@ const shopWebposConfig = {
|
|
|
1093
1066
|
*/
|
|
1094
1067
|
const channelConfigMap = exports.channelConfigMap = {
|
|
1095
1068
|
'online-store': onlineStoreConfig,
|
|
1096
|
-
'online-store-h5': h5OnlineStoreConfig,
|
|
1097
1069
|
'default': defaultConfig,
|
|
1098
1070
|
'webpos': webposConfig,
|
|
1099
1071
|
'shop.webpos': shopWebposConfig
|
|
@@ -1111,16 +1083,9 @@ function getChannelConfig(channel) {
|
|
|
1111
1083
|
* 负责根据配置执行 API 调用
|
|
1112
1084
|
*/
|
|
1113
1085
|
class ApiCaller {
|
|
1114
|
-
constructor(request, config
|
|
1086
|
+
constructor(request, config) {
|
|
1115
1087
|
this.request = request;
|
|
1116
1088
|
this.config = config;
|
|
1117
|
-
this.options = options;
|
|
1118
|
-
}
|
|
1119
|
-
resolveUrl(url) {
|
|
1120
|
-
if (!this.options.baseUrl || !url.startsWith('/h5/auth/')) {
|
|
1121
|
-
return url;
|
|
1122
|
-
}
|
|
1123
|
-
return `${this.options.baseUrl.replace(/\/$/, '')}${url}`;
|
|
1124
1089
|
}
|
|
1125
1090
|
|
|
1126
1091
|
/**
|
|
@@ -1146,12 +1111,6 @@ class ApiCaller {
|
|
|
1146
1111
|
...options,
|
|
1147
1112
|
...additionalOptions
|
|
1148
1113
|
};
|
|
1149
|
-
if (apiConfig.url.startsWith('/h5/auth/') && h5CustomerAuthApiNames.has(apiName)) {
|
|
1150
|
-
requestOptions.h5CustomerAuth = true;
|
|
1151
|
-
if (this.options.shopDomain) {
|
|
1152
|
-
requestOptions.h5AuthShopDomain = this.options.shopDomain;
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
1114
|
|
|
1156
1115
|
// 处理动态 headers
|
|
1157
1116
|
if (requestOptions.headers && typeof requestOptions.headers === 'function') {
|
|
@@ -1164,19 +1123,19 @@ class ApiCaller {
|
|
|
1164
1123
|
switch (apiConfig.method) {
|
|
1165
1124
|
case 'GET':
|
|
1166
1125
|
if (transformedParams && Object.keys(transformedParams).length > 0) {
|
|
1167
|
-
response = await this.request.get(
|
|
1126
|
+
response = await this.request.get(apiConfig.url, transformedParams, requestOptions);
|
|
1168
1127
|
} else {
|
|
1169
|
-
response = await this.request.get(
|
|
1128
|
+
response = await this.request.get(apiConfig.url, undefined, requestOptions);
|
|
1170
1129
|
}
|
|
1171
1130
|
break;
|
|
1172
1131
|
case 'POST':
|
|
1173
|
-
response = await this.request.post(
|
|
1132
|
+
response = await this.request.post(apiConfig.url, transformedParams, requestOptions);
|
|
1174
1133
|
break;
|
|
1175
1134
|
case 'PUT':
|
|
1176
|
-
response = await this.request.put(
|
|
1135
|
+
response = await this.request.put(apiConfig.url, transformedParams, requestOptions);
|
|
1177
1136
|
break;
|
|
1178
1137
|
case 'DELETE':
|
|
1179
|
-
response = await this.request.delete(
|
|
1138
|
+
response = await this.request.delete(apiConfig.url, requestOptions);
|
|
1180
1139
|
break;
|
|
1181
1140
|
default:
|
|
1182
1141
|
throw new Error(`不支持的 HTTP 方法: ${apiConfig.method}`);
|
|
@@ -1191,7 +1150,7 @@ class ApiCaller {
|
|
|
1191
1150
|
* 创建 API 调用器
|
|
1192
1151
|
*/
|
|
1193
1152
|
exports.ApiCaller = ApiCaller;
|
|
1194
|
-
function createApiCaller(request, channel
|
|
1153
|
+
function createApiCaller(request, channel) {
|
|
1195
1154
|
const config = getChannelConfig(channel);
|
|
1196
|
-
return new ApiCaller(request, config
|
|
1155
|
+
return new ApiCaller(request, config);
|
|
1197
1156
|
}
|
|
@@ -227,10 +227,7 @@ class RegisterAndLoginImpl extends _BaseModule.BaseModule {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
// 创建 API 调用器
|
|
230
|
-
this.apiCaller = (0, _config.createApiCaller)(this.request, this.channel
|
|
231
|
-
baseUrl: this.otherParams.h5AuthBaseUrl,
|
|
232
|
-
shopDomain: this.otherParams.h5AuthShopDomain
|
|
233
|
-
});
|
|
230
|
+
this.apiCaller = (0, _config.createApiCaller)(this.request, this.channel);
|
|
234
231
|
|
|
235
232
|
// 尝试从本地存储恢复登录状态
|
|
236
233
|
await this.restoreLoginState();
|
|
@@ -1200,11 +1200,7 @@ class ScanOrderImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1200
1200
|
return sourceMap;
|
|
1201
1201
|
}
|
|
1202
1202
|
getItemRuleRuntimeConfig() {
|
|
1203
|
-
|
|
1204
|
-
return {
|
|
1205
|
-
...runtimeConfig,
|
|
1206
|
-
channel: runtimeConfig.channel ?? runtimeConfig.custom?.channel ?? this.otherParams?.channel
|
|
1207
|
-
};
|
|
1203
|
+
return this.itemRuleRuntimeConfig || {};
|
|
1208
1204
|
}
|
|
1209
1205
|
async ensureItemRuleConfigsLoaded() {
|
|
1210
1206
|
if (this.itemRuleConfigs.length > 0) return this.itemRuleConfigs;
|
|
@@ -333,7 +333,6 @@ function buildItemRuleBusinessData(params) {
|
|
|
333
333
|
cartItems,
|
|
334
334
|
historicalItems,
|
|
335
335
|
serviceType: runtimeConfig.serviceType || 'dine-in',
|
|
336
|
-
channel: runtimeConfig.channel ?? runtimeConfig.custom?.channel,
|
|
337
336
|
submissionIndex: typeof runtimeConfig.submissionIndex === 'number' ? toNonNegativeInt(runtimeConfig.submissionIndex) : tempOrder.order_id ? 1 : 0,
|
|
338
337
|
custom: runtimeConfig.custom || {},
|
|
339
338
|
strategyConfigs: itemRuleConfigs
|