@pisell/pisellos 2.3.62 → 2.3.64

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.
Files changed (56) hide show
  1. package/dist/core/index.d.ts +0 -7
  2. package/dist/core/index.js +65 -109
  3. package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -1
  4. package/dist/model/strategy/adapter/walletPass/utils.js +0 -2
  5. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +7 -3
  6. package/dist/modules/Customer/index.d.ts +4 -0
  7. package/dist/modules/Customer/index.js +91 -59
  8. package/dist/modules/Customer/types.d.ts +2 -0
  9. package/dist/modules/Order/index.js +4 -1
  10. package/dist/modules/Order/utils.js +36 -30
  11. package/dist/modules/Payment/walletpass.js +4 -5
  12. package/dist/modules/Quotation/index.d.ts +0 -6
  13. package/dist/modules/Quotation/index.js +19 -75
  14. package/dist/plugins/request.d.ts +0 -1
  15. package/dist/server/index.d.ts +2 -6
  16. package/dist/server/index.js +92 -133
  17. package/dist/server/modules/floor-plan/index.d.ts +0 -4
  18. package/dist/server/modules/floor-plan/index.js +98 -240
  19. package/dist/server/modules/menu/index.js +23 -48
  20. package/dist/server/modules/order/index.d.ts +8 -12
  21. package/dist/server/modules/order/index.js +348 -342
  22. package/dist/server/modules/products/index.d.ts +2 -8
  23. package/dist/server/modules/products/index.js +75 -167
  24. package/dist/server/modules/resource/index.js +13 -21
  25. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  26. package/dist/solution/BookingTicket/index.d.ts +2 -0
  27. package/dist/solution/BookingTicket/index.js +34 -10
  28. package/lib/core/index.d.ts +0 -7
  29. package/lib/core/index.js +2 -20
  30. package/lib/model/strategy/adapter/promotion/index.js +0 -51
  31. package/lib/model/strategy/adapter/walletPass/evaluator.js +0 -1
  32. package/lib/model/strategy/adapter/walletPass/utils.js +0 -1
  33. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -0
  34. package/lib/modules/Customer/index.d.ts +4 -0
  35. package/lib/modules/Customer/index.js +11 -0
  36. package/lib/modules/Customer/types.d.ts +2 -0
  37. package/lib/modules/Order/index.js +3 -2
  38. package/lib/modules/Order/utils.js +3 -0
  39. package/lib/modules/Payment/walletpass.js +0 -1
  40. package/lib/modules/Quotation/index.d.ts +0 -6
  41. package/lib/modules/Quotation/index.js +5 -49
  42. package/lib/plugins/request.d.ts +0 -1
  43. package/lib/server/index.d.ts +2 -6
  44. package/lib/server/index.js +12 -34
  45. package/lib/server/modules/floor-plan/index.d.ts +0 -4
  46. package/lib/server/modules/floor-plan/index.js +6 -54
  47. package/lib/server/modules/menu/index.js +5 -31
  48. package/lib/server/modules/order/index.d.ts +8 -12
  49. package/lib/server/modules/order/index.js +94 -145
  50. package/lib/server/modules/products/index.d.ts +2 -8
  51. package/lib/server/modules/products/index.js +24 -97
  52. package/lib/server/modules/resource/index.js +2 -7
  53. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +1 -0
  54. package/lib/solution/BookingTicket/index.d.ts +2 -0
  55. package/lib/solution/BookingTicket/index.js +18 -2
  56. package/package.json +1 -1
@@ -25,7 +25,6 @@ module.exports = __toCommonJS(floor_plan_exports);
25
25
  var import_BaseModule = require("../../../modules/BaseModule");
26
26
  var import_types = require("./types");
27
27
  var FLOOR_PLAN_SYNC_DEBOUNCE_MS = 3e3;
28
- var FLOOR_PLAN_STORE_NAME = "floor_plans";
29
28
  var FloorPlanModule = class extends import_BaseModule.BaseModule {
30
29
  constructor(name, version) {
31
30
  super(name, version);
@@ -51,7 +50,6 @@ var FloorPlanModule = class extends import_BaseModule.BaseModule {
51
50
  if (appPlugin) {
52
51
  const app = appPlugin.getApp();
53
52
  this.logger = app.logger;
54
- this.dbManager = app.sqlite || app.dbManager;
55
53
  }
56
54
  this.initFloorPlanDataSource();
57
55
  this.setupFloorPlanSync();
@@ -161,45 +159,6 @@ var FloorPlanModule = class extends import_BaseModule.BaseModule {
161
159
  return [];
162
160
  }
163
161
  }
164
- async loadListFromSQLite() {
165
- if (!this.dbManager)
166
- return [];
167
- try {
168
- const list = await this.dbManager.getAll(FLOOR_PLAN_STORE_NAME);
169
- return Array.isArray(list) ? list : [];
170
- } catch (error) {
171
- this.logWarning("从 SQLite 读取平面图失败", {
172
- error: error instanceof Error ? error.message : String(error)
173
- });
174
- return [];
175
- }
176
- }
177
- async saveListToSQLite(list) {
178
- if (!this.dbManager)
179
- return;
180
- try {
181
- await this.dbManager.clear(FLOOR_PLAN_STORE_NAME);
182
- if (list.length > 0) {
183
- await this.dbManager.bulkAdd(FLOOR_PLAN_STORE_NAME, list);
184
- }
185
- } catch (error) {
186
- this.logWarning("保存平面图到 SQLite 失败", {
187
- count: list.length,
188
- error: error instanceof Error ? error.message : String(error)
189
- });
190
- }
191
- }
192
- async refreshListFromServer() {
193
- const list = await this.loadListFromServer();
194
- if (list.length === 0) {
195
- this.logWarning("远端平面图刷新完成但列表为空");
196
- return;
197
- }
198
- this.replaceStore(list);
199
- await this.saveListToSQLite(list);
200
- this.core.effects.emit(import_types.FloorPlanHooks.onFloorPlansChanged, this.getSortedList());
201
- this.logInfo("远端平面图刷新完成", { count: list.length });
202
- }
203
162
  async fetchByIdFromServer(id) {
204
163
  try {
205
164
  const res = await this.request.get(
@@ -231,19 +190,14 @@ var FloorPlanModule = class extends import_BaseModule.BaseModule {
231
190
  }
232
191
  async preload() {
233
192
  this.logInfo("开始预加载平面图列表");
234
- const cachedList = await this.loadListFromSQLite();
235
- if (cachedList.length > 0) {
236
- this.replaceStore(cachedList);
193
+ const list = await this.loadListFromServer();
194
+ if (list.length > 0) {
195
+ this.replaceStore(list);
237
196
  this.core.effects.emit(import_types.FloorPlanHooks.onFloorPlansChanged, this.getSortedList());
238
- this.logInfo("预加载完成(SQLite)", { count: cachedList.length });
239
- void this.refreshListFromServer().catch((error) => {
240
- this.logWarning("后台刷新平面图失败,继续使用本地数据", {
241
- error: error instanceof Error ? error.message : String(error)
242
- });
243
- });
244
- return;
197
+ this.logInfo("预加载完成", { count: list.length });
198
+ } else {
199
+ this.logWarning("预加载完成但列表为空");
245
200
  }
246
- await this.refreshListFromServer();
247
201
  }
248
202
  initFloorPlanDataSource() {
249
203
  var _a, _b;
@@ -345,7 +299,6 @@ var FloorPlanModule = class extends import_BaseModule.BaseModule {
345
299
  }
346
300
  }
347
301
  if (changed) {
348
- await this.saveListToSQLite(this.store.list);
349
302
  this.core.effects.emit(import_types.FloorPlanHooks.onFloorPlansChanged, this.getSortedList());
350
303
  this.core.effects.emit(import_types.FloorPlanHooks.onFloorPlanSyncCompleted, null);
351
304
  }
@@ -354,7 +307,6 @@ var FloorPlanModule = class extends import_BaseModule.BaseModule {
354
307
  this.store.list = [];
355
308
  this.store.map.clear();
356
309
  this.store.codeMap.clear();
357
- await this.saveListToSQLite([]);
358
310
  }
359
311
  destroy() {
360
312
  var _a;
@@ -185,21 +185,16 @@ var MenuModule = class extends import_BaseModule.BaseModule {
185
185
  this.logWarning("loadMenuFromIndexDB: dbManager 不可用");
186
186
  return [];
187
187
  }
188
- const startedAt = performance.now();
189
188
  try {
190
189
  const menuList = await this.dbManager.getAll(INDEXDB_STORE_NAME);
191
190
  this.logInfo("从 IndexDB 加载餐牌数据", {
192
- menuCount: (menuList == null ? void 0 : menuList.length) ?? 0,
193
- durationMs: +(performance.now() - startedAt).toFixed(2)
191
+ menuCount: (menuList == null ? void 0 : menuList.length) ?? 0
194
192
  });
195
193
  return menuList || [];
196
194
  } catch (error) {
197
195
  const errorMessage = error instanceof Error ? error.message : String(error);
198
196
  console.error("[Menu] 从 IndexDB 读取数据失败:", error);
199
- this.logError("从 IndexDB 读取数据失败", {
200
- durationMs: +(performance.now() - startedAt).toFixed(2),
201
- error: errorMessage
202
- });
197
+ this.logError("从 IndexDB 读取数据失败", { error: errorMessage });
203
198
  return [];
204
199
  }
205
200
  }
@@ -212,41 +207,20 @@ var MenuModule = class extends import_BaseModule.BaseModule {
212
207
  this.logWarning("saveMenuToIndexDB: dbManager 不可用");
213
208
  return;
214
209
  }
215
- const startedAt = performance.now();
216
- let clearDurationMs = 0;
217
- let writeDurationMs = 0;
218
210
  this.logInfo("开始保存餐牌数据到 IndexDB", { menuCount: menuList.length });
219
211
  try {
220
- const clearStartedAt = performance.now();
221
- try {
222
- await this.dbManager.clear(INDEXDB_STORE_NAME);
223
- } finally {
224
- clearDurationMs = +(performance.now() - clearStartedAt).toFixed(2);
225
- }
226
- const writeStartedAt = performance.now();
212
+ await this.dbManager.clear(INDEXDB_STORE_NAME);
227
213
  const savePromises = menuList.map(
228
214
  (menu) => this.dbManager.add(INDEXDB_STORE_NAME, menu)
229
215
  );
230
- try {
231
- await Promise.all(savePromises);
232
- } finally {
233
- writeDurationMs = +(performance.now() - writeStartedAt).toFixed(2);
234
- }
216
+ await Promise.all(savePromises);
235
217
  console.log(`[Menu] 已将 ${menuList.length} 条餐牌数据保存到 IndexDB`);
236
- this.logInfo("餐牌数据已保存到 IndexDB", {
237
- menuCount: menuList.length,
238
- clearDurationMs,
239
- writeDurationMs,
240
- totalDurationMs: +(performance.now() - startedAt).toFixed(2)
241
- });
218
+ this.logInfo("餐牌数据已保存到 IndexDB", { menuCount: menuList.length });
242
219
  } catch (error) {
243
220
  const errorMessage = error instanceof Error ? error.message : String(error);
244
221
  console.error("[Menu] 保存数据到 IndexDB 失败:", error);
245
222
  this.logError("保存数据到 IndexDB 失败", {
246
223
  menuCount: menuList.length,
247
- clearDurationMs,
248
- writeDurationMs,
249
- totalDurationMs: +(performance.now() - startedAt).toFixed(2),
250
224
  error: errorMessage
251
225
  });
252
226
  }
@@ -119,17 +119,13 @@ export declare class OrderModule extends BaseModule implements Module {
119
119
  payment: Record<string, any>;
120
120
  previousPayment: Record<string, any>;
121
121
  } | null>;
122
- loadOrdersByServer(options?: {
123
- trigger?: string;
124
- }): Promise<OrderData[]>;
122
+ loadOrdersByServer(): Promise<OrderData[]>;
125
123
  /**
126
124
  * 静默全量刷新:后台重新拉取全量 SSE 订单数据并更新本地
127
125
  * 拿到完整数据后一次性替换 store,触发订单变更与同步完成事件
128
126
  * @returns 刷新后的订单列表
129
127
  */
130
- silentRefresh(options?: {
131
- trigger?: string;
132
- }): Promise<OrderData[]>;
128
+ silentRefresh(): Promise<OrderData[]>;
133
129
  private normalizeOrderForMemoryList;
134
130
  private normalizeOrdersForMemoryList;
135
131
  private hasRealOrderId;
@@ -278,6 +274,7 @@ export declare class OrderModule extends BaseModule implements Module {
278
274
  * // => 'S-1001'
279
275
  */
280
276
  private getOrderStorageKey;
277
+ private getPersistedOrderStorageKey;
281
278
  private getOrderIdentityMatchKeys;
282
279
  private doOrdersShareIdentity;
283
280
  private findOrderIndexByIdentity;
@@ -294,14 +291,13 @@ export declare class OrderModule extends BaseModule implements Module {
294
291
  private logDuplicateOrders;
295
292
  private compactOrderListByIdentity;
296
293
  /**
297
- * 当前订单缓存可复用窗口。
298
- * start_time 模式使用精确的营业日起止时间;配置缺失或异常时退化为自然日。
294
+ * 当前订单拉取窗口:
295
+ * - 优先使用 createdAtQuery.sales_time_between(已按营业日边界初始化)
296
+ * - 无法解析时退化为自然日窗口
299
297
  */
300
- private getCurrentOrderCacheWindow;
298
+ private getCurrentPullWindow;
301
299
  private hasPulledOrdersToday;
302
300
  private markOrderPulledAtNow;
303
- private clearOrderSnapshotMarker;
304
- private getCurrentShopId;
305
301
  private getStorageItem;
306
302
  private setStorageItem;
307
303
  private loadOrdersFromSQLite;
@@ -339,7 +335,7 @@ export declare class OrderModule extends BaseModule implements Module {
339
335
  * 用于 SSE 全量拉取与营业日窗口裁剪。
340
336
  *
341
337
  * @example
342
- * const { orders, persisted } = await this.replaceOrdersSnapshotInSQLite(orderList, 'refresh')
338
+ * await this.replaceOrdersSnapshotInSQLite(orderList)
343
339
  */
344
340
  private replaceOrdersSnapshotInSQLite;
345
341
  /**
@@ -39,8 +39,8 @@ var import_orderCollectionIdentity = require("../../../modules/Order/utils/order
39
39
  var import_types = require("./types");
40
40
  var import_payment_utils = require("../../../modules/Order/payment-utils");
41
41
  var INDEXDB_STORE_NAME = "orders";
42
+ var ORDER_STORAGE_KEY_FIELD = "__order_storage_key";
42
43
  var ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY = "server_order_last_full_fetch_at";
43
- var ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY = "server_order_last_full_fetch_shop_id";
44
44
  var ORDER_SYNC_THROTTLE_MS_STORAGE_KEY = "order_sync_throttle_ms";
45
45
  var DEFAULT_ORDER_SYNC_THROTTLE_MS = 2e3;
46
46
  var ORDER_SQLITE_DEDUPE_MS = 15e3;
@@ -525,47 +525,11 @@ var OrderModule = class extends import_BaseModule.BaseModule {
525
525
  return DEFAULT_ORDER_SYNC_THROTTLE_MS;
526
526
  }
527
527
  async preload() {
528
- const preloadStartedAt = Date.now();
529
- let cachedOrders = null;
530
- if (this.dbManager) {
531
- try {
532
- cachedOrders = await this.loadOrdersFromSQLite({ throwOnError: true });
533
- } catch (error) {
534
- this.logWarning("preload-SQLite读取失败,回退远端全量拉取", {
535
- error: error instanceof Error ? error.message : String(error)
536
- });
537
- }
538
- }
539
- if (cachedOrders !== null && this.hasPulledOrdersToday()) {
540
- const memoryOrders = this.normalizeOrdersForMemoryList(
541
- cachedOrders,
542
- "preload.sqliteMemory"
543
- );
544
- this.store.list = (0, import_lodash_es.cloneDeep)(memoryOrders);
545
- this.syncOrdersMap();
546
- await this.core.effects.emit(import_types.OrderHooks.onOrdersLoaded, this.store.list);
547
- await this.emitOrdersChanged([], "preload.sqlite");
548
- this.logInfo("预加载完成", {
549
- trigger: "preload",
550
- source: "SQLite",
551
- orderCount: this.store.list.length,
552
- duration: `${Date.now() - preloadStartedAt}ms`
553
- });
554
- return;
555
- }
556
- const orders = await this.loadOrdersByServer({
557
- trigger: "preload"
558
- });
528
+ const orders = await this.loadOrdersByServer();
559
529
  this.store.list = (0, import_lodash_es.cloneDeep)(orders);
560
530
  this.syncOrdersMap();
561
531
  await this.emitOrdersChanged([], "preload");
562
532
  await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
563
- this.logInfo("预加载完成", {
564
- trigger: "preload",
565
- source: "Server",
566
- orderCount: this.store.list.length,
567
- duration: `${Date.now() - preloadStartedAt}ms`
568
- });
569
533
  }
570
534
  getOrders() {
571
535
  return this.store.list;
@@ -786,16 +750,13 @@ var OrderModule = class extends import_BaseModule.BaseModule {
786
750
  this.logInfo("updateLocalPayment-变更事件完成", paymentContext);
787
751
  return { order: nextOrder, payment: nextPayment, previousPayment };
788
752
  }
789
- async loadOrdersByServer(options = {}) {
753
+ async loadOrdersByServer() {
790
754
  var _a;
791
755
  let orderList = [];
792
- let hasFetchedRemoteSnapshot = false;
793
- const trigger = options.trigger || "unknown";
794
756
  const protectedOrdersBeforeRemoteFetch = (await this.loadOrdersFromSQLite()).filter(
795
757
  (order) => this.shouldProtectLocalOrderFromRemoteSnapshot(order)
796
758
  );
797
759
  this.logInfo("loadOrdersByServer-开始", {
798
- trigger,
799
760
  hasOrderDataSource: !!this.orderDataSource,
800
761
  query: ((_a = this.store) == null ? void 0 : _a.createdAtQuery) || null,
801
762
  protectedLocalOrderCount: protectedOrdersBeforeRemoteFetch.length,
@@ -813,36 +774,25 @@ var OrderModule = class extends import_BaseModule.BaseModule {
813
774
  });
814
775
  orderList = data || [];
815
776
  this.logInfo("loadOrdersByServer-SSE拉取成功", {
816
- trigger,
817
777
  count: orderList.length
818
778
  });
819
- hasFetchedRemoteSnapshot = true;
779
+ this.markOrderPulledAtNow();
820
780
  this.lastServerFullFetchAtMs = Date.now();
821
781
  } catch {
822
782
  this.logInfo("loadOrdersByServer-SSE拉取失败,保持当前内存订单");
823
783
  return this.store.list;
824
784
  }
825
785
  }
826
- if (hasFetchedRemoteSnapshot) {
827
- this.clearOrderSnapshotMarker();
828
- }
829
- const {
830
- orders: mergedOrders,
831
- persisted: isRemoteSnapshotPersisted
832
- } = await this.replaceOrdersSnapshotInSQLite(
786
+ const mergedOrders = await this.replaceOrdersSnapshotInSQLite(
833
787
  orderList,
834
788
  "loadOrdersByServer",
835
789
  protectedOrdersBeforeRemoteFetch
836
790
  );
837
- if (hasFetchedRemoteSnapshot && isRemoteSnapshotPersisted) {
838
- this.markOrderPulledAtNow();
839
- }
840
791
  const memoryOrders = this.normalizeOrdersForMemoryList(
841
792
  mergedOrders,
842
793
  "loadOrdersByServer.memory"
843
794
  );
844
795
  this.logInfo("loadOrdersByServer-结束", {
845
- trigger,
846
796
  count: memoryOrders.length,
847
797
  persistedCount: mergedOrders.length,
848
798
  sqliteOnlyDraftCount: mergedOrders.length - memoryOrders.length
@@ -855,34 +805,21 @@ var OrderModule = class extends import_BaseModule.BaseModule {
855
805
  * 拿到完整数据后一次性替换 store,触发订单变更与同步完成事件
856
806
  * @returns 刷新后的订单列表
857
807
  */
858
- async silentRefresh(options = {}) {
808
+ async silentRefresh() {
859
809
  const startTime = Date.now();
860
- const trigger = options.trigger || "background";
861
810
  const elapsedSinceFullFetch = Date.now() - this.lastServerFullFetchAtMs;
862
811
  if (this.lastServerFullFetchAtMs > 0 && elapsedSinceFullFetch < ORDER_SILENT_REFRESH_MIN_INTERVAL_MS) {
863
- this.logInfo("silentRefresh 跳过全量 SSE", {
864
- trigger,
865
- reason: "within_min_interval",
866
- minIntervalMs: ORDER_SILENT_REFRESH_MIN_INTERVAL_MS,
867
- elapsedSinceFullFetchMs: elapsedSinceFullFetch,
868
- orderCount: this.store.list.length
869
- });
870
812
  return this.store.list;
871
813
  }
872
- this.logInfo("silentRefresh 开始", {
873
- trigger,
874
- elapsedSinceFullFetchMs: elapsedSinceFullFetch,
875
- orderCount: this.store.list.length
876
- });
814
+ this.logInfo("silentRefresh 开始");
877
815
  try {
878
816
  this.updateCreateStore();
879
- const orders = await this.loadOrdersByServer({ trigger });
817
+ const orders = await this.loadOrdersByServer();
880
818
  this.store.list = (0, import_lodash_es.cloneDeep)(orders);
881
819
  this.syncOrdersMap();
882
820
  await this.emitOrdersChanged([], "silentRefresh");
883
821
  await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
884
822
  this.logInfo("silentRefresh 完成", {
885
- trigger,
886
823
  orderCount: orders.length,
887
824
  duration: `${Date.now() - startTime}ms`
888
825
  });
@@ -890,7 +827,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
890
827
  } catch (error) {
891
828
  const errorMessage = error instanceof Error ? error.message : String(error);
892
829
  this.logError("silentRefresh 失败", {
893
- trigger,
894
830
  duration: `${Date.now() - startTime}ms`,
895
831
  error: errorMessage
896
832
  });
@@ -1598,6 +1534,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1598
1534
  const patchedOrders = [];
1599
1535
  const remoteProductMembershipChanges = [];
1600
1536
  const forceWriteStorageKeys = /* @__PURE__ */ new Set();
1537
+ const storageKeyMigrations = [];
1601
1538
  const mergeActions = {};
1602
1539
  const existingProductsHaveStableIdentity = this.store.list.map(
1603
1540
  (order) => this.doProductsHaveStableMembershipIdentity(
@@ -1622,6 +1559,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1622
1559
  const mergeKey = storageKey || (fresh.order_id !== void 0 && fresh.order_id !== null ? this.getIdKey(fresh.order_id) : "");
1623
1560
  if (matchIndex >= 0) {
1624
1561
  const existingOrder = updatedList[matchIndex];
1562
+ const previousStorageKey = this.getPersistedOrderStorageKey(existingOrder);
1625
1563
  if (this.isPendingSyncOrder(existingOrder) && this.isRemoteEchoMergeSource(source)) {
1626
1564
  this.logInfo("mergeOrdersToStore-跳过 pending 订单远端覆盖", {
1627
1565
  source,
@@ -1683,6 +1621,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1683
1621
  }
1684
1622
  }
1685
1623
  }
1624
+ const nextStorageKey = this.getOrderStorageKey(mergedOrder);
1625
+ if (previousStorageKey && nextStorageKey && previousStorageKey !== nextStorageKey) {
1626
+ storageKeyMigrations.push({
1627
+ orderId: mergedOrder.order_id ?? existingOrder.order_id ?? fresh.order_id ?? null,
1628
+ from: previousStorageKey,
1629
+ to: nextStorageKey
1630
+ });
1631
+ }
1686
1632
  updatedList[adjustedMatchIndex] = mergedOrder;
1687
1633
  existingProductsHaveStableIdentity[adjustedMatchIndex] = mergedProductsHaveStableIdentity;
1688
1634
  if (membershipChange) {
@@ -1720,7 +1666,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1720
1666
  patchedOrders,
1721
1667
  source,
1722
1668
  mergeActions,
1723
- {},
1669
+ { storageKeyMigrations },
1724
1670
  forceWriteStorageKeys
1725
1671
  );
1726
1672
  this.logInfo("mergeOrdersToStore-结束", {
@@ -1925,6 +1871,13 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1925
1871
  }
1926
1872
  return "";
1927
1873
  }
1874
+ getPersistedOrderStorageKey(order) {
1875
+ const persistedStorageKey = order == null ? void 0 : order[ORDER_STORAGE_KEY_FIELD];
1876
+ if (persistedStorageKey !== void 0 && persistedStorageKey !== null && persistedStorageKey !== "") {
1877
+ return String(persistedStorageKey);
1878
+ }
1879
+ return this.getOrderStorageKey(order);
1880
+ }
1928
1881
  getOrderIdentityMatchKeys(order) {
1929
1882
  return this.getOrderIdentityEntries(order).map((entry) => `${entry.field}:${entry.key}`);
1930
1883
  }
@@ -2184,29 +2137,20 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2184
2137
  return { list, removedCount };
2185
2138
  }
2186
2139
  /**
2187
- * 当前订单缓存可复用窗口。
2188
- * start_time 模式使用精确的营业日起止时间;配置缺失或异常时退化为自然日。
2140
+ * 当前订单拉取窗口:
2141
+ * - 优先使用 createdAtQuery.sales_time_between(已按营业日边界初始化)
2142
+ * - 无法解析时退化为自然日窗口
2189
2143
  */
2190
- getCurrentOrderCacheWindow() {
2191
- var _a;
2144
+ getCurrentPullWindow() {
2145
+ var _a, _b;
2192
2146
  const now = (0, import_dayjs.default)();
2193
- try {
2194
- const appPlugin = this.core.getPlugin("app");
2195
- const app = appPlugin == null ? void 0 : appPlugin.getApp();
2196
- const coreData = app == null ? void 0 : app.data.store.getStore().getDataByModel("core");
2197
- const boundary = (_a = coreData == null ? void 0 : coreData.core) == null ? void 0 : _a.operating_day_boundary;
2198
- if ((boundary == null ? void 0 : boundary.type) === "start_time") {
2199
- const boundaryTime = String(boundary.time || "").trim();
2200
- const todayBoundary = (0, import_dayjs.default)(`${now.format("YYYY-MM-DD")} ${boundaryTime}`);
2201
- if (todayBoundary.isValid()) {
2202
- const startAt2 = now.isBefore(todayBoundary) ? todayBoundary.subtract(1, "day") : todayBoundary;
2203
- return {
2204
- startAt: startAt2,
2205
- endExclusiveAt: startAt2.add(1, "day")
2206
- };
2207
- }
2147
+ const range = (_b = (_a = this.store) == null ? void 0 : _a.createdAtQuery) == null ? void 0 : _b.sales_time_between;
2148
+ if (Array.isArray(range) && range.length >= 2) {
2149
+ const startAt2 = (0, import_dayjs.default)(range[0]);
2150
+ const endExclusiveAt = (0, import_dayjs.default)(range[1]);
2151
+ if (startAt2.isValid() && endExclusiveAt.isValid() && endExclusiveAt.isAfter(startAt2)) {
2152
+ return { startAt: startAt2, endExclusiveAt };
2208
2153
  }
2209
- } catch {
2210
2154
  }
2211
2155
  const startAt = now.startOf("day");
2212
2156
  return { startAt, endExclusiveAt: startAt.add(1, "day") };
@@ -2215,51 +2159,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2215
2159
  const lastFullFetchAt = this.getStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY);
2216
2160
  if (!lastFullFetchAt)
2217
2161
  return false;
2218
- const currentShopId = this.getCurrentShopId();
2219
- const lastFullFetchShopId = this.getStorageItem(
2220
- ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY
2221
- );
2222
- if (!currentShopId || !lastFullFetchShopId || currentShopId !== lastFullFetchShopId) {
2223
- return false;
2224
- }
2225
2162
  const parsed = (0, import_dayjs.default)(lastFullFetchAt);
2226
2163
  if (!parsed.isValid())
2227
2164
  return false;
2228
- const { startAt, endExclusiveAt } = this.getCurrentOrderCacheWindow();
2165
+ const { startAt, endExclusiveAt } = this.getCurrentPullWindow();
2229
2166
  return (parsed.isAfter(startAt) || parsed.isSame(startAt)) && parsed.isBefore(endExclusiveAt);
2230
2167
  }
2231
2168
  markOrderPulledAtNow() {
2232
- const currentShopId = this.getCurrentShopId();
2233
- if (!currentShopId)
2234
- return;
2235
2169
  this.setStorageItem(
2236
2170
  ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY,
2237
2171
  (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
2238
2172
  );
2239
- this.setStorageItem(
2240
- ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY,
2241
- currentShopId
2242
- );
2243
- }
2244
- clearOrderSnapshotMarker() {
2245
- this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, "");
2246
- this.setStorageItem(ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY, "");
2247
- }
2248
- getCurrentShopId() {
2249
- var _a;
2250
- try {
2251
- const appPlugin = this.core.getPlugin("app");
2252
- const app = appPlugin == null ? void 0 : appPlugin.getApp();
2253
- if (!app)
2254
- return null;
2255
- const coreData = app.data.store.getStore().getDataByModel("core");
2256
- const shopId = (_a = coreData == null ? void 0 : coreData.core) == null ? void 0 : _a.id;
2257
- if (shopId === void 0 || shopId === null || shopId === "")
2258
- return null;
2259
- return String(shopId);
2260
- } catch {
2261
- return null;
2262
- }
2263
2173
  }
2264
2174
  getStorageItem(key) {
2265
2175
  var _a;
@@ -2286,7 +2196,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2286
2196
  } catch {
2287
2197
  }
2288
2198
  }
2289
- async loadOrdersFromSQLite(options = {}) {
2199
+ async loadOrdersFromSQLite() {
2290
2200
  if (!this.dbManager)
2291
2201
  return [];
2292
2202
  try {
@@ -2294,9 +2204,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2294
2204
  return (orders || []).map(
2295
2205
  (order) => this.normalizeOrderCollectionsForIngress(order, "loadOrdersFromSQLite")
2296
2206
  );
2297
- } catch (error) {
2298
- if (options.throwOnError)
2299
- throw error;
2207
+ } catch {
2300
2208
  return [];
2301
2209
  }
2302
2210
  }
@@ -2400,7 +2308,18 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2400
2308
  throw new Error("订单 SQLite 数据库未初始化");
2401
2309
  return;
2402
2310
  }
2403
- const ordersSnapshot = (0, import_lodash_es.cloneDeep)(orders).map((order) => this.normalizeOrderCollectionsForIngress(order, `${source}.sqliteIngress`)).filter((order) => this.getOrderStorageKey(order));
2311
+ const migrationTargetStorageKeys = new Set(
2312
+ (options.storageKeyMigrations || []).map((migration) => migration.to)
2313
+ );
2314
+ const ordersSnapshot = (0, import_lodash_es.cloneDeep)(orders).map((order) => this.normalizeOrderCollectionsForIngress(order, `${source}.sqliteIngress`)).map((order) => {
2315
+ const storageKey = this.getOrderStorageKey(order);
2316
+ if (!storageKey || !migrationTargetStorageKeys.has(storageKey))
2317
+ return order;
2318
+ return {
2319
+ ...order,
2320
+ [ORDER_STORAGE_KEY_FIELD]: storageKey
2321
+ };
2322
+ }).filter((order) => this.getOrderStorageKey(order));
2404
2323
  if (ordersSnapshot.length === 0) {
2405
2324
  return;
2406
2325
  }
@@ -2417,6 +2336,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2417
2336
  if (compactedToWrite.length === 0) {
2418
2337
  return;
2419
2338
  }
2339
+ const writtenStorageKeys = new Set(
2340
+ compactedToWrite.map((order) => this.getOrderStorageKey(order)).filter(Boolean)
2341
+ );
2342
+ const storageKeyMigrations = /* @__PURE__ */ new Map();
2343
+ for (const migration of options.storageKeyMigrations || []) {
2344
+ if (!writtenStorageKeys.has(migration.to))
2345
+ continue;
2346
+ if (writtenStorageKeys.has(migration.from))
2347
+ continue;
2348
+ storageKeyMigrations.set(migration.from, migration);
2349
+ }
2420
2350
  try {
2421
2351
  await this.runInOrderSQLiteSaveQueue(async () => {
2422
2352
  let writeMethod = "none";
@@ -2440,6 +2370,30 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2440
2370
  throw new Error("订单 SQLite 数据库不支持写入");
2441
2371
  }
2442
2372
  this.recordRecentSqliteWrite(source, compactedToWrite);
2373
+ if (writeMethod !== "none") {
2374
+ for (const migration of storageKeyMigrations.values()) {
2375
+ try {
2376
+ await this.dbManager.delete(INDEXDB_STORE_NAME, migration.from);
2377
+ this.recentSqliteWriteByStorageKey.delete(migration.from);
2378
+ for (const order of orders) {
2379
+ if (this.getOrderStorageKey(order) !== migration.to)
2380
+ continue;
2381
+ const orderRecord = order;
2382
+ if (String(orderRecord[ORDER_STORAGE_KEY_FIELD] ?? "") !== migration.from)
2383
+ continue;
2384
+ orderRecord[ORDER_STORAGE_KEY_FIELD] = migration.to;
2385
+ }
2386
+ } catch (error) {
2387
+ this.logError("删除订单旧 SQLite storage key 失败", {
2388
+ source,
2389
+ order_id: migration.orderId,
2390
+ oldStorageKey: migration.from,
2391
+ newStorageKey: migration.to,
2392
+ error: error instanceof Error ? error.message : String(error)
2393
+ });
2394
+ }
2395
+ }
2396
+ }
2443
2397
  this.logInfo("patchOrdersInSQLite-完成", {
2444
2398
  source,
2445
2399
  count: compactedToWrite.length,
@@ -2518,17 +2472,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2518
2472
  * 用于 SSE 全量拉取与营业日窗口裁剪。
2519
2473
  *
2520
2474
  * @example
2521
- * const { orders, persisted } = await this.replaceOrdersSnapshotInSQLite(orderList, 'refresh')
2475
+ * await this.replaceOrdersSnapshotInSQLite(orderList)
2522
2476
  */
2523
2477
  async replaceOrdersSnapshotInSQLite(orderList, source, protectedOrdersBeforeRemoteFetch = []) {
2524
2478
  if (!this.dbManager) {
2525
- return {
2526
- orders: this.compactOrderListByIdentity(
2527
- orderList.map((order) => this.normalizeRemoteSyncedOrder(order)),
2528
- `${source}.snapshotNoDb`
2529
- ).list,
2530
- persisted: false
2531
- };
2479
+ return this.compactOrderListByIdentity(
2480
+ orderList.map((order) => this.normalizeRemoteSyncedOrder(order)),
2481
+ `${source}.snapshotNoDb`
2482
+ ).list;
2532
2483
  }
2533
2484
  const remoteSnapshot = (0, import_lodash_es.cloneDeep)(orderList).map(
2534
2485
  (order) => this.normalizeOrderCollectionsForIngress(order, `${source}.remoteIngress`)
@@ -2537,7 +2488,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2537
2488
  remoteSnapshot.map((order) => this.normalizeRemoteSyncedOrder(order)),
2538
2489
  `${source}.remoteSnapshot`
2539
2490
  ).list;
2540
- let persisted = false;
2541
2491
  try {
2542
2492
  await this.runInOrderSQLiteSaveQueue(async () => {
2543
2493
  const existingOrders = typeof this.dbManager.getAll === "function" ? await this.dbManager.getAll(INDEXDB_STORE_NAME) : [];
@@ -2602,14 +2552,13 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2602
2552
  count: mergedSnapshot.length
2603
2553
  });
2604
2554
  });
2605
- persisted = true;
2606
2555
  } catch (error) {
2607
2556
  this.logError("全量保存订单到 SQLite 失败", {
2608
2557
  error: error instanceof Error ? error.message : String(error),
2609
2558
  orderList: remoteSnapshot.length
2610
2559
  });
2611
2560
  }
2612
- return { orders: mergedSnapshot, persisted };
2561
+ return mergedSnapshot;
2613
2562
  }
2614
2563
  /**
2615
2564
  * 清空订单模块的内存数据和本地 SQLite 订单表。
@@ -2625,7 +2574,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2625
2574
  await this.dbManager.clear(INDEXDB_STORE_NAME);
2626
2575
  });
2627
2576
  }
2628
- this.clearOrderSnapshotMarker();
2577
+ this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, "");
2629
2578
  this.emitOrdersChanged([], "clear");
2630
2579
  }
2631
2580
  };