@pisell/pisellos 2.3.65 → 2.3.67

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 (52) hide show
  1. package/dist/core/index.d.ts +7 -0
  2. package/dist/core/index.js +109 -65
  3. package/dist/model/strategy/adapter/walletPass/evaluator.js +1 -0
  4. package/dist/model/strategy/adapter/walletPass/utils.js +2 -0
  5. package/dist/modules/Customer/index.d.ts +0 -4
  6. package/dist/modules/Customer/index.js +59 -91
  7. package/dist/modules/Customer/types.d.ts +0 -2
  8. package/dist/modules/Payment/walletpass.js +5 -4
  9. package/dist/modules/Quotation/index.d.ts +6 -0
  10. package/dist/modules/Quotation/index.js +75 -19
  11. package/dist/plugins/request.d.ts +1 -0
  12. package/dist/server/index.d.ts +8 -2
  13. package/dist/server/index.js +209 -142
  14. package/dist/server/modules/floor-plan/index.d.ts +4 -0
  15. package/dist/server/modules/floor-plan/index.js +240 -98
  16. package/dist/server/modules/menu/index.js +48 -23
  17. package/dist/server/modules/order/index.d.ts +17 -8
  18. package/dist/server/modules/order/index.js +506 -453
  19. package/dist/server/modules/products/index.d.ts +8 -2
  20. package/dist/server/modules/products/index.js +167 -75
  21. package/dist/server/modules/resource/index.js +21 -13
  22. package/dist/server/utils/small-ticket.js +1 -2
  23. package/dist/solution/BookingByStep/index.d.ts +1 -1
  24. package/dist/solution/BookingTicket/index.d.ts +0 -2
  25. package/dist/solution/BookingTicket/index.js +10 -34
  26. package/lib/core/index.d.ts +7 -0
  27. package/lib/core/index.js +20 -2
  28. package/lib/model/strategy/adapter/promotion/index.js +0 -51
  29. package/lib/model/strategy/adapter/walletPass/evaluator.js +1 -0
  30. package/lib/model/strategy/adapter/walletPass/utils.js +1 -0
  31. package/lib/modules/Customer/index.d.ts +0 -4
  32. package/lib/modules/Customer/index.js +0 -11
  33. package/lib/modules/Customer/types.d.ts +0 -2
  34. package/lib/modules/Payment/walletpass.js +1 -0
  35. package/lib/modules/Quotation/index.d.ts +6 -0
  36. package/lib/modules/Quotation/index.js +49 -5
  37. package/lib/plugins/request.d.ts +1 -0
  38. package/lib/server/index.d.ts +8 -2
  39. package/lib/server/index.js +55 -19
  40. package/lib/server/modules/floor-plan/index.d.ts +4 -0
  41. package/lib/server/modules/floor-plan/index.js +54 -6
  42. package/lib/server/modules/menu/index.js +31 -5
  43. package/lib/server/modules/order/index.d.ts +17 -8
  44. package/lib/server/modules/order/index.js +199 -106
  45. package/lib/server/modules/products/index.d.ts +8 -2
  46. package/lib/server/modules/products/index.js +97 -24
  47. package/lib/server/modules/resource/index.js +7 -2
  48. package/lib/server/utils/small-ticket.js +1 -1
  49. package/lib/solution/BookingByStep/index.d.ts +1 -1
  50. package/lib/solution/BookingTicket/index.d.ts +0 -2
  51. package/lib/solution/BookingTicket/index.js +2 -18
  52. package/package.json +1 -1
@@ -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";
43
42
  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;
@@ -192,18 +192,21 @@ var OrderModule = class extends import_BaseModule.BaseModule {
192
192
  * 仅记录计数与订单标识,不输出商品、预约、支付或客户明细。
193
193
  */
194
194
  normalizeOrderCollectionsForIngress(order, source) {
195
- const sourceOrder = (0, import_lodash_es.cloneDeep)(order);
196
- const sourceOrderRecord = sourceOrder;
195
+ const sourceOrderRecord = order;
196
+ let sourceOrder = sourceOrderRecord;
197
197
  if (Array.isArray(sourceOrderRecord.payments)) {
198
- sourceOrderRecord.payments = sourceOrderRecord.payments.map((payment) => {
199
- if (!(0, import_payment_utils.isPendingOrderPayment)(payment) || (0, import_payment_utils.getOrderPaymentIdentityKeys)(payment).some((key) => key.startsWith("unique_payment_number:"))) {
200
- return payment;
201
- }
202
- return {
203
- ...payment,
204
- [PENDING_PAYMENT_WITHOUT_UNIQUE_MARKER]: true
205
- };
206
- });
198
+ sourceOrder = {
199
+ ...sourceOrderRecord,
200
+ payments: sourceOrderRecord.payments.map((payment) => {
201
+ if (!(0, import_payment_utils.isPendingOrderPayment)(payment) || (0, import_payment_utils.getOrderPaymentIdentityKeys)(payment).some((key) => key.startsWith("unique_payment_number:"))) {
202
+ return payment;
203
+ }
204
+ return {
205
+ ...payment,
206
+ [PENDING_PAYMENT_WITHOUT_UNIQUE_MARKER]: true
207
+ };
208
+ })
209
+ };
207
210
  }
208
211
  const result = (0, import_orderCollectionIdentity.normalizeOrderCollections)(sourceOrder);
209
212
  const normalizedOrderRecord = result.order;
@@ -525,11 +528,65 @@ var OrderModule = class extends import_BaseModule.BaseModule {
525
528
  return DEFAULT_ORDER_SYNC_THROTTLE_MS;
526
529
  }
527
530
  async preload() {
528
- const orders = await this.loadOrdersByServer();
531
+ const preloadStartedAt = Date.now();
532
+ let cachedOrders = null;
533
+ let sqliteLoadTimings;
534
+ if (this.dbManager) {
535
+ try {
536
+ cachedOrders = await this.loadOrdersFromSQLite({
537
+ throwOnError: true,
538
+ onTiming: (timings) => {
539
+ sqliteLoadTimings = timings;
540
+ }
541
+ });
542
+ } catch (error) {
543
+ this.logWarning("preload-SQLite读取失败,回退远端全量拉取", {
544
+ error: error instanceof Error ? error.message : String(error)
545
+ });
546
+ }
547
+ }
548
+ if (cachedOrders !== null && this.hasPulledOrdersToday()) {
549
+ const memoryPrepareStartedAt = performance.now();
550
+ const memoryOrders = this.prepareNormalizedOrdersForMemoryList(cachedOrders);
551
+ const memoryPrepareMs = +(performance.now() - memoryPrepareStartedAt).toFixed(2);
552
+ this.store.list = memoryOrders;
553
+ const syncMapStartedAt = performance.now();
554
+ this.syncOrdersMap();
555
+ const syncMapMs = +(performance.now() - syncMapStartedAt).toFixed(2);
556
+ const onOrdersLoadedStartedAt = performance.now();
557
+ await this.core.effects.emit(import_types.OrderHooks.onOrdersLoaded, this.store.list);
558
+ const onOrdersLoadedMs = +(performance.now() - onOrdersLoadedStartedAt).toFixed(2);
559
+ const emitOrdersChangedStartedAt = performance.now();
560
+ await this.emitOrdersChanged([], "preload.sqlite");
561
+ const emitOrdersChangedMs = +(performance.now() - emitOrdersChangedStartedAt).toFixed(2);
562
+ this.logInfo("预加载完成", {
563
+ trigger: "preload",
564
+ source: "SQLite",
565
+ orderCount: this.store.list.length,
566
+ duration: `${Date.now() - preloadStartedAt}ms`,
567
+ stages: {
568
+ ...sqliteLoadTimings || {},
569
+ memoryPrepareMs,
570
+ syncMapMs,
571
+ onOrdersLoadedMs,
572
+ emitOrdersChangedMs
573
+ }
574
+ });
575
+ return;
576
+ }
577
+ const orders = await this.loadOrdersByServer({
578
+ trigger: "preload"
579
+ });
529
580
  this.store.list = (0, import_lodash_es.cloneDeep)(orders);
530
581
  this.syncOrdersMap();
531
582
  await this.emitOrdersChanged([], "preload");
532
583
  await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
584
+ this.logInfo("预加载完成", {
585
+ trigger: "preload",
586
+ source: "Server",
587
+ orderCount: this.store.list.length,
588
+ duration: `${Date.now() - preloadStartedAt}ms`
589
+ });
533
590
  }
534
591
  getOrders() {
535
592
  return this.store.list;
@@ -750,13 +807,16 @@ var OrderModule = class extends import_BaseModule.BaseModule {
750
807
  this.logInfo("updateLocalPayment-变更事件完成", paymentContext);
751
808
  return { order: nextOrder, payment: nextPayment, previousPayment };
752
809
  }
753
- async loadOrdersByServer() {
810
+ async loadOrdersByServer(options = {}) {
754
811
  var _a;
755
812
  let orderList = [];
813
+ let hasFetchedRemoteSnapshot = false;
814
+ const trigger = options.trigger || "unknown";
756
815
  const protectedOrdersBeforeRemoteFetch = (await this.loadOrdersFromSQLite()).filter(
757
816
  (order) => this.shouldProtectLocalOrderFromRemoteSnapshot(order)
758
817
  );
759
818
  this.logInfo("loadOrdersByServer-开始", {
819
+ trigger,
760
820
  hasOrderDataSource: !!this.orderDataSource,
761
821
  query: ((_a = this.store) == null ? void 0 : _a.createdAtQuery) || null,
762
822
  protectedLocalOrderCount: protectedOrdersBeforeRemoteFetch.length,
@@ -774,25 +834,36 @@ var OrderModule = class extends import_BaseModule.BaseModule {
774
834
  });
775
835
  orderList = data || [];
776
836
  this.logInfo("loadOrdersByServer-SSE拉取成功", {
837
+ trigger,
777
838
  count: orderList.length
778
839
  });
779
- this.markOrderPulledAtNow();
840
+ hasFetchedRemoteSnapshot = true;
780
841
  this.lastServerFullFetchAtMs = Date.now();
781
842
  } catch {
782
843
  this.logInfo("loadOrdersByServer-SSE拉取失败,保持当前内存订单");
783
844
  return this.store.list;
784
845
  }
785
846
  }
786
- const mergedOrders = await this.replaceOrdersSnapshotInSQLite(
847
+ if (hasFetchedRemoteSnapshot) {
848
+ this.clearOrderSnapshotMarker();
849
+ }
850
+ const {
851
+ orders: mergedOrders,
852
+ persisted: isRemoteSnapshotPersisted
853
+ } = await this.replaceOrdersSnapshotInSQLite(
787
854
  orderList,
788
855
  "loadOrdersByServer",
789
856
  protectedOrdersBeforeRemoteFetch
790
857
  );
858
+ if (hasFetchedRemoteSnapshot && isRemoteSnapshotPersisted) {
859
+ this.markOrderPulledAtNow();
860
+ }
791
861
  const memoryOrders = this.normalizeOrdersForMemoryList(
792
862
  mergedOrders,
793
863
  "loadOrdersByServer.memory"
794
864
  );
795
865
  this.logInfo("loadOrdersByServer-结束", {
866
+ trigger,
796
867
  count: memoryOrders.length,
797
868
  persistedCount: mergedOrders.length,
798
869
  sqliteOnlyDraftCount: mergedOrders.length - memoryOrders.length
@@ -805,21 +876,34 @@ var OrderModule = class extends import_BaseModule.BaseModule {
805
876
  * 拿到完整数据后一次性替换 store,触发订单变更与同步完成事件
806
877
  * @returns 刷新后的订单列表
807
878
  */
808
- async silentRefresh() {
879
+ async silentRefresh(options = {}) {
809
880
  const startTime = Date.now();
881
+ const trigger = options.trigger || "background";
810
882
  const elapsedSinceFullFetch = Date.now() - this.lastServerFullFetchAtMs;
811
883
  if (this.lastServerFullFetchAtMs > 0 && elapsedSinceFullFetch < ORDER_SILENT_REFRESH_MIN_INTERVAL_MS) {
884
+ this.logInfo("silentRefresh 跳过全量 SSE", {
885
+ trigger,
886
+ reason: "within_min_interval",
887
+ minIntervalMs: ORDER_SILENT_REFRESH_MIN_INTERVAL_MS,
888
+ elapsedSinceFullFetchMs: elapsedSinceFullFetch,
889
+ orderCount: this.store.list.length
890
+ });
812
891
  return this.store.list;
813
892
  }
814
- this.logInfo("silentRefresh 开始");
893
+ this.logInfo("silentRefresh 开始", {
894
+ trigger,
895
+ elapsedSinceFullFetchMs: elapsedSinceFullFetch,
896
+ orderCount: this.store.list.length
897
+ });
815
898
  try {
816
899
  this.updateCreateStore();
817
- const orders = await this.loadOrdersByServer();
900
+ const orders = await this.loadOrdersByServer({ trigger });
818
901
  this.store.list = (0, import_lodash_es.cloneDeep)(orders);
819
902
  this.syncOrdersMap();
820
903
  await this.emitOrdersChanged([], "silentRefresh");
821
904
  await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
822
905
  this.logInfo("silentRefresh 完成", {
906
+ trigger,
823
907
  orderCount: orders.length,
824
908
  duration: `${Date.now() - startTime}ms`
825
909
  });
@@ -827,6 +911,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
827
911
  } catch (error) {
828
912
  const errorMessage = error instanceof Error ? error.message : String(error);
829
913
  this.logError("silentRefresh 失败", {
914
+ trigger,
830
915
  duration: `${Date.now() - startTime}ms`,
831
916
  error: errorMessage
832
917
  });
@@ -835,6 +920,12 @@ var OrderModule = class extends import_BaseModule.BaseModule {
835
920
  }
836
921
  normalizeOrderForMemoryList(order, source = "normalizeOrderForMemoryList") {
837
922
  const normalizedOrder = this.normalizeOrderCollectionsForIngress(order, source);
923
+ return this.prepareNormalizedOrderForMemoryList(normalizedOrder);
924
+ }
925
+ /**
926
+ * 将已经完成集合规范化的订单转换为内存身份,不重复扫描 products/bookings/payments。
927
+ */
928
+ prepareNormalizedOrderForMemoryList(normalizedOrder) {
838
929
  const externalSaleNumber = normalizedOrder == null ? void 0 : normalizedOrder.external_sale_number;
839
930
  if (this.isDraftOrder(normalizedOrder) && !this.hasRealOrderId(normalizedOrder)) {
840
931
  return normalizedOrder;
@@ -850,6 +941,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
850
941
  order_id: externalSaleNumber
851
942
  };
852
943
  }
944
+ prepareNormalizedOrdersForMemoryList(orders) {
945
+ return orders.map((order) => this.prepareNormalizedOrderForMemoryList(order)).filter((order) => this.shouldKeepOrderInMemory(order));
946
+ }
853
947
  normalizeOrdersForMemoryList(orders, source) {
854
948
  return orders.map((order) => this.normalizeOrderForMemoryList(order, source)).filter((order) => this.shouldKeepOrderInMemory(order));
855
949
  }
@@ -1534,7 +1628,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1534
1628
  const patchedOrders = [];
1535
1629
  const remoteProductMembershipChanges = [];
1536
1630
  const forceWriteStorageKeys = /* @__PURE__ */ new Set();
1537
- const storageKeyMigrations = [];
1538
1631
  const mergeActions = {};
1539
1632
  const existingProductsHaveStableIdentity = this.store.list.map(
1540
1633
  (order) => this.doProductsHaveStableMembershipIdentity(
@@ -1559,7 +1652,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1559
1652
  const mergeKey = storageKey || (fresh.order_id !== void 0 && fresh.order_id !== null ? this.getIdKey(fresh.order_id) : "");
1560
1653
  if (matchIndex >= 0) {
1561
1654
  const existingOrder = updatedList[matchIndex];
1562
- const previousStorageKey = this.getPersistedOrderStorageKey(existingOrder);
1563
1655
  if (this.isPendingSyncOrder(existingOrder) && this.isRemoteEchoMergeSource(source)) {
1564
1656
  this.logInfo("mergeOrdersToStore-跳过 pending 订单远端覆盖", {
1565
1657
  source,
@@ -1621,14 +1713,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1621
1713
  }
1622
1714
  }
1623
1715
  }
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
- }
1632
1716
  updatedList[adjustedMatchIndex] = mergedOrder;
1633
1717
  existingProductsHaveStableIdentity[adjustedMatchIndex] = mergedProductsHaveStableIdentity;
1634
1718
  if (membershipChange) {
@@ -1666,7 +1750,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1666
1750
  patchedOrders,
1667
1751
  source,
1668
1752
  mergeActions,
1669
- { storageKeyMigrations },
1753
+ {},
1670
1754
  forceWriteStorageKeys
1671
1755
  );
1672
1756
  this.logInfo("mergeOrdersToStore-结束", {
@@ -1871,13 +1955,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
1871
1955
  }
1872
1956
  return "";
1873
1957
  }
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
- }
1881
1958
  getOrderIdentityMatchKeys(order) {
1882
1959
  return this.getOrderIdentityEntries(order).map((entry) => `${entry.field}:${entry.key}`);
1883
1960
  }
@@ -2137,20 +2214,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2137
2214
  return { list, removedCount };
2138
2215
  }
2139
2216
  /**
2140
- * 当前订单拉取窗口:
2141
- * - 优先使用 createdAtQuery.sales_time_between(已按营业日边界初始化)
2142
- * - 无法解析时退化为自然日窗口
2217
+ * 当前订单缓存可复用窗口。
2218
+ * start_time 模式使用精确的营业日起止时间;配置缺失或异常时退化为自然日。
2143
2219
  */
2144
- getCurrentPullWindow() {
2145
- var _a, _b;
2220
+ getCurrentOrderCacheWindow() {
2221
+ var _a;
2146
2222
  const now = (0, import_dayjs.default)();
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 };
2223
+ try {
2224
+ const appPlugin = this.core.getPlugin("app");
2225
+ const app = appPlugin == null ? void 0 : appPlugin.getApp();
2226
+ const coreData = app == null ? void 0 : app.data.store.getStore().getDataByModel("core");
2227
+ const boundary = (_a = coreData == null ? void 0 : coreData.core) == null ? void 0 : _a.operating_day_boundary;
2228
+ if ((boundary == null ? void 0 : boundary.type) === "start_time") {
2229
+ const boundaryTime = String(boundary.time || "").trim();
2230
+ const todayBoundary = (0, import_dayjs.default)(`${now.format("YYYY-MM-DD")} ${boundaryTime}`);
2231
+ if (todayBoundary.isValid()) {
2232
+ const startAt2 = now.isBefore(todayBoundary) ? todayBoundary.subtract(1, "day") : todayBoundary;
2233
+ return {
2234
+ startAt: startAt2,
2235
+ endExclusiveAt: startAt2.add(1, "day")
2236
+ };
2237
+ }
2153
2238
  }
2239
+ } catch {
2154
2240
  }
2155
2241
  const startAt = now.startOf("day");
2156
2242
  return { startAt, endExclusiveAt: startAt.add(1, "day") };
@@ -2159,17 +2245,51 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2159
2245
  const lastFullFetchAt = this.getStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY);
2160
2246
  if (!lastFullFetchAt)
2161
2247
  return false;
2248
+ const currentShopId = this.getCurrentShopId();
2249
+ const lastFullFetchShopId = this.getStorageItem(
2250
+ ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY
2251
+ );
2252
+ if (!currentShopId || !lastFullFetchShopId || currentShopId !== lastFullFetchShopId) {
2253
+ return false;
2254
+ }
2162
2255
  const parsed = (0, import_dayjs.default)(lastFullFetchAt);
2163
2256
  if (!parsed.isValid())
2164
2257
  return false;
2165
- const { startAt, endExclusiveAt } = this.getCurrentPullWindow();
2258
+ const { startAt, endExclusiveAt } = this.getCurrentOrderCacheWindow();
2166
2259
  return (parsed.isAfter(startAt) || parsed.isSame(startAt)) && parsed.isBefore(endExclusiveAt);
2167
2260
  }
2168
2261
  markOrderPulledAtNow() {
2262
+ const currentShopId = this.getCurrentShopId();
2263
+ if (!currentShopId)
2264
+ return;
2169
2265
  this.setStorageItem(
2170
2266
  ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY,
2171
2267
  (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
2172
2268
  );
2269
+ this.setStorageItem(
2270
+ ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY,
2271
+ currentShopId
2272
+ );
2273
+ }
2274
+ clearOrderSnapshotMarker() {
2275
+ this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, "");
2276
+ this.setStorageItem(ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY, "");
2277
+ }
2278
+ getCurrentShopId() {
2279
+ var _a;
2280
+ try {
2281
+ const appPlugin = this.core.getPlugin("app");
2282
+ const app = appPlugin == null ? void 0 : appPlugin.getApp();
2283
+ if (!app)
2284
+ return null;
2285
+ const coreData = app.data.store.getStore().getDataByModel("core");
2286
+ const shopId = (_a = coreData == null ? void 0 : coreData.core) == null ? void 0 : _a.id;
2287
+ if (shopId === void 0 || shopId === null || shopId === "")
2288
+ return null;
2289
+ return String(shopId);
2290
+ } catch {
2291
+ return null;
2292
+ }
2173
2293
  }
2174
2294
  getStorageItem(key) {
2175
2295
  var _a;
@@ -2196,15 +2316,29 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2196
2316
  } catch {
2197
2317
  }
2198
2318
  }
2199
- async loadOrdersFromSQLite() {
2319
+ async loadOrdersFromSQLite(options = {}) {
2320
+ var _a;
2200
2321
  if (!this.dbManager)
2201
2322
  return [];
2202
2323
  try {
2324
+ const loadStartedAt = performance.now();
2325
+ const rawReadStartedAt = performance.now();
2203
2326
  const orders = await this.dbManager.getAll(INDEXDB_STORE_NAME);
2204
- return (orders || []).map(
2327
+ const sqliteRawReadMs = +(performance.now() - rawReadStartedAt).toFixed(2);
2328
+ const normalizeStartedAt = performance.now();
2329
+ const normalizedOrders = (orders || []).map(
2205
2330
  (order) => this.normalizeOrderCollectionsForIngress(order, "loadOrdersFromSQLite")
2206
2331
  );
2207
- } catch {
2332
+ const sqliteNormalizeMs = +(performance.now() - normalizeStartedAt).toFixed(2);
2333
+ (_a = options.onTiming) == null ? void 0 : _a.call(options, {
2334
+ sqliteRawReadMs,
2335
+ sqliteNormalizeMs,
2336
+ sqliteLoadTotalMs: +(performance.now() - loadStartedAt).toFixed(2)
2337
+ });
2338
+ return normalizedOrders;
2339
+ } catch (error) {
2340
+ if (options.throwOnError)
2341
+ throw error;
2208
2342
  return [];
2209
2343
  }
2210
2344
  }
@@ -2308,18 +2442,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2308
2442
  throw new Error("订单 SQLite 数据库未初始化");
2309
2443
  return;
2310
2444
  }
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));
2445
+ const ordersSnapshot = (0, import_lodash_es.cloneDeep)(orders).map((order) => this.normalizeOrderCollectionsForIngress(order, `${source}.sqliteIngress`)).filter((order) => this.getOrderStorageKey(order));
2323
2446
  if (ordersSnapshot.length === 0) {
2324
2447
  return;
2325
2448
  }
@@ -2336,17 +2459,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2336
2459
  if (compactedToWrite.length === 0) {
2337
2460
  return;
2338
2461
  }
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
- }
2350
2462
  try {
2351
2463
  await this.runInOrderSQLiteSaveQueue(async () => {
2352
2464
  let writeMethod = "none";
@@ -2370,30 +2482,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2370
2482
  throw new Error("订单 SQLite 数据库不支持写入");
2371
2483
  }
2372
2484
  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
- }
2397
2485
  this.logInfo("patchOrdersInSQLite-完成", {
2398
2486
  source,
2399
2487
  count: compactedToWrite.length,
@@ -2472,14 +2560,17 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2472
2560
  * 用于 SSE 全量拉取与营业日窗口裁剪。
2473
2561
  *
2474
2562
  * @example
2475
- * await this.replaceOrdersSnapshotInSQLite(orderList)
2563
+ * const { orders, persisted } = await this.replaceOrdersSnapshotInSQLite(orderList, 'refresh')
2476
2564
  */
2477
2565
  async replaceOrdersSnapshotInSQLite(orderList, source, protectedOrdersBeforeRemoteFetch = []) {
2478
2566
  if (!this.dbManager) {
2479
- return this.compactOrderListByIdentity(
2480
- orderList.map((order) => this.normalizeRemoteSyncedOrder(order)),
2481
- `${source}.snapshotNoDb`
2482
- ).list;
2567
+ return {
2568
+ orders: this.compactOrderListByIdentity(
2569
+ orderList.map((order) => this.normalizeRemoteSyncedOrder(order)),
2570
+ `${source}.snapshotNoDb`
2571
+ ).list,
2572
+ persisted: false
2573
+ };
2483
2574
  }
2484
2575
  const remoteSnapshot = (0, import_lodash_es.cloneDeep)(orderList).map(
2485
2576
  (order) => this.normalizeOrderCollectionsForIngress(order, `${source}.remoteIngress`)
@@ -2488,6 +2579,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2488
2579
  remoteSnapshot.map((order) => this.normalizeRemoteSyncedOrder(order)),
2489
2580
  `${source}.remoteSnapshot`
2490
2581
  ).list;
2582
+ let persisted = false;
2491
2583
  try {
2492
2584
  await this.runInOrderSQLiteSaveQueue(async () => {
2493
2585
  const existingOrders = typeof this.dbManager.getAll === "function" ? await this.dbManager.getAll(INDEXDB_STORE_NAME) : [];
@@ -2552,13 +2644,14 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2552
2644
  count: mergedSnapshot.length
2553
2645
  });
2554
2646
  });
2647
+ persisted = true;
2555
2648
  } catch (error) {
2556
2649
  this.logError("全量保存订单到 SQLite 失败", {
2557
2650
  error: error instanceof Error ? error.message : String(error),
2558
2651
  orderList: remoteSnapshot.length
2559
2652
  });
2560
2653
  }
2561
- return mergedSnapshot;
2654
+ return { orders: mergedSnapshot, persisted };
2562
2655
  }
2563
2656
  /**
2564
2657
  * 清空订单模块的内存数据和本地 SQLite 订单表。
@@ -2574,7 +2667,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2574
2667
  await this.dbManager.clear(INDEXDB_STORE_NAME);
2575
2668
  });
2576
2669
  }
2577
- this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, "");
2670
+ this.clearOrderSnapshotMarker();
2578
2671
  this.emitOrdersChanged([], "clear");
2579
2672
  }
2580
2673
  };
@@ -25,6 +25,7 @@ export declare class ProductsModule extends BaseModule implements Module {
25
25
  private quotationBridgeLoadedKey?;
26
26
  private quotationBridgeRefreshPromise?;
27
27
  private quotationBridgeRefreshKey?;
28
+ private quotationBridgeUpdatedCallback?;
28
29
  private quotationScheduleCache;
29
30
  private quotationScheduleCacheSource;
30
31
  private quotationScheduleCacheLoaded;
@@ -72,6 +73,7 @@ export declare class ProductsModule extends BaseModule implements Module {
72
73
  scheduleModule?: any;
73
74
  channel?: string;
74
75
  customer_id?: number | string;
76
+ onQuotationUpdated?: () => void;
75
77
  }): Promise<void>;
76
78
  /**
77
79
  * 刷新桥接器内的报价单列表。
@@ -181,7 +183,9 @@ export declare class ProductsModule extends BaseModule implements Module {
181
183
  /**
182
184
  * 通过 ProductDataSource SSE 加载完整商品列表
183
185
  */
184
- loadProductsByServer(): Promise<any>;
186
+ loadProductsByServer(options?: {
187
+ trigger?: string;
188
+ }): Promise<any>;
185
189
  /**
186
190
  * 纯请求方法:通过 HTTP 接口获取商品列表(无副作用,不触发事件、不写 IndexDB)
187
191
  * @param params 查询参数
@@ -331,7 +335,9 @@ export declare class ProductsModule extends BaseModule implements Module {
331
335
  * 拿到完整数据后一次性替换 store,清除价格缓存,触发 onProductsSyncCompleted
332
336
  * @returns 刷新后的商品列表
333
337
  */
334
- silentRefresh(): Promise<ProductData[]>;
338
+ silentRefresh(options?: {
339
+ trigger?: string;
340
+ }): Promise<ProductData[]>;
335
341
  /**
336
342
  * 销毁同步资源(取消 pubsub 订阅、清除定时器)
337
343
  */