@pisell/pisellos 0.10.3 → 0.10.5

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.
@@ -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;
@@ -23,45 +23,41 @@ export var BaseModule = /*#__PURE__*/function () {
23
23
  this.core.effects.offByModuleDestroy(this.name);
24
24
  this.core.unregisterModule(this);
25
25
  }
26
+ }, {
27
+ key: "isRecord",
28
+ value: function isRecord(value) {
29
+ return !!value && _typeof(value) === 'object' && !Array.isArray(value);
30
+ }
26
31
 
27
32
  // 提供统一的缓存 module 里的数据的方法
28
33
  }, {
29
34
  key: "checkSaveCache",
30
35
  value: function checkSaveCache(_ref) {
31
- var _this = this;
32
36
  var cacheId = _ref.cacheId,
33
37
  fatherModule = _ref.fatherModule,
34
38
  store = _ref.store,
35
39
  cacheKey = _ref.cacheKey;
36
- var window = this.core.getPlugin('window');
37
- if (cacheId) {
40
+ if (!cacheId) return;
41
+ try {
42
+ var window = this.core.getPlugin('window');
43
+ var sessionStorage = window === null || window === void 0 ? void 0 : window.sessionStorage;
44
+ if (!sessionStorage) return;
45
+ var storageKey = fatherModule || cacheId;
46
+ var rawCacheData = sessionStorage.getItem(storageKey);
47
+ var parsedCacheData = rawCacheData ? JSON.parse(rawCacheData) : {};
48
+ if (!this.isRecord(parsedCacheData)) return;
49
+ var cacheBucket = fatherModule ? this.isRecord(parsedCacheData[cacheId]) ? parsedCacheData[cacheId] : {} : parsedCacheData;
50
+ var moduleBucket = this.isRecord(cacheBucket[this.name]) ? cacheBucket[this.name] : {};
51
+ cacheKey.forEach(function (key) {
52
+ moduleBucket[key] = store === null || store === void 0 ? void 0 : store[key];
53
+ });
54
+ cacheBucket[this.name] = moduleBucket;
38
55
  if (fatherModule) {
39
- var currentCacheData = window.sessionStorage.getItem(fatherModule);
40
- var currentCacheDataObj = JSON.parse(currentCacheData || '{}');
41
- if (!currentCacheData || !currentCacheDataObj[cacheId]) {
42
- currentCacheDataObj = _defineProperty({}, cacheId, _defineProperty({}, this.name, {}));
43
- }
44
- if (!currentCacheDataObj[cacheId][this.name]) {
45
- currentCacheDataObj[cacheId][this.name] = {};
46
- }
47
- cacheKey.forEach(function (key) {
48
- currentCacheDataObj[cacheId][_this.name][key] = store === null || store === void 0 ? void 0 : store[key];
49
- });
50
- window.sessionStorage.setItem(fatherModule, JSON.stringify(currentCacheDataObj));
51
- } else {
52
- var _currentCacheData = window.sessionStorage.getItem(cacheId);
53
- var _currentCacheDataObj2 = JSON.parse(_currentCacheData || '{}');
54
- if (!_currentCacheDataObj2) {
55
- _currentCacheDataObj2 = {};
56
- }
57
- if (!_currentCacheDataObj2[this.name]) {
58
- _currentCacheDataObj2[this.name] = {};
59
- }
60
- cacheKey.forEach(function (key) {
61
- _currentCacheDataObj2[_this.name][key] = store[key];
62
- });
63
- window.sessionStorage.setItem(cacheId, JSON.stringify(_currentCacheDataObj2));
56
+ parsedCacheData[cacheId] = cacheBucket;
64
57
  }
58
+ sessionStorage.setItem(storageKey, JSON.stringify(parsedCacheData));
59
+ } catch (_unused) {
60
+ // sessionStorage persistence is best-effort and must not block checkout.
65
61
  }
66
62
  }
67
63
  }, {
@@ -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
- * localStorage tempOrder 持久化已废弃,此方法仅影响 saveDraft。
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
- /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化;草稿保存请使用 IndexedDB saveDraft。 */
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 的历史形态,统一补到运行时展示路径。
@@ -121,6 +121,10 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
121
121
  _defineProperty(_assertThisInitialized(_this), "window", void 0);
122
122
  _defineProperty(_assertThisInitialized(_this), "appPlugin", void 0);
123
123
  _defineProperty(_assertThisInitialized(_this), "cacheId", void 0);
124
+ _defineProperty(_assertThisInitialized(_this), "fatherModule", void 0);
125
+ _defineProperty(_assertThisInitialized(_this), "openCache", false);
126
+ _defineProperty(_assertThisInitialized(_this), "sessionStoragePersistEnabled", false);
127
+ _defineProperty(_assertThisInitialized(_this), "sessionStorageRestoreRecord", null);
124
128
  _defineProperty(_assertThisInitialized(_this), "salesSummaryModuleName", void 0);
125
129
  _defineProperty(_assertThisInitialized(_this), "rulesHooksOverride", void 0);
126
130
  _defineProperty(_assertThisInitialized(_this), "moduleHooksOverride", void 0);
@@ -305,18 +309,38 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
305
309
  return product;
306
310
  });
307
311
  }
312
+ }, {
313
+ key: "syncSessionStorageOptions",
314
+ value: function syncSessionStorageOptions(otherParams) {
315
+ this.cacheId = otherParams.cacheId;
316
+ this.fatherModule = otherParams.fatherModule;
317
+ this.openCache = Boolean(this.cacheId && otherParams.openCache !== false);
318
+ this.sessionStoragePersistEnabled = Boolean(this.openCache && otherParams.enableSessionStoragePersist === true);
319
+ }
308
320
  }, {
309
321
  key: "initialize",
310
322
  value: function () {
311
323
  var _initialize = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(core, options) {
312
324
  var _appPlugin$getApp, _otherParams$rules, _otherParams$order, _otherParams$hooks;
313
- var appPlugin, app, otherParams;
325
+ var otherParams, cachedTempOrder, appPlugin, app;
314
326
  return _regeneratorRuntime().wrap(function _callee$(_context) {
315
327
  while (1) switch (_context.prev = _context.next) {
316
328
  case 0:
317
329
  this.core = core;
318
330
  this.store = options.store;
319
- if (!this.store.tempOrder) {
331
+ otherParams = options.otherParams || {};
332
+ this.syncSessionStorageOptions(otherParams);
333
+ if (this.sessionStoragePersistEnabled) {
334
+ cachedTempOrder = this.store.tempOrder;
335
+ this.sessionStorageRestoreRecord = isTempOrder(cachedTempOrder) ? cloneDeep(cachedTempOrder) : null;
336
+ // 统一由 loadSalesDetail hydrate,初始化阶段不直接把缓存态暴露给业务。
337
+ this.store.tempOrder = null;
338
+ this.store.summary = createEmptySummary();
339
+ this.store.availableWalletIds = [];
340
+ this.store.lastOrderInfo = undefined;
341
+ this.store.syncState = undefined;
342
+ this.store.discountList = [];
343
+ } else if (!this.store.tempOrder) {
320
344
  this.store.tempOrder = null;
321
345
  }
322
346
  if (!this.store.summary) {
@@ -333,8 +357,6 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
333
357
  app = appPlugin === null || appPlugin === void 0 || (_appPlugin$getApp = appPlugin.getApp) === null || _appPlugin$getApp === void 0 ? void 0 : _appPlugin$getApp.call(appPlugin);
334
358
  this.logger = app === null || app === void 0 ? void 0 : app.logger;
335
359
  this.window = this.core.getPlugin('window');
336
- otherParams = options.otherParams || {};
337
- this.cacheId = otherParams.cacheId;
338
360
  this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
339
361
  this.rulesHooksOverride = (_otherParams$rules = otherParams.rules) === null || _otherParams$rules === void 0 ? void 0 : _otherParams$rules.hooks;
340
362
  this.moduleHooksOverride = options.hooks;
@@ -362,49 +384,50 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
362
384
  return _regeneratorRuntime().wrap(function _callee2$(_context2) {
363
385
  while (1) switch (_context2.prev = _context2.next) {
364
386
  case 0:
387
+ this.sessionStorageRestoreRecord = null;
365
388
  childModules = [(_this$store = this.store) === null || _this$store === void 0 ? void 0 : _this$store.discount, (_this$store2 = this.store) === null || _this$store2 === void 0 ? void 0 : _this$store2.rules];
366
389
  _i = 0, _childModules = childModules;
367
- case 2:
390
+ case 3:
368
391
  if (!(_i < _childModules.length)) {
369
- _context2.next = 18;
392
+ _context2.next = 19;
370
393
  break;
371
394
  }
372
395
  childModule = _childModules[_i];
373
396
  if (!(!childModule || typeof childModule.destroy !== 'function')) {
374
- _context2.next = 6;
397
+ _context2.next = 7;
375
398
  break;
376
399
  }
377
- return _context2.abrupt("continue", 15);
378
- case 6:
379
- _context2.prev = 6;
380
- _context2.next = 9;
400
+ return _context2.abrupt("continue", 16);
401
+ case 7:
402
+ _context2.prev = 7;
403
+ _context2.next = 10;
381
404
  return childModule.destroy();
382
- case 9:
383
- _context2.next = 15;
405
+ case 10:
406
+ _context2.next = 16;
384
407
  break;
385
- case 11:
386
- _context2.prev = 11;
387
- _context2.t0 = _context2["catch"](6);
408
+ case 12:
409
+ _context2.prev = 12;
410
+ _context2.t0 = _context2["catch"](7);
388
411
  errorMessage = _context2.t0 instanceof Error ? _context2.t0.message : String(_context2.t0);
389
412
  this.logWarning('Destroy child module failed', {
390
413
  module: childModule.name,
391
414
  error: errorMessage
392
415
  });
393
- case 15:
416
+ case 16:
394
417
  _i++;
395
- _context2.next = 2;
418
+ _context2.next = 3;
396
419
  break;
397
- case 18:
420
+ case 19:
398
421
  if (this.store) {
399
422
  this.store.discount = null;
400
423
  this.store.rules = null;
401
424
  }
402
425
  _get(_getPrototypeOf(OrderModule.prototype), "destroy", this).call(this);
403
- case 20:
426
+ case 21:
404
427
  case "end":
405
428
  return _context2.stop();
406
429
  }
407
- }, _callee2, this, [[6, 11]]);
430
+ }, _callee2, this, [[7, 12]]);
408
431
  }));
409
432
  function destroy() {
410
433
  return _destroy.apply(this, arguments);
@@ -422,7 +445,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
422
445
  value: function updateOtherParams(params) {
423
446
  var _otherParams$rules2, _otherParams$order2, _otherParams$hooks2;
424
447
  var otherParams = params || {};
425
- this.cacheId = otherParams.cacheId;
448
+ this.syncSessionStorageOptions(otherParams);
426
449
  this.salesSummaryModuleName = otherParams.salesSummaryModuleName;
427
450
  this.rulesHooksOverride = (_otherParams$rules2 = otherParams.rules) === null || _otherParams$rules2 === void 0 ? void 0 : _otherParams$rules2.hooks;
428
451
  this.orderHooks = this.moduleHooksOverride || ((_otherParams$order2 = otherParams.order) === null || _otherParams$order2 === void 0 ? void 0 : _otherParams$order2.hooks) || ((_otherParams$hooks2 = otherParams.hooks) === null || _otherParams$hooks2 === void 0 ? void 0 : _otherParams$hooks2.order);
@@ -480,15 +503,15 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
480
503
  value: function registerDiscountModules(options) {
481
504
  var _targetCacheData;
482
505
  var targetCacheData = {};
483
- if (this.cacheId && this.window) {
484
- var sessionData = this.window.sessionStorage.getItem(this.name);
485
- if (sessionData) {
486
- try {
506
+ if (!this.sessionStoragePersistEnabled && this.openCache && this.cacheId && this.window) {
507
+ try {
508
+ var sessionData = this.window.sessionStorage.getItem(this.name);
509
+ if (sessionData) {
487
510
  var data = JSON.parse(sessionData);
488
511
  targetCacheData = (data === null || data === void 0 ? void 0 : data[this.cacheId]) || {};
489
- } catch (_unused) {
490
- // sessionStorage 损坏则忽略,按空 initialState 走
491
512
  }
513
+ } catch (_unused) {
514
+ // sessionStorage 损坏或不可用时忽略,按空 initialState 走
492
515
  }
493
516
  }
494
517
  var discount = new DiscountModule("".concat(this.name, "_discount"));
@@ -496,7 +519,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
496
519
  initialState: (_targetCacheData = targetCacheData) === null || _targetCacheData === void 0 ? void 0 : _targetCacheData[discount.name],
497
520
  otherParams: {
498
521
  fatherModule: this.name,
499
- openCache: !!this.cacheId,
522
+ // Unified 的单快照由 Order 管理;其他 Solution 保持原有 Discount 缓存语义。
523
+ openCache: this.openCache && !this.sessionStoragePersistEnabled,
500
524
  cacheId: this.cacheId
501
525
  }
502
526
  });
@@ -1249,7 +1273,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1249
1273
 
1250
1274
  /**
1251
1275
  * 控制 IndexedDB 草稿(saveDraft)是否写入。
1252
- * localStorage tempOrder 持久化已废弃,此方法仅影响 saveDraft。
1276
+ * 此开关仅影响 saveDraft;可选 sessionStorage 会话恢复由
1277
+ * enableSessionStoragePersist 独立控制。
1253
1278
  *
1254
1279
  * @example
1255
1280
  * order.setEnableTempOrderPersist(false); // BigSale 弹窗:跳过 ~1s 的 dbUpdate
@@ -1267,11 +1292,29 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1267
1292
  return this.draftPersistEnabled;
1268
1293
  }
1269
1294
 
1270
- /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化;草稿保存请使用 IndexedDB saveDraft。 */
1295
+ /**
1296
+ * 在 UnifiedBookingSales 显式开启会话恢复时,将完整 tempOrder 写入
1297
+ * sessionStorage 的 cacheId 分桶。写入失败由 BaseModule 静默降级。
1298
+ */
1271
1299
  }, {
1272
1300
  key: "persistTempOrder",
1273
1301
  value: function persistTempOrder() {
1274
- // no-op: OrderModule 的刷新恢复不再依赖 localStorage。
1302
+ if (!this.sessionStoragePersistEnabled || !this.store.tempOrder) return;
1303
+ this.checkSaveCache({
1304
+ cacheId: this.cacheId,
1305
+ fatherModule: this.fatherModule,
1306
+ store: {
1307
+ tempOrder: this.store.tempOrder
1308
+ },
1309
+ cacheKey: ['tempOrder']
1310
+ });
1311
+ }
1312
+ }, {
1313
+ key: "consumeSessionStorageRestore",
1314
+ value: function consumeSessionStorageRestore() {
1315
+ var record = this.sessionStorageRestoreRecord;
1316
+ this.sessionStorageRestoreRecord = null;
1317
+ return record ? cloneDeep(record) : null;
1275
1318
  }
1276
1319
  }, {
1277
1320
  key: "notifyTempOrderChanged",
@@ -2336,6 +2379,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2336
2379
  value: function restoreOrder() {
2337
2380
  var _this$store$discount16, _this$store$discount17;
2338
2381
  this.logInfo('restoreOrder start', {});
2382
+ this.sessionStorageRestoreRecord = null;
2339
2383
  var freshTempOrder = this.createDefaultTempOrderInstance();
2340
2384
  this.ensureExternalSaleNumber(freshTempOrder);
2341
2385
  this.store.tempOrder = freshTempOrder;
@@ -2366,36 +2410,37 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2366
2410
  }
2367
2411
  throw new Error('无效的 tempOrder 数据');
2368
2412
  case 2:
2413
+ this.sessionStorageRestoreRecord = null;
2369
2414
  nextTempOrder = this.normalizeTempOrderForRuntime(cloneDeep(tempOrder), {
2370
2415
  ensureIdentity: false
2371
2416
  });
2372
2417
  this.store.tempOrder = nextTempOrder;
2373
2418
  if (!((options === null || options === void 0 ? void 0 : options.recalculateSummary) !== false)) {
2374
- _context12.next = 9;
2419
+ _context12.next = 10;
2375
2420
  break;
2376
2421
  }
2377
- _context12.next = 7;
2422
+ _context12.next = 8;
2378
2423
  return this.recalculateSummary({
2379
2424
  createIfMissing: false
2380
2425
  });
2381
- case 7:
2382
- _context12.next = 10;
2426
+ case 8:
2427
+ _context12.next = 11;
2383
2428
  break;
2384
- case 9:
2385
- this.store.summary = createEmptySummary();
2386
2429
  case 10:
2430
+ this.store.summary = createEmptySummary();
2431
+ case 11:
2387
2432
  if ((options === null || options === void 0 ? void 0 : options.persist) !== false) {
2388
2433
  this.persistTempOrder();
2389
2434
  }
2390
2435
  if (!(options !== null && options !== void 0 && options.saveDraft)) {
2391
- _context12.next = 14;
2436
+ _context12.next = 15;
2392
2437
  break;
2393
2438
  }
2394
- _context12.next = 14;
2439
+ _context12.next = 15;
2395
2440
  return this.saveDraft();
2396
- case 14:
2397
- return _context12.abrupt("return", nextTempOrder);
2398
2441
  case 15:
2442
+ return _context12.abrupt("return", nextTempOrder);
2443
+ case 16:
2399
2444
  case "end":
2400
2445
  return _context12.stop();
2401
2446
  }
@@ -5866,8 +5911,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5866
5911
  key: "hydrateTempOrderFromRecord",
5867
5912
  value: (function () {
5868
5913
  var _hydrateTempOrderFromRecord = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee44(record, options) {
5869
- var _this$store$discount20;
5870
- var sourceRaw, identityReadySource, normalizedCollections, raw, hasIdentityChanges, identityLogMetadata, hasIdentityWarnings, nextTempOrder, sourceLastOrderInfo, isDraftOrder, syntheticIdentityOptions, rawSummary, summarySurcharges, hadSyntheticDraftOrderId, hydratedEditDiscounts, currentDiscounts, currentScanDiscounts, hydratedDiscountIds, retainedScanDiscounts, nextDiscounts, shouldSkipEmptyDiscountSync, _this$store$discount21, _this$store$discount22;
5914
+ var _this$store$discount22;
5915
+ var sourceRaw, identityReadySource, normalizedCollections, raw, hasIdentityChanges, identityLogMetadata, hasIdentityWarnings, isSessionStorageHydrate, nextTempOrder, _this$store$discount20, _this$store$discount21, restoredSessionDiscounts, nextExtend, sourceLastOrderInfo, isDraftOrder, syntheticIdentityOptions, rawSummary, summarySurcharges, hadSyntheticDraftOrderId, hydratedEditDiscounts, currentDiscounts, currentScanDiscounts, hydratedDiscountIds, retainedScanDiscounts, nextDiscounts, shouldSkipEmptyDiscountSync, _this$store$discount23, _this$store$discount24;
5871
5916
  return _regeneratorRuntime().wrap(function _callee44$(_context47) {
5872
5917
  while (1) switch (_context47.prev = _context47.next) {
5873
5918
  case 0:
@@ -5892,10 +5937,48 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5892
5937
  this.logInfo('Normalized hydrated order collection identities', identityLogMetadata);
5893
5938
  }
5894
5939
  }
5940
+ isSessionStorageHydrate = (options === null || options === void 0 ? void 0 : options.source) === 'sessionStorage';
5895
5941
  nextTempOrder = this.normalizeTempOrderForRuntime(raw, {
5896
- makeEditMark: true
5897
- }); // Server list compatibility may synthesize order_id from external_sale_number; tempOrder must not.
5898
- sourceLastOrderInfo = raw.lastOrderInfo || raw;
5942
+ makeEditMark: !isSessionStorageHydrate
5943
+ });
5944
+ this.store.tempOrder = nextTempOrder;
5945
+ if (!isSessionStorageHydrate) {
5946
+ _context47.next = 27;
5947
+ break;
5948
+ }
5949
+ // 会话快照是未提交购物车,不应获得编辑订单的 saved/edit 标记与服务端基线。
5950
+ restoredSessionDiscounts = Array.isArray(raw.discount_list) ? cloneDeep(raw.discount_list) : [];
5951
+ nextExtend = _objectSpread({}, nextTempOrder._extend || {});
5952
+ delete nextExtend.originalSalesSnapshot;
5953
+ nextTempOrder._extend = nextExtend;
5954
+ nextTempOrder.products.forEach(function (product) {
5955
+ if (product.metadata) {
5956
+ delete product.metadata.is_edit_for_runtime;
5957
+ }
5958
+ });
5959
+ nextTempOrder.discount_list = restoredSessionDiscounts;
5960
+ this.store.summary = createEmptySummary();
5961
+ this.store.lastOrderInfo = undefined;
5962
+ _context47.next = 20;
5963
+ return (_this$store$discount20 = this.store.discount) === null || _this$store$discount20 === void 0 ? void 0 : _this$store$discount20.setOriginalDiscountList(cloneDeep(restoredSessionDiscounts));
5964
+ case 20:
5965
+ _context47.next = 22;
5966
+ return (_this$store$discount21 = this.store.discount) === null || _this$store$discount21 === void 0 ? void 0 : _this$store$discount21.setDiscountList(cloneDeep(restoredSessionDiscounts));
5967
+ case 22:
5968
+ if (!(options !== null && options !== void 0 && options.recalcOnHydrate)) {
5969
+ _context47.next = 25;
5970
+ break;
5971
+ }
5972
+ _context47.next = 25;
5973
+ return this.recalculateSummary({
5974
+ createIfMissing: false
5975
+ });
5976
+ case 25:
5977
+ this.persistTempOrder();
5978
+ return _context47.abrupt("return", nextTempOrder);
5979
+ case 27:
5980
+ // Server list compatibility may synthesize order_id from external_sale_number; tempOrder must not.
5981
+ sourceLastOrderInfo = sourceRaw.lastOrderInfo || sourceRaw;
5899
5982
  isDraftOrder = Number(nextTempOrder.is_draft_order || 0) === 1;
5900
5983
  syntheticIdentityOptions = {
5901
5984
  isDraftOrder: isDraftOrder,
@@ -5905,7 +5988,6 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5905
5988
  summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map(function (s) {
5906
5989
  return _objectSpread({}, s || {});
5907
5990
  }) : cloneDeep(nextTempOrder.surcharges || []);
5908
- this.store.tempOrder = nextTempOrder;
5909
5991
  this.store.summary = _objectSpread(_objectSpread(_objectSpread({}, createEmptySummary()), rawSummary), {}, {
5910
5992
  surcharges: summarySurcharges
5911
5993
  });
@@ -5926,7 +6008,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5926
6008
  this.store.syncState = 'local';
5927
6009
  }
5928
6010
  hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
5929
- currentDiscounts = typeof ((_this$store$discount20 = this.store.discount) === null || _this$store$discount20 === void 0 ? void 0 : _this$store$discount20.getDiscountList) === 'function' ? this.store.discount.getDiscountList() || [] : [];
6011
+ currentDiscounts = typeof ((_this$store$discount22 = this.store.discount) === null || _this$store$discount22 === void 0 ? void 0 : _this$store$discount22.getDiscountList) === 'function' ? this.store.discount.getDiscountList() || [] : [];
5930
6012
  currentScanDiscounts = currentDiscounts.filter(function (discount) {
5931
6013
  return discount === null || discount === void 0 ? void 0 : discount.isScan;
5932
6014
  });
@@ -5939,28 +6021,28 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
5939
6021
  nextDiscounts = [].concat(_toConsumableArray(hydratedEditDiscounts), _toConsumableArray(retainedScanDiscounts));
5940
6022
  shouldSkipEmptyDiscountSync = nextDiscounts.length === 0 && currentDiscounts.length === 0;
5941
6023
  if (shouldSkipEmptyDiscountSync) {
5942
- _context47.next = 31;
6024
+ _context47.next = 50;
5943
6025
  break;
5944
6026
  }
5945
6027
  OrderModule.populateSavedAmounts(nextTempOrder.products, nextDiscounts);
5946
- _context47.next = 29;
5947
- return (_this$store$discount21 = this.store.discount) === null || _this$store$discount21 === void 0 ? void 0 : _this$store$discount21.setOriginalDiscountList(nextDiscounts);
5948
- case 29:
5949
- _context47.next = 31;
5950
- return (_this$store$discount22 = this.store.discount) === null || _this$store$discount22 === void 0 ? void 0 : _this$store$discount22.setDiscountList(nextDiscounts);
5951
- case 31:
6028
+ _context47.next = 48;
6029
+ return (_this$store$discount23 = this.store.discount) === null || _this$store$discount23 === void 0 ? void 0 : _this$store$discount23.setOriginalDiscountList(nextDiscounts);
6030
+ case 48:
6031
+ _context47.next = 50;
6032
+ return (_this$store$discount24 = this.store.discount) === null || _this$store$discount24 === void 0 ? void 0 : _this$store$discount24.setDiscountList(nextDiscounts);
6033
+ case 50:
5952
6034
  if (!(options !== null && options !== void 0 && options.recalcOnHydrate)) {
5953
- _context47.next = 34;
6035
+ _context47.next = 53;
5954
6036
  break;
5955
6037
  }
5956
- _context47.next = 34;
6038
+ _context47.next = 53;
5957
6039
  return this.recalculateSummary({
5958
6040
  createIfMissing: false
5959
6041
  });
5960
- case 34:
6042
+ case 53:
5961
6043
  this.persistTempOrder();
5962
6044
  return _context47.abrupt("return", nextTempOrder);
5963
- case 36:
6045
+ case 55:
5964
6046
  case "end":
5965
6047
  return _context47.stop();
5966
6048
  }
@@ -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
- /** @deprecated no-op;OrderModule 不再负责 tempOrder localStorage 持久化。 */
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>;
@@ -1395,7 +1395,6 @@ export function productRequiresFormSubject(tempOrder, product) {
1395
1395
  }
1396
1396
  export function resolveIsFormSubject(tempOrder, product) {
1397
1397
  var _tempOrder$holder;
1398
- debugger;
1399
1398
  // 旧版预约维度的 holder 类型仍然生效;新版则从当前商品 holder_config 判断。
1400
1399
  if ((tempOrder === null || tempOrder === void 0 || (_tempOrder$holder = tempOrder.holder) === null || _tempOrder$holder === void 0 ? void 0 : _tempOrder$holder.type) === 'form') return true;
1401
1400
  if (product) return productRequiresFormSubject(tempOrder, product);
@@ -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 buildSubModuleOtherParams(): Record<string, any>;
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
  *