@pisell/pisellos 0.10.3 → 0.10.4
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/BaseModule.d.ts +1 -0
- package/dist/modules/BaseModule.js +24 -28
- package/dist/modules/Order/index.d.ts +13 -2
- package/dist/modules/Order/index.js +142 -60
- package/dist/modules/Order/types.d.ts +8 -1
- package/dist/solution/BaseSales/index.d.ts +3 -1
- package/dist/solution/BaseSales/index.js +98 -81
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +1 -13
- package/dist/solution/UnifiedBookingSales/index.d.ts +3 -0
- package/dist/solution/UnifiedBookingSales/index.js +377 -309
- package/dist/solution/UnifiedBookingSales/types.d.ts +7 -0
- package/lib/model/strategy/adapter/promotion/index.js +51 -0
- package/lib/modules/BaseModule.d.ts +1 -0
- package/lib/modules/BaseModule.js +24 -37
- package/lib/modules/Order/index.d.ts +13 -2
- package/lib/modules/Order/index.js +90 -19
- package/lib/modules/Order/types.d.ts +8 -1
- package/lib/solution/BaseSales/index.d.ts +3 -1
- package/lib/solution/BaseSales/index.js +29 -16
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +1 -13
- package/lib/solution/UnifiedBookingSales/index.d.ts +3 -0
- package/lib/solution/UnifiedBookingSales/index.js +38 -0
- package/lib/solution/UnifiedBookingSales/types.d.ts +7 -0
- package/package.json +1 -1
|
@@ -11,6 +11,13 @@ export declare enum UnifiedBookingSalesHooks {
|
|
|
11
11
|
export interface UnifiedBookingSalesState extends BookingTicketState {
|
|
12
12
|
resourcePlanner: ResourcePlannerModule;
|
|
13
13
|
}
|
|
14
|
+
export interface UnifiedBookingSalesOtherParams extends Record<string, any> {
|
|
15
|
+
/**
|
|
16
|
+
* Persist the active order workspace in sessionStorage, partitioned by cacheId.
|
|
17
|
+
* Disabled by default and ignored when cacheId is missing.
|
|
18
|
+
*/
|
|
19
|
+
enableSessionStoragePersist?: boolean;
|
|
20
|
+
}
|
|
14
21
|
/** Explicit OpenData target used by page-level UnifiedBookingSales skins. */
|
|
15
22
|
export interface UnifiedBookingSalesLoadOpenDataParams {
|
|
16
23
|
businessCode: string;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/model/strategy/adapter/promotion/index.ts
|
|
30
|
+
var promotion_exports = {};
|
|
31
|
+
__export(promotion_exports, {
|
|
32
|
+
BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
|
|
33
|
+
ITEM_REWARD_STRATEGY: () => import_examples.ITEM_REWARD_STRATEGY,
|
|
34
|
+
PromotionAdapter: () => import_adapter.PromotionAdapter,
|
|
35
|
+
PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
|
|
36
|
+
X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
|
|
37
|
+
default: () => import_adapter2.default
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(promotion_exports);
|
|
40
|
+
var import_evaluator = require("./evaluator");
|
|
41
|
+
var import_adapter = require("./adapter");
|
|
42
|
+
var import_adapter2 = __toESM(require("./adapter"));
|
|
43
|
+
var import_examples = require("./examples");
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
BUY_X_GET_Y_FREE_STRATEGY,
|
|
47
|
+
ITEM_REWARD_STRATEGY,
|
|
48
|
+
PromotionAdapter,
|
|
49
|
+
PromotionEvaluator,
|
|
50
|
+
X_ITEMS_FOR_Y_PRICE_STRATEGY
|
|
51
|
+
});
|
|
@@ -8,6 +8,7 @@ export declare class BaseModule {
|
|
|
8
8
|
protected core: PisellCore;
|
|
9
9
|
constructor(name?: string, version?: string);
|
|
10
10
|
destroy(): void;
|
|
11
|
+
private isRecord;
|
|
11
12
|
checkSaveCache({ cacheId, fatherModule, store, cacheKey, }: {
|
|
12
13
|
cacheId: string | undefined;
|
|
13
14
|
fatherModule: string | undefined;
|
|
@@ -34,6 +34,9 @@ var BaseModule = class {
|
|
|
34
34
|
this.core.effects.offByModuleDestroy(this.name);
|
|
35
35
|
this.core.unregisterModule(this);
|
|
36
36
|
}
|
|
37
|
+
isRecord(value) {
|
|
38
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
39
|
+
}
|
|
37
40
|
// 提供统一的缓存 module 里的数据的方法
|
|
38
41
|
checkSaveCache({
|
|
39
42
|
cacheId,
|
|
@@ -41,45 +44,29 @@ var BaseModule = class {
|
|
|
41
44
|
store,
|
|
42
45
|
cacheKey
|
|
43
46
|
}) {
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
if (!cacheId)
|
|
48
|
+
return;
|
|
49
|
+
try {
|
|
50
|
+
const window = this.core.getPlugin("window");
|
|
51
|
+
const sessionStorage = window == null ? void 0 : window.sessionStorage;
|
|
52
|
+
if (!sessionStorage)
|
|
53
|
+
return;
|
|
54
|
+
const storageKey = fatherModule || cacheId;
|
|
55
|
+
const rawCacheData = sessionStorage.getItem(storageKey);
|
|
56
|
+
const parsedCacheData = rawCacheData ? JSON.parse(rawCacheData) : {};
|
|
57
|
+
if (!this.isRecord(parsedCacheData))
|
|
58
|
+
return;
|
|
59
|
+
const cacheBucket = fatherModule ? this.isRecord(parsedCacheData[cacheId]) ? parsedCacheData[cacheId] : {} : parsedCacheData;
|
|
60
|
+
const moduleBucket = this.isRecord(cacheBucket[this.name]) ? cacheBucket[this.name] : {};
|
|
61
|
+
cacheKey.forEach((key) => {
|
|
62
|
+
moduleBucket[key] = store == null ? void 0 : store[key];
|
|
63
|
+
});
|
|
64
|
+
cacheBucket[this.name] = moduleBucket;
|
|
46
65
|
if (fatherModule) {
|
|
47
|
-
|
|
48
|
-
let currentCacheDataObj = JSON.parse(currentCacheData || "{}");
|
|
49
|
-
if (!currentCacheData || !currentCacheDataObj[cacheId]) {
|
|
50
|
-
currentCacheDataObj = {
|
|
51
|
-
[cacheId]: {
|
|
52
|
-
[this.name]: {}
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
if (!currentCacheDataObj[cacheId][this.name]) {
|
|
57
|
-
currentCacheDataObj[cacheId][this.name] = {};
|
|
58
|
-
}
|
|
59
|
-
cacheKey.forEach((key) => {
|
|
60
|
-
currentCacheDataObj[cacheId][this.name][key] = store == null ? void 0 : store[key];
|
|
61
|
-
});
|
|
62
|
-
window.sessionStorage.setItem(
|
|
63
|
-
fatherModule,
|
|
64
|
-
JSON.stringify(currentCacheDataObj)
|
|
65
|
-
);
|
|
66
|
-
} else {
|
|
67
|
-
let currentCacheData = window.sessionStorage.getItem(cacheId);
|
|
68
|
-
let currentCacheDataObj = JSON.parse(currentCacheData || "{}");
|
|
69
|
-
if (!currentCacheDataObj) {
|
|
70
|
-
currentCacheDataObj = {};
|
|
71
|
-
}
|
|
72
|
-
if (!currentCacheDataObj[this.name]) {
|
|
73
|
-
currentCacheDataObj[this.name] = {};
|
|
74
|
-
}
|
|
75
|
-
cacheKey.forEach((key) => {
|
|
76
|
-
currentCacheDataObj[this.name][key] = store[key];
|
|
77
|
-
});
|
|
78
|
-
window.sessionStorage.setItem(
|
|
79
|
-
cacheId,
|
|
80
|
-
JSON.stringify(currentCacheDataObj)
|
|
81
|
-
);
|
|
66
|
+
parsedCacheData[cacheId] = cacheBucket;
|
|
82
67
|
}
|
|
68
|
+
sessionStorage.setItem(storageKey, JSON.stringify(parsedCacheData));
|
|
69
|
+
} catch {
|
|
83
70
|
}
|
|
84
71
|
}
|
|
85
72
|
effectsOn(eventType, callback) {
|
|
@@ -16,6 +16,10 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
16
16
|
private window;
|
|
17
17
|
private appPlugin;
|
|
18
18
|
private cacheId;
|
|
19
|
+
private fatherModule;
|
|
20
|
+
private openCache;
|
|
21
|
+
private sessionStoragePersistEnabled;
|
|
22
|
+
private sessionStorageRestoreRecord;
|
|
19
23
|
private salesSummaryModuleName;
|
|
20
24
|
private rulesHooksOverride?;
|
|
21
25
|
private moduleHooksOverride?;
|
|
@@ -46,6 +50,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
46
50
|
static populateSavedAmounts(productList: Array<Record<string, any>>, discountList: Array<Record<string, any>>): void;
|
|
47
51
|
private applyProductDiscountPrices;
|
|
48
52
|
constructor(name?: string, version?: string);
|
|
53
|
+
private syncSessionStorageOptions;
|
|
49
54
|
initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
|
|
50
55
|
destroy(): Promise<void>;
|
|
51
56
|
/**
|
|
@@ -137,7 +142,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
137
142
|
}): void;
|
|
138
143
|
/**
|
|
139
144
|
* 控制 IndexedDB 草稿(saveDraft)是否写入。
|
|
140
|
-
*
|
|
145
|
+
* 此开关仅影响 saveDraft;可选 sessionStorage 会话恢复由
|
|
146
|
+
* enableSessionStoragePersist 独立控制。
|
|
141
147
|
*
|
|
142
148
|
* @example
|
|
143
149
|
* order.setEnableTempOrderPersist(false); // BigSale 弹窗:跳过 ~1s 的 dbUpdate
|
|
@@ -145,8 +151,12 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
145
151
|
setEnableTempOrderPersist(enabled: boolean): void;
|
|
146
152
|
/** 是否允许 saveDraft 写入 IndexedDB 草稿。 */
|
|
147
153
|
isTempOrderPersistEnabled(): boolean;
|
|
148
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* 在 UnifiedBookingSales 显式开启会话恢复时,将完整 tempOrder 写入
|
|
156
|
+
* sessionStorage 的 cacheId 分桶。写入失败由 BaseModule 静默降级。
|
|
157
|
+
*/
|
|
149
158
|
persistTempOrder(): void;
|
|
159
|
+
consumeSessionStorageRestore(): Record<string, any> | null;
|
|
150
160
|
notifyTempOrderChanged(): void;
|
|
151
161
|
private createDefaultTempOrderInstance;
|
|
152
162
|
private createExternalSaleNumber;
|
|
@@ -537,6 +547,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
|
|
|
537
547
|
*/
|
|
538
548
|
hydrateTempOrderFromRecord(record: Record<string, any>, options?: {
|
|
539
549
|
recalcOnHydrate?: boolean;
|
|
550
|
+
source?: 'salesDetail' | 'sessionStorage';
|
|
540
551
|
}): Promise<OrderTempOrder>;
|
|
541
552
|
/**
|
|
542
553
|
* 兼容后端详情将 holder 放在 metadata.holder 的历史形态,统一补到运行时展示路径。
|
|
@@ -113,6 +113,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
113
113
|
super(name || "order", version);
|
|
114
114
|
this.defaultName = "order";
|
|
115
115
|
this.defaultVersion = "1.0.0";
|
|
116
|
+
this.openCache = false;
|
|
117
|
+
this.sessionStoragePersistEnabled = false;
|
|
118
|
+
this.sessionStorageRestoreRecord = null;
|
|
116
119
|
// ─── 促销/赠品 ────────────────────────────────────
|
|
117
120
|
/** 评估器引用;由 SalesSdkProvider 注入,未注入时 applyPromotion 静默跳过 */
|
|
118
121
|
this.promotionEvaluator = null;
|
|
@@ -327,11 +330,32 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
327
330
|
return product;
|
|
328
331
|
});
|
|
329
332
|
}
|
|
333
|
+
syncSessionStorageOptions(otherParams) {
|
|
334
|
+
this.cacheId = otherParams.cacheId;
|
|
335
|
+
this.fatherModule = otherParams.fatherModule;
|
|
336
|
+
this.openCache = Boolean(
|
|
337
|
+
this.cacheId && otherParams.openCache !== false
|
|
338
|
+
);
|
|
339
|
+
this.sessionStoragePersistEnabled = Boolean(
|
|
340
|
+
this.openCache && otherParams.enableSessionStoragePersist === true
|
|
341
|
+
);
|
|
342
|
+
}
|
|
330
343
|
async initialize(core, options) {
|
|
331
344
|
var _a, _b, _c, _d;
|
|
332
345
|
this.core = core;
|
|
333
346
|
this.store = options.store;
|
|
334
|
-
|
|
347
|
+
const otherParams = options.otherParams || {};
|
|
348
|
+
this.syncSessionStorageOptions(otherParams);
|
|
349
|
+
if (this.sessionStoragePersistEnabled) {
|
|
350
|
+
const cachedTempOrder = this.store.tempOrder;
|
|
351
|
+
this.sessionStorageRestoreRecord = (0, import_utils.isTempOrder)(cachedTempOrder) ? (0, import_lodash_es.cloneDeep)(cachedTempOrder) : null;
|
|
352
|
+
this.store.tempOrder = null;
|
|
353
|
+
this.store.summary = (0, import_utils.createEmptySummary)();
|
|
354
|
+
this.store.availableWalletIds = [];
|
|
355
|
+
this.store.lastOrderInfo = void 0;
|
|
356
|
+
this.store.syncState = void 0;
|
|
357
|
+
this.store.discountList = [];
|
|
358
|
+
} else if (!this.store.tempOrder) {
|
|
335
359
|
this.store.tempOrder = null;
|
|
336
360
|
}
|
|
337
361
|
if (!this.store.summary) {
|
|
@@ -348,8 +372,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
348
372
|
const app = (_a = appPlugin == null ? void 0 : appPlugin.getApp) == null ? void 0 : _a.call(appPlugin);
|
|
349
373
|
this.logger = app == null ? void 0 : app.logger;
|
|
350
374
|
this.window = this.core.getPlugin("window");
|
|
351
|
-
const otherParams = options.otherParams || {};
|
|
352
|
-
this.cacheId = otherParams.cacheId;
|
|
353
375
|
this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
|
|
354
376
|
this.rulesHooksOverride = (_b = otherParams.rules) == null ? void 0 : _b.hooks;
|
|
355
377
|
this.moduleHooksOverride = options.hooks;
|
|
@@ -360,6 +382,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
360
382
|
}
|
|
361
383
|
async destroy() {
|
|
362
384
|
var _a, _b;
|
|
385
|
+
this.sessionStorageRestoreRecord = null;
|
|
363
386
|
const childModules = [(_a = this.store) == null ? void 0 : _a.discount, (_b = this.store) == null ? void 0 : _b.rules];
|
|
364
387
|
for (const childModule of childModules) {
|
|
365
388
|
if (!childModule || typeof childModule.destroy !== "function")
|
|
@@ -389,7 +412,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
389
412
|
updateOtherParams(params) {
|
|
390
413
|
var _a, _b, _c;
|
|
391
414
|
const otherParams = params || {};
|
|
392
|
-
this.
|
|
415
|
+
this.syncSessionStorageOptions(otherParams);
|
|
393
416
|
this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
|
|
394
417
|
this.rulesHooksOverride = (_a = otherParams.rules) == null ? void 0 : _a.hooks;
|
|
395
418
|
this.orderHooks = this.moduleHooksOverride || ((_b = otherParams.order) == null ? void 0 : _b.hooks) || ((_c = otherParams.hooks) == null ? void 0 : _c.order);
|
|
@@ -434,14 +457,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
434
457
|
// ─── Discount: 子模块注册 ───
|
|
435
458
|
registerDiscountModules(options) {
|
|
436
459
|
let targetCacheData = {};
|
|
437
|
-
if (this.cacheId && this.window) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
460
|
+
if (!this.sessionStoragePersistEnabled && this.openCache && this.cacheId && this.window) {
|
|
461
|
+
try {
|
|
462
|
+
const sessionData = this.window.sessionStorage.getItem(this.name);
|
|
463
|
+
if (sessionData) {
|
|
441
464
|
const data = JSON.parse(sessionData);
|
|
442
465
|
targetCacheData = (data == null ? void 0 : data[this.cacheId]) || {};
|
|
443
|
-
} catch {
|
|
444
466
|
}
|
|
467
|
+
} catch {
|
|
445
468
|
}
|
|
446
469
|
}
|
|
447
470
|
const discount = new import_Discount.DiscountModule(`${this.name}_discount`);
|
|
@@ -449,7 +472,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
449
472
|
initialState: targetCacheData == null ? void 0 : targetCacheData[discount.name],
|
|
450
473
|
otherParams: {
|
|
451
474
|
fatherModule: this.name,
|
|
452
|
-
|
|
475
|
+
// Unified 的单快照由 Order 管理;其他 Solution 保持原有 Discount 缓存语义。
|
|
476
|
+
openCache: this.openCache && !this.sessionStoragePersistEnabled,
|
|
453
477
|
cacheId: this.cacheId
|
|
454
478
|
}
|
|
455
479
|
});
|
|
@@ -865,7 +889,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
865
889
|
}
|
|
866
890
|
/**
|
|
867
891
|
* 控制 IndexedDB 草稿(saveDraft)是否写入。
|
|
868
|
-
*
|
|
892
|
+
* 此开关仅影响 saveDraft;可选 sessionStorage 会话恢复由
|
|
893
|
+
* enableSessionStoragePersist 独立控制。
|
|
869
894
|
*
|
|
870
895
|
* @example
|
|
871
896
|
* order.setEnableTempOrderPersist(false); // BigSale 弹窗:跳过 ~1s 的 dbUpdate
|
|
@@ -877,8 +902,24 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
877
902
|
isTempOrderPersistEnabled() {
|
|
878
903
|
return this.draftPersistEnabled;
|
|
879
904
|
}
|
|
880
|
-
/**
|
|
905
|
+
/**
|
|
906
|
+
* 在 UnifiedBookingSales 显式开启会话恢复时,将完整 tempOrder 写入
|
|
907
|
+
* sessionStorage 的 cacheId 分桶。写入失败由 BaseModule 静默降级。
|
|
908
|
+
*/
|
|
881
909
|
persistTempOrder() {
|
|
910
|
+
if (!this.sessionStoragePersistEnabled || !this.store.tempOrder)
|
|
911
|
+
return;
|
|
912
|
+
this.checkSaveCache({
|
|
913
|
+
cacheId: this.cacheId,
|
|
914
|
+
fatherModule: this.fatherModule,
|
|
915
|
+
store: { tempOrder: this.store.tempOrder },
|
|
916
|
+
cacheKey: ["tempOrder"]
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
consumeSessionStorageRestore() {
|
|
920
|
+
const record = this.sessionStorageRestoreRecord;
|
|
921
|
+
this.sessionStorageRestoreRecord = null;
|
|
922
|
+
return record ? (0, import_lodash_es.cloneDeep)(record) : null;
|
|
882
923
|
}
|
|
883
924
|
notifyTempOrderChanged() {
|
|
884
925
|
if (!this.store.tempOrder)
|
|
@@ -1733,6 +1774,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1733
1774
|
restoreOrder() {
|
|
1734
1775
|
var _a, _b;
|
|
1735
1776
|
this.logInfo("restoreOrder start", {});
|
|
1777
|
+
this.sessionStorageRestoreRecord = null;
|
|
1736
1778
|
const freshTempOrder = this.createDefaultTempOrderInstance();
|
|
1737
1779
|
this.ensureExternalSaleNumber(freshTempOrder);
|
|
1738
1780
|
this.store.tempOrder = freshTempOrder;
|
|
@@ -1751,6 +1793,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
1751
1793
|
if (!(0, import_utils.isTempOrder)(tempOrder)) {
|
|
1752
1794
|
throw new Error("无效的 tempOrder 数据");
|
|
1753
1795
|
}
|
|
1796
|
+
this.sessionStorageRestoreRecord = null;
|
|
1754
1797
|
const nextTempOrder = this.normalizeTempOrderForRuntime(
|
|
1755
1798
|
(0, import_lodash_es.cloneDeep)(tempOrder),
|
|
1756
1799
|
{ ensureIdentity: false }
|
|
@@ -4257,7 +4300,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4257
4300
|
* 例如数组字段、商品行唯一值、价格 metadata、summary 派生状态和 _extend。
|
|
4258
4301
|
*/
|
|
4259
4302
|
async hydrateTempOrderFromRecord(record, options) {
|
|
4260
|
-
var _a, _b, _c;
|
|
4303
|
+
var _a, _b, _c, _d, _e;
|
|
4261
4304
|
const sourceRaw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
|
|
4262
4305
|
const identityReadySource = this.seedAnonymousBookingUidsFromProducts(
|
|
4263
4306
|
sourceRaw
|
|
@@ -4287,8 +4330,37 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4287
4330
|
);
|
|
4288
4331
|
}
|
|
4289
4332
|
}
|
|
4290
|
-
const
|
|
4291
|
-
const
|
|
4333
|
+
const isSessionStorageHydrate = (options == null ? void 0 : options.source) === "sessionStorage";
|
|
4334
|
+
const nextTempOrder = this.normalizeTempOrderForRuntime(raw, {
|
|
4335
|
+
makeEditMark: !isSessionStorageHydrate
|
|
4336
|
+
});
|
|
4337
|
+
this.store.tempOrder = nextTempOrder;
|
|
4338
|
+
if (isSessionStorageHydrate) {
|
|
4339
|
+
const restoredSessionDiscounts = Array.isArray(raw.discount_list) ? (0, import_lodash_es.cloneDeep)(raw.discount_list) : [];
|
|
4340
|
+
const nextExtend = { ...nextTempOrder._extend || {} };
|
|
4341
|
+
delete nextExtend.originalSalesSnapshot;
|
|
4342
|
+
nextTempOrder._extend = nextExtend;
|
|
4343
|
+
nextTempOrder.products.forEach((product) => {
|
|
4344
|
+
if (product.metadata) {
|
|
4345
|
+
delete product.metadata.is_edit_for_runtime;
|
|
4346
|
+
}
|
|
4347
|
+
});
|
|
4348
|
+
nextTempOrder.discount_list = restoredSessionDiscounts;
|
|
4349
|
+
this.store.summary = (0, import_utils.createEmptySummary)();
|
|
4350
|
+
this.store.lastOrderInfo = void 0;
|
|
4351
|
+
await ((_a = this.store.discount) == null ? void 0 : _a.setOriginalDiscountList(
|
|
4352
|
+
(0, import_lodash_es.cloneDeep)(restoredSessionDiscounts)
|
|
4353
|
+
));
|
|
4354
|
+
await ((_b = this.store.discount) == null ? void 0 : _b.setDiscountList(
|
|
4355
|
+
(0, import_lodash_es.cloneDeep)(restoredSessionDiscounts)
|
|
4356
|
+
));
|
|
4357
|
+
if (options == null ? void 0 : options.recalcOnHydrate) {
|
|
4358
|
+
await this.recalculateSummary({ createIfMissing: false });
|
|
4359
|
+
}
|
|
4360
|
+
this.persistTempOrder();
|
|
4361
|
+
return nextTempOrder;
|
|
4362
|
+
}
|
|
4363
|
+
const sourceLastOrderInfo = sourceRaw.lastOrderInfo || sourceRaw;
|
|
4292
4364
|
const isDraftOrder = Number(nextTempOrder.is_draft_order || 0) === 1;
|
|
4293
4365
|
const syntheticIdentityOptions = {
|
|
4294
4366
|
isDraftOrder,
|
|
@@ -4296,7 +4368,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4296
4368
|
};
|
|
4297
4369
|
const rawSummary = raw.summary && typeof raw.summary === "object" ? raw.summary : {};
|
|
4298
4370
|
const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map((s) => ({ ...s || {} })) : (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []);
|
|
4299
|
-
this.store.tempOrder = nextTempOrder;
|
|
4300
4371
|
this.store.summary = {
|
|
4301
4372
|
...(0, import_utils.createEmptySummary)(),
|
|
4302
4373
|
...rawSummary,
|
|
@@ -4323,7 +4394,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4323
4394
|
this.store.syncState = "local";
|
|
4324
4395
|
}
|
|
4325
4396
|
const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
|
|
4326
|
-
const currentDiscounts = typeof ((
|
|
4397
|
+
const currentDiscounts = typeof ((_c = this.store.discount) == null ? void 0 : _c.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
|
|
4327
4398
|
const currentScanDiscounts = currentDiscounts.filter((discount) => discount == null ? void 0 : discount.isScan);
|
|
4328
4399
|
const hydratedDiscountIds = new Set(
|
|
4329
4400
|
hydratedEditDiscounts.map((discount) => discount == null ? void 0 : discount.id)
|
|
@@ -4341,8 +4412,8 @@ var OrderModule = class extends import_BaseModule.BaseModule {
|
|
|
4341
4412
|
nextTempOrder.products,
|
|
4342
4413
|
nextDiscounts
|
|
4343
4414
|
);
|
|
4344
|
-
await ((
|
|
4345
|
-
await ((
|
|
4415
|
+
await ((_d = this.store.discount) == null ? void 0 : _d.setOriginalDiscountList(nextDiscounts));
|
|
4416
|
+
await ((_e = this.store.discount) == null ? void 0 : _e.setDiscountList(nextDiscounts));
|
|
4346
4417
|
}
|
|
4347
4418
|
if (options == null ? void 0 : options.recalcOnHydrate) {
|
|
4348
4419
|
await this.recalculateSummary({ createIfMissing: false });
|
|
@@ -561,6 +561,10 @@ export interface LoadSalesDetailParams {
|
|
|
561
561
|
* 存在时 loadSalesDetail 会跳过远端 lookup,直接复用 hydrate 后半段逻辑。
|
|
562
562
|
*/
|
|
563
563
|
preloadedSalesDetail?: Record<string, any>;
|
|
564
|
+
/**
|
|
565
|
+
* sessionStorage 快照复用详情 hydrate 时使用;不带该值时保持既有编辑订单语义。
|
|
566
|
+
*/
|
|
567
|
+
hydrateSource?: 'sessionStorage';
|
|
564
568
|
forceRemote?: boolean;
|
|
565
569
|
merge?: boolean;
|
|
566
570
|
}
|
|
@@ -731,8 +735,10 @@ export interface OrderModuleAPI {
|
|
|
731
735
|
removeProductFromOrder: (identity: OrderProductIdentity) => Promise<OrderProduct[]>;
|
|
732
736
|
/** 批量删除购物车行,末尾仅触发一次促销重算与 summary 刷新 */
|
|
733
737
|
removeProductsFromOrder: (identities: OrderProductIdentity[]) => Promise<OrderProduct[]>;
|
|
734
|
-
/**
|
|
738
|
+
/** 在显式开启时保存当前 tempOrder 的 sessionStorage 会话快照。 */
|
|
735
739
|
persistTempOrder: () => void;
|
|
740
|
+
/** 取出一次待恢复的 sessionStorage tempOrder 快照。 */
|
|
741
|
+
consumeSessionStorageRestore: () => Record<string, any> | null;
|
|
736
742
|
/**
|
|
737
743
|
* 控制 IndexedDB 草稿(saveDraft)开关;localStorage tempOrder 持久化已废弃。
|
|
738
744
|
* BigSale 弹窗等场景传 false 可跳过 saveDraft。
|
|
@@ -790,6 +796,7 @@ export interface OrderModuleAPI {
|
|
|
790
796
|
saveDraft: () => Promise<void>;
|
|
791
797
|
hydrateTempOrderFromRecord: (record: Record<string, any>, options?: {
|
|
792
798
|
recalcOnHydrate?: boolean;
|
|
799
|
+
source?: 'salesDetail' | 'sessionStorage';
|
|
793
800
|
}) => Promise<OrderTempOrder>;
|
|
794
801
|
syncPaymentsToOrder: <T = any>(params: SyncPaymentsToOrderParams) => Promise<SyncPaymentsToOrderResult<T>>;
|
|
795
802
|
getSalesOrderByLookup: (params: SalesOrderLookupParams) => Promise<any>;
|
|
@@ -131,7 +131,9 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
|
|
|
131
131
|
* const params = this.buildSubModuleOtherParams();
|
|
132
132
|
* this.core.registerModule(orderModule, { otherParams: params });
|
|
133
133
|
*/
|
|
134
|
-
protected
|
|
134
|
+
protected isSessionStoragePersistEnabled(): boolean;
|
|
135
|
+
protected shouldUseSessionStorageForSubModule(_moduleName?: string): boolean;
|
|
136
|
+
protected buildSubModuleOtherParams(moduleName?: string): Record<string, any>;
|
|
135
137
|
/**
|
|
136
138
|
* 将父级 otherParams 的变更显式同步给已注册的子模块。
|
|
137
139
|
*
|
|
@@ -588,7 +588,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
588
588
|
});
|
|
589
589
|
});
|
|
590
590
|
}
|
|
591
|
-
async hydrateLatestLoadedSalesDetail(record, loadSequence) {
|
|
591
|
+
async hydrateLatestLoadedSalesDetail(record, loadSequence, hydrateSource) {
|
|
592
592
|
let hydratedSales = null;
|
|
593
593
|
let skippedBeforeHydrate = false;
|
|
594
594
|
const hydrateTask = async () => {
|
|
@@ -598,9 +598,10 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
598
598
|
}
|
|
599
599
|
if (!this.store.order)
|
|
600
600
|
throw new Error("order 模块未初始化");
|
|
601
|
-
const sales = await this.store.order.hydrateTempOrderFromRecord(
|
|
602
|
-
|
|
603
|
-
|
|
601
|
+
const sales = await this.store.order.hydrateTempOrderFromRecord(
|
|
602
|
+
record,
|
|
603
|
+
hydrateSource === "sessionStorage" ? { recalcOnHydrate: true, source: "sessionStorage" } : { recalcOnHydrate: false }
|
|
604
|
+
);
|
|
604
605
|
hydratedSales = sales;
|
|
605
606
|
if (loadSequence !== this.salesDetailLoadSequence)
|
|
606
607
|
return;
|
|
@@ -891,12 +892,18 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
891
892
|
* const params = this.buildSubModuleOtherParams();
|
|
892
893
|
* this.core.registerModule(orderModule, { otherParams: params });
|
|
893
894
|
*/
|
|
894
|
-
|
|
895
|
+
isSessionStoragePersistEnabled() {
|
|
896
|
+
return Boolean(this.cacheId);
|
|
897
|
+
}
|
|
898
|
+
shouldUseSessionStorageForSubModule(_moduleName) {
|
|
899
|
+
return this.isSessionStoragePersistEnabled();
|
|
900
|
+
}
|
|
901
|
+
buildSubModuleOtherParams(moduleName) {
|
|
895
902
|
return {
|
|
896
903
|
...this.otherParams,
|
|
897
904
|
salesSummaryModuleName: `${this.name}_salesSummary`,
|
|
898
905
|
fatherModule: this.name,
|
|
899
|
-
openCache: this.
|
|
906
|
+
openCache: this.shouldUseSessionStorageForSubModule(moduleName),
|
|
900
907
|
cacheId: this.cacheId
|
|
901
908
|
};
|
|
902
909
|
}
|
|
@@ -907,7 +914,6 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
907
914
|
* await this.syncOtherParamsToSubModules({ channel: 'pos' });
|
|
908
915
|
*/
|
|
909
916
|
async syncOtherParamsToSubModules(changedParams, { cover = false } = {}) {
|
|
910
|
-
const nextSubModuleOtherParams = this.buildSubModuleOtherParams();
|
|
911
917
|
await Promise.all(
|
|
912
918
|
Object.entries(this.store).map(async ([moduleName, subModule]) => {
|
|
913
919
|
if (this.reusedSharedSubModuleNames.has(moduleName)) {
|
|
@@ -917,6 +923,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
917
923
|
if (!targetModule || typeof targetModule.updateOtherParams !== "function") {
|
|
918
924
|
return;
|
|
919
925
|
}
|
|
926
|
+
const nextSubModuleOtherParams = this.buildSubModuleOtherParams(moduleName);
|
|
920
927
|
await targetModule.updateOtherParams(nextSubModuleOtherParams, {
|
|
921
928
|
changedParams,
|
|
922
929
|
cover
|
|
@@ -929,14 +936,16 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
929
936
|
* sessionStorage 损坏时静默忽略,按空状态注册。
|
|
930
937
|
*/
|
|
931
938
|
readSessionCacheData() {
|
|
932
|
-
|
|
939
|
+
const cacheId = this.cacheId;
|
|
940
|
+
if (!cacheId || !this.isSessionStoragePersistEnabled() || !this.window) {
|
|
933
941
|
return {};
|
|
942
|
+
}
|
|
934
943
|
try {
|
|
935
944
|
const sessionData = this.window.sessionStorage.getItem(this.name);
|
|
936
945
|
if (!sessionData)
|
|
937
946
|
return {};
|
|
938
947
|
const data = JSON.parse(sessionData);
|
|
939
|
-
return data && data[
|
|
948
|
+
return data && data[cacheId] || {};
|
|
940
949
|
} catch {
|
|
941
950
|
return {};
|
|
942
951
|
}
|
|
@@ -1038,9 +1047,9 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1038
1047
|
const hooks = this.getSubModuleHooks(step);
|
|
1039
1048
|
this.store[step] = targetModule;
|
|
1040
1049
|
this.core.registerModule(targetModule, {
|
|
1041
|
-
initialState: (targetCacheData == null ? void 0 : targetCacheData[targetModule.name]) || {},
|
|
1050
|
+
initialState: this.shouldUseSessionStorageForSubModule(step) ? (targetCacheData == null ? void 0 : targetCacheData[targetModule.name]) || {} : {},
|
|
1042
1051
|
...hooks ? { hooks } : {},
|
|
1043
|
-
otherParams: this.buildSubModuleOtherParams()
|
|
1052
|
+
otherParams: this.buildSubModuleOtherParams(step)
|
|
1044
1053
|
});
|
|
1045
1054
|
});
|
|
1046
1055
|
if (this.store.schedule && !this.isScheduleListLoaded(this.store.schedule)) {
|
|
@@ -1107,17 +1116,21 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
|
|
|
1107
1116
|
const message = loadedRecord && (loadedRecord.message || loadedRecord.msg) || `加载销售详情失败: ${lookup}`;
|
|
1108
1117
|
throw new Error(message);
|
|
1109
1118
|
}
|
|
1110
|
-
const
|
|
1111
|
-
|
|
1112
|
-
);
|
|
1119
|
+
const loadedSalesDetail = preloadedSalesDetail ?? loadedRecord.data;
|
|
1120
|
+
const shouldFilterPendingPayments = params.hydrateSource !== "sessionStorage";
|
|
1121
|
+
const remoteRecord = shouldFilterPendingPayments ? filterPendingPaymentsFromLoadedSalesDetail(loadedSalesDetail) : loadedSalesDetail;
|
|
1113
1122
|
const currentTempOrder = params.merge ? this.store.order.getTempOrder() : null;
|
|
1114
1123
|
const mergedRecord = params.merge ? mergeSalesDetailRecordWithTempOrder(
|
|
1115
1124
|
currentTempOrder,
|
|
1116
1125
|
remoteRecord,
|
|
1117
1126
|
"preserve-local"
|
|
1118
1127
|
) : remoteRecord;
|
|
1119
|
-
const record = filterPendingPaymentsFromLoadedSalesDetail(mergedRecord);
|
|
1120
|
-
return await this.hydrateLatestLoadedSalesDetail(
|
|
1128
|
+
const record = shouldFilterPendingPayments ? filterPendingPaymentsFromLoadedSalesDetail(mergedRecord) : mergedRecord;
|
|
1129
|
+
return await this.hydrateLatestLoadedSalesDetail(
|
|
1130
|
+
record,
|
|
1131
|
+
loadSequence,
|
|
1132
|
+
params.hydrateSource
|
|
1133
|
+
);
|
|
1121
1134
|
} finally {
|
|
1122
1135
|
this.salesDetailLoadInFlightCount = Math.max(
|
|
1123
1136
|
0,
|
|
@@ -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 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
330
330
|
}[]>;
|
|
331
331
|
submitTimeSlot(timeSlots: TimeSliceItem): void;
|
|
332
332
|
private getScheduleDataByIds;
|
|
@@ -445,19 +445,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
|
|
|
445
445
|
* 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
|
|
446
446
|
* 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
|
|
447
447
|
*/
|
|
448
|
-
decideAddProduct(item: any, options?: Partial<AddProductDecideContext>):
|
|
449
|
-
action: "reloadCatalog";
|
|
450
|
-
} | {
|
|
451
|
-
action: "add";
|
|
452
|
-
cacheItem: any;
|
|
453
|
-
} | {
|
|
454
|
-
action: "requiresDetail";
|
|
455
|
-
payload: AddProductRequiresDetailPayload;
|
|
456
|
-
} | {
|
|
457
|
-
action: "requiresBookingEdit";
|
|
458
|
-
cacheItem: any;
|
|
459
|
-
payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
|
|
460
|
-
};
|
|
448
|
+
decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
|
|
461
449
|
/** 规格弹窗 callback 后的第二段决策。 */
|
|
462
450
|
decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
|
|
463
451
|
/**
|
|
@@ -63,6 +63,8 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
63
63
|
private openDataTarget;
|
|
64
64
|
private loadOpenDataInFlight;
|
|
65
65
|
private loadOpenDataInFlightTarget;
|
|
66
|
+
protected isSessionStoragePersistEnabled(): boolean;
|
|
67
|
+
protected shouldUseSessionStorageForSubModule(moduleName?: string): boolean;
|
|
66
68
|
/**
|
|
67
69
|
* Kiosk 不能把已收款订单留在本地等待重试:默认直接等待云端 checkout。
|
|
68
70
|
* 兼容仍需要 WebPOS 待同步模式的入口可显式传 checkoutSyncTaskEnabled: true。
|
|
@@ -72,6 +74,7 @@ export declare class UnifiedBookingSalesImpl extends BookingTicket {
|
|
|
72
74
|
protected getDefaultCheckoutSmallTicketDataFlag(): number;
|
|
73
75
|
protected getRegisteredModuleNames(): readonly string[];
|
|
74
76
|
protected createSubModule(moduleName: string): Module | null;
|
|
77
|
+
addNewOrder(): Promise<import("../../modules/Order/types").OrderTempOrder>;
|
|
75
78
|
/**
|
|
76
79
|
* Loads OpenData without borrowing BookingTicket. Cache ownership is tied to the exact
|
|
77
80
|
* business/channel target so a reused solution instance cannot leak another entry's menus.
|