@pisell/pisellos 2.3.57 → 2.3.59

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 (34) 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/promotion/index.js +0 -9
  4. package/dist/modules/Quotation/index.d.ts +6 -0
  5. package/dist/modules/Quotation/index.js +75 -19
  6. package/dist/modules/Rules/index.js +14 -7
  7. package/dist/plugins/request.d.ts +1 -0
  8. package/dist/server/index.d.ts +15 -0
  9. package/dist/server/index.js +970 -842
  10. package/dist/server/modules/floor-plan/index.d.ts +4 -0
  11. package/dist/server/modules/floor-plan/index.js +240 -98
  12. package/dist/server/modules/order/index.d.ts +7 -5
  13. package/dist/server/modules/order/index.js +185 -80
  14. package/dist/server/modules/order/types.d.ts +1 -1
  15. package/dist/server/modules/products/index.d.ts +2 -0
  16. package/dist/server/modules/products/index.js +17 -3
  17. package/dist/server/modules/resource/index.js +21 -13
  18. package/lib/core/index.d.ts +7 -0
  19. package/lib/core/index.js +20 -2
  20. package/lib/modules/Quotation/index.d.ts +6 -0
  21. package/lib/modules/Quotation/index.js +49 -5
  22. package/lib/modules/Rules/index.js +20 -5
  23. package/lib/plugins/request.d.ts +1 -0
  24. package/lib/server/index.d.ts +15 -0
  25. package/lib/server/index.js +120 -15
  26. package/lib/server/modules/floor-plan/index.d.ts +4 -0
  27. package/lib/server/modules/floor-plan/index.js +54 -6
  28. package/lib/server/modules/order/index.d.ts +7 -5
  29. package/lib/server/modules/order/index.js +114 -26
  30. package/lib/server/modules/order/types.d.ts +1 -1
  31. package/lib/server/modules/products/index.d.ts +2 -0
  32. package/lib/server/modules/products/index.js +15 -4
  33. package/lib/server/modules/resource/index.js +7 -2
  34. package/package.json +1 -1
@@ -42,6 +42,7 @@ import { getOrderPaymentIdentityKeys, isIdentifiedPendingOrderPayment, isPending
42
42
  */
43
43
  var INDEXDB_STORE_NAME = 'orders';
44
44
  var ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY = 'server_order_last_full_fetch_at';
45
+ var ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY = 'server_order_last_full_fetch_shop_id';
45
46
  var ORDER_SYNC_THROTTLE_MS_STORAGE_KEY = 'order_sync_throttle_ms';
46
47
  var DEFAULT_ORDER_SYNC_THROTTLE_MS = 2000;
47
48
  /** pubsub 回声写入去重窗口:业务 API 刚写入后,跳过同单 SQLite patch */
@@ -700,26 +701,62 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
700
701
  key: "preload",
701
702
  value: function () {
702
703
  var _preload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
703
- var orders;
704
+ var cachedOrders, memoryOrders, orders;
704
705
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
705
706
  while (1) switch (_context4.prev = _context4.next) {
706
707
  case 0:
707
- _context4.next = 2;
708
+ cachedOrders = null;
709
+ if (!this.dbManager) {
710
+ _context4.next = 11;
711
+ break;
712
+ }
713
+ _context4.prev = 2;
714
+ _context4.next = 5;
715
+ return this.loadOrdersFromSQLite({
716
+ throwOnError: true
717
+ });
718
+ case 5:
719
+ cachedOrders = _context4.sent;
720
+ _context4.next = 11;
721
+ break;
722
+ case 8:
723
+ _context4.prev = 8;
724
+ _context4.t0 = _context4["catch"](2);
725
+ this.logWarning('preload-SQLite读取失败,回退远端全量拉取', {
726
+ error: _context4.t0 instanceof Error ? _context4.t0.message : String(_context4.t0)
727
+ });
728
+ case 11:
729
+ if (!(cachedOrders !== null && this.hasPulledOrdersToday())) {
730
+ _context4.next = 20;
731
+ break;
732
+ }
733
+ memoryOrders = this.normalizeOrdersForMemoryList(cachedOrders, 'preload.sqliteMemory');
734
+ this.store.list = cloneDeep(memoryOrders);
735
+ this.syncOrdersMap();
736
+ _context4.next = 17;
737
+ return this.core.effects.emit(OrderHooks.onOrdersLoaded, this.store.list);
738
+ case 17:
739
+ _context4.next = 19;
740
+ return this.emitOrdersChanged([], 'preload.sqlite');
741
+ case 19:
742
+ return _context4.abrupt("return");
743
+ case 20:
744
+ _context4.next = 22;
708
745
  return this.loadOrdersByServer();
709
- case 2:
746
+ case 22:
710
747
  orders = _context4.sent;
711
748
  this.store.list = cloneDeep(orders);
712
749
  this.syncOrdersMap();
713
- _context4.next = 7;
750
+ _context4.next = 27;
714
751
  return this.emitOrdersChanged([], 'preload');
715
- case 7:
716
- _context4.next = 9;
752
+ case 27:
753
+ _context4.next = 29;
717
754
  return this.core.effects.emit(OrderHooks.onOrdersSyncCompleted, null);
718
- case 9:
755
+ case 29:
719
756
  case "end":
720
757
  return _context4.stop();
721
758
  }
722
- }, _callee4, this);
759
+ }, _callee4, this, [[2, 8]]);
723
760
  }));
724
761
  function preload() {
725
762
  return _preload.apply(this, arguments);
@@ -1052,14 +1089,15 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1052
1089
  var _loadOrdersByServer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8() {
1053
1090
  var _this5 = this,
1054
1091
  _this$store;
1055
- var orderList, protectedOrdersBeforeRemoteFetch, data, mergedOrders, memoryOrders;
1092
+ var orderList, hasFetchedRemoteSnapshot, protectedOrdersBeforeRemoteFetch, data, _yield$this$replaceOr, mergedOrders, isRemoteSnapshotPersisted, memoryOrders;
1056
1093
  return _regeneratorRuntime().wrap(function _callee8$(_context8) {
1057
1094
  while (1) switch (_context8.prev = _context8.next) {
1058
1095
  case 0:
1059
1096
  orderList = [];
1060
- _context8.next = 3;
1097
+ hasFetchedRemoteSnapshot = false;
1098
+ _context8.next = 4;
1061
1099
  return this.loadOrdersFromSQLite();
1062
- case 3:
1100
+ case 4:
1063
1101
  protectedOrdersBeforeRemoteFetch = _context8.sent.filter(function (order) {
1064
1102
  return _this5.shouldProtectLocalOrderFromRemoteSnapshot(order);
1065
1103
  });
@@ -1072,51 +1110,59 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1072
1110
  }, 0)
1073
1111
  });
1074
1112
  if (!this.orderDataSource) {
1075
- _context8.next = 20;
1113
+ _context8.next = 21;
1076
1114
  break;
1077
1115
  }
1078
- _context8.prev = 6;
1079
- _context8.next = 9;
1116
+ _context8.prev = 7;
1117
+ _context8.next = 10;
1080
1118
  return this.orderDataSource.run({
1081
1119
  sse: {
1082
1120
  query: this.store.createdAtQuery
1083
1121
  }
1084
1122
  });
1085
- case 9:
1123
+ case 10:
1086
1124
  data = _context8.sent;
1087
1125
  orderList = data || [];
1088
1126
  this.logInfo('loadOrdersByServer-SSE拉取成功', {
1089
1127
  count: orderList.length
1090
1128
  });
1091
- this.markOrderPulledAtNow();
1129
+ hasFetchedRemoteSnapshot = true;
1092
1130
  this.lastServerFullFetchAtMs = Date.now();
1093
- _context8.next = 20;
1131
+ _context8.next = 21;
1094
1132
  break;
1095
- case 16:
1096
- _context8.prev = 16;
1097
- _context8.t0 = _context8["catch"](6);
1133
+ case 17:
1134
+ _context8.prev = 17;
1135
+ _context8.t0 = _context8["catch"](7);
1098
1136
  this.logInfo('loadOrdersByServer-SSE拉取失败,保持当前内存订单');
1099
1137
  return _context8.abrupt("return", this.store.list);
1100
- case 20:
1101
- _context8.next = 22;
1138
+ case 21:
1139
+ if (hasFetchedRemoteSnapshot) {
1140
+ this.clearOrderSnapshotMarker();
1141
+ }
1142
+ _context8.next = 24;
1102
1143
  return this.replaceOrdersSnapshotInSQLite(orderList, 'loadOrdersByServer', protectedOrdersBeforeRemoteFetch);
1103
- case 22:
1104
- mergedOrders = _context8.sent;
1144
+ case 24:
1145
+ _yield$this$replaceOr = _context8.sent;
1146
+ mergedOrders = _yield$this$replaceOr.orders;
1147
+ isRemoteSnapshotPersisted = _yield$this$replaceOr.persisted;
1148
+ if (hasFetchedRemoteSnapshot && isRemoteSnapshotPersisted) {
1149
+ this.markOrderPulledAtNow();
1150
+ }
1105
1151
  memoryOrders = this.normalizeOrdersForMemoryList(mergedOrders, 'loadOrdersByServer.memory');
1106
1152
  this.logInfo('loadOrdersByServer-结束', {
1107
1153
  count: memoryOrders.length,
1108
1154
  persistedCount: mergedOrders.length,
1109
1155
  sqliteOnlyDraftCount: mergedOrders.length - memoryOrders.length
1110
1156
  });
1111
- _context8.next = 27;
1157
+ _context8.next = 32;
1112
1158
  return this.core.effects.emit(OrderHooks.onOrdersLoaded, memoryOrders);
1113
- case 27:
1159
+ case 32:
1114
1160
  return _context8.abrupt("return", memoryOrders);
1115
- case 28:
1161
+ case 33:
1116
1162
  case "end":
1117
1163
  return _context8.stop();
1118
1164
  }
1119
- }, _callee8, this, [[6, 16]]);
1165
+ }, _callee8, this, [[7, 17]]);
1120
1166
  }));
1121
1167
  function loadOrdersByServer() {
1122
1168
  return _loadOrdersByServer.apply(this, arguments);
@@ -1331,7 +1377,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1331
1377
  _context11.next = 4;
1332
1378
  break;
1333
1379
  }
1334
- this.logInfo('upsertOrdersFromRemote-订单列表为空', {});
1380
+ this.logInfo('upsertOrdersFromRemote-订单列表为空', {
1381
+ source: source
1382
+ });
1335
1383
  return _context11.abrupt("return");
1336
1384
  case 4:
1337
1385
  this.logInfo('upsertOrdersFromRemote-开始', {
@@ -2638,6 +2686,11 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2638
2686
  value: function isRemoteEchoMergeSource(source) {
2639
2687
  return source === 'pubsub.bodyUpsert' || source === 'pubsub.httpRefresh';
2640
2688
  }
2689
+ }, {
2690
+ key: "isRemoteProductMembershipChangeSource",
2691
+ value: function isRemoteProductMembershipChangeSource(source) {
2692
+ return this.isRemoteEchoMergeSource(source) || source === 'manual.editOpenRemoteCheck';
2693
+ }
2641
2694
  }, {
2642
2695
  key: "getProductMembershipKey",
2643
2696
  value: function getProductMembershipKey(product) {
@@ -2677,7 +2730,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2677
2730
  value: function getRemoteProductMembershipChange(existingOrder, mergedOrder, source) {
2678
2731
  var _this17 = this,
2679
2732
  _mergedOrder$order_id;
2680
- if (!this.isRemoteEchoMergeSource(source)) return null;
2733
+ if (!this.isRemoteProductMembershipChangeSource(source)) return null;
2681
2734
  var previousProducts = Array.isArray(existingOrder.products) ? existingOrder.products : [];
2682
2735
  var currentProducts = Array.isArray(mergedOrder.products) ? mergedOrder.products : [];
2683
2736
  var unmatchedCurrentIndexes = new Set(currentProducts.map(function (_, index) {
@@ -3186,25 +3239,32 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3186
3239
  }
3187
3240
 
3188
3241
  /**
3189
- * 当前订单拉取窗口:
3190
- * - 优先使用 createdAtQuery.sales_time_between(已按营业日边界初始化)
3191
- * - 无法解析时退化为自然日窗口
3242
+ * 当前订单缓存可复用窗口。
3243
+ * start_time 模式使用精确的营业日起止时间;配置缺失或异常时退化为自然日。
3192
3244
  */
3193
3245
  }, {
3194
- key: "getCurrentPullWindow",
3195
- value: function getCurrentPullWindow() {
3196
- var _this$store2;
3246
+ key: "getCurrentOrderCacheWindow",
3247
+ value: function getCurrentOrderCacheWindow() {
3197
3248
  var now = dayjs();
3198
- var range = (_this$store2 = this.store) === null || _this$store2 === void 0 || (_this$store2 = _this$store2.createdAtQuery) === null || _this$store2 === void 0 ? void 0 : _this$store2.sales_time_between;
3199
- if (Array.isArray(range) && range.length >= 2) {
3200
- var _startAt = dayjs(range[0]);
3201
- var endExclusiveAt = dayjs(range[1]);
3202
- if (_startAt.isValid() && endExclusiveAt.isValid() && endExclusiveAt.isAfter(_startAt)) {
3203
- return {
3204
- startAt: _startAt,
3205
- endExclusiveAt: endExclusiveAt
3206
- };
3249
+ try {
3250
+ var _coreData$core;
3251
+ var appPlugin = this.core.getPlugin('app');
3252
+ var app = appPlugin === null || appPlugin === void 0 ? void 0 : appPlugin.getApp();
3253
+ var coreData = app === null || app === void 0 ? void 0 : app.data.store.getStore().getDataByModel('core');
3254
+ var boundary = coreData === null || coreData === void 0 || (_coreData$core = coreData.core) === null || _coreData$core === void 0 ? void 0 : _coreData$core.operating_day_boundary;
3255
+ if ((boundary === null || boundary === void 0 ? void 0 : boundary.type) === 'start_time') {
3256
+ var boundaryTime = String(boundary.time || '').trim();
3257
+ var todayBoundary = dayjs("".concat(now.format('YYYY-MM-DD'), " ").concat(boundaryTime));
3258
+ if (todayBoundary.isValid()) {
3259
+ var _startAt = now.isBefore(todayBoundary) ? todayBoundary.subtract(1, 'day') : todayBoundary;
3260
+ return {
3261
+ startAt: _startAt,
3262
+ endExclusiveAt: _startAt.add(1, 'day')
3263
+ };
3264
+ }
3207
3265
  }
3266
+ } catch (_unused6) {
3267
+ // 读取营业日配置失败时按自然日兜底,不影响启动。
3208
3268
  }
3209
3269
  var startAt = now.startOf('day');
3210
3270
  return {
@@ -3217,20 +3277,47 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3217
3277
  value: function hasPulledOrdersToday() {
3218
3278
  var lastFullFetchAt = this.getStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY);
3219
3279
  if (!lastFullFetchAt) return false;
3280
+ var currentShopId = this.getCurrentShopId();
3281
+ var lastFullFetchShopId = this.getStorageItem(ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY);
3282
+ if (!currentShopId || !lastFullFetchShopId || currentShopId !== lastFullFetchShopId) {
3283
+ return false;
3284
+ }
3220
3285
  var parsed = dayjs(lastFullFetchAt);
3221
3286
  if (!parsed.isValid()) return false;
3222
-
3223
- // 按当前拉取窗口判断,而不是自然日判断。
3224
- // 这样在营业日跨日边界(start_time)场景下也能正确判定是否需要重新拉取。
3225
- var _this$getCurrentPullW = this.getCurrentPullWindow(),
3226
- startAt = _this$getCurrentPullW.startAt,
3227
- endExclusiveAt = _this$getCurrentPullW.endExclusiveAt;
3287
+ var _this$getCurrentOrder = this.getCurrentOrderCacheWindow(),
3288
+ startAt = _this$getCurrentOrder.startAt,
3289
+ endExclusiveAt = _this$getCurrentOrder.endExclusiveAt;
3228
3290
  return (parsed.isAfter(startAt) || parsed.isSame(startAt)) && parsed.isBefore(endExclusiveAt);
3229
3291
  }
3230
3292
  }, {
3231
3293
  key: "markOrderPulledAtNow",
3232
3294
  value: function markOrderPulledAtNow() {
3295
+ var currentShopId = this.getCurrentShopId();
3296
+ if (!currentShopId) return;
3233
3297
  this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, dayjs().format('YYYY-MM-DD HH:mm:ss'));
3298
+ this.setStorageItem(ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY, currentShopId);
3299
+ }
3300
+ }, {
3301
+ key: "clearOrderSnapshotMarker",
3302
+ value: function clearOrderSnapshotMarker() {
3303
+ this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, '');
3304
+ this.setStorageItem(ORDER_LAST_FULL_FETCH_SHOP_ID_STORAGE_KEY, '');
3305
+ }
3306
+ }, {
3307
+ key: "getCurrentShopId",
3308
+ value: function getCurrentShopId() {
3309
+ try {
3310
+ var _coreData$core2;
3311
+ var appPlugin = this.core.getPlugin('app');
3312
+ var app = appPlugin === null || appPlugin === void 0 ? void 0 : appPlugin.getApp();
3313
+ if (!app) return null;
3314
+ var coreData = app.data.store.getStore().getDataByModel('core');
3315
+ var shopId = coreData === null || coreData === void 0 || (_coreData$core2 = coreData.core) === null || _coreData$core2 === void 0 ? void 0 : _coreData$core2.id;
3316
+ if (shopId === undefined || shopId === null || shopId === '') return null;
3317
+ return String(shopId);
3318
+ } catch (_unused7) {
3319
+ return null;
3320
+ }
3234
3321
  }
3235
3322
  }, {
3236
3323
  key: "getStorageItem",
@@ -3241,7 +3328,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3241
3328
  if (typeof globalThis !== 'undefined' && globalThis !== null && globalThis !== void 0 && globalThis.localStorage) {
3242
3329
  return globalThis.localStorage.getItem(key);
3243
3330
  }
3244
- } catch (_unused6) {
3331
+ } catch (_unused8) {
3245
3332
  // 忽略存储异常,避免影响主流程
3246
3333
  }
3247
3334
  return null;
@@ -3258,7 +3345,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3258
3345
  if (typeof globalThis !== 'undefined' && globalThis !== null && globalThis !== void 0 && globalThis.localStorage) {
3259
3346
  globalThis.localStorage.setItem(key, value);
3260
3347
  }
3261
- } catch (_unused7) {
3348
+ } catch (_unused9) {
3262
3349
  // 忽略存储异常,避免影响主流程
3263
3350
  }
3264
3351
  }
@@ -3267,33 +3354,42 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3267
3354
  value: function () {
3268
3355
  var _loadOrdersFromSQLite = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee20() {
3269
3356
  var _this20 = this;
3270
- var orders;
3357
+ var options,
3358
+ orders,
3359
+ _args20 = arguments;
3271
3360
  return _regeneratorRuntime().wrap(function _callee20$(_context20) {
3272
3361
  while (1) switch (_context20.prev = _context20.next) {
3273
3362
  case 0:
3363
+ options = _args20.length > 0 && _args20[0] !== undefined ? _args20[0] : {};
3274
3364
  if (this.dbManager) {
3275
- _context20.next = 2;
3365
+ _context20.next = 3;
3276
3366
  break;
3277
3367
  }
3278
3368
  return _context20.abrupt("return", []);
3279
- case 2:
3280
- _context20.prev = 2;
3281
- _context20.next = 5;
3369
+ case 3:
3370
+ _context20.prev = 3;
3371
+ _context20.next = 6;
3282
3372
  return this.dbManager.getAll(INDEXDB_STORE_NAME);
3283
- case 5:
3373
+ case 6:
3284
3374
  orders = _context20.sent;
3285
3375
  return _context20.abrupt("return", (orders || []).map(function (order) {
3286
3376
  return _this20.normalizeOrderCollectionsForIngress(order, 'loadOrdersFromSQLite');
3287
3377
  }));
3288
- case 9:
3289
- _context20.prev = 9;
3290
- _context20.t0 = _context20["catch"](2);
3378
+ case 10:
3379
+ _context20.prev = 10;
3380
+ _context20.t0 = _context20["catch"](3);
3381
+ if (!options.throwOnError) {
3382
+ _context20.next = 14;
3383
+ break;
3384
+ }
3385
+ throw _context20.t0;
3386
+ case 14:
3291
3387
  return _context20.abrupt("return", []);
3292
- case 12:
3388
+ case 15:
3293
3389
  case "end":
3294
3390
  return _context20.stop();
3295
3391
  }
3296
- }, _callee20, this, [[2, 9]]);
3392
+ }, _callee20, this, [[3, 10]]);
3297
3393
  }));
3298
3394
  function loadOrdersFromSQLite() {
3299
3395
  return _loadOrdersFromSQLite.apply(this, arguments);
@@ -3733,7 +3829,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3733
3829
  * 用于 SSE 全量拉取与营业日窗口裁剪。
3734
3830
  *
3735
3831
  * @example
3736
- * await this.replaceOrdersSnapshotInSQLite(orderList)
3832
+ * const { orders, persisted } = await this.replaceOrdersSnapshotInSQLite(orderList, 'refresh')
3737
3833
  */
3738
3834
  )
3739
3835
  }, {
@@ -3744,6 +3840,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3744
3840
  var protectedOrdersBeforeRemoteFetch,
3745
3841
  remoteSnapshot,
3746
3842
  mergedSnapshot,
3843
+ persisted,
3747
3844
  _args27 = arguments;
3748
3845
  return _regeneratorRuntime().wrap(function _callee27$(_context27) {
3749
3846
  while (1) switch (_context27.prev = _context27.next) {
@@ -3753,9 +3850,12 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3753
3850
  _context27.next = 3;
3754
3851
  break;
3755
3852
  }
3756
- return _context27.abrupt("return", this.compactOrderListByIdentity(orderList.map(function (order) {
3757
- return _this24.normalizeRemoteSyncedOrder(order);
3758
- }), "".concat(source, ".snapshotNoDb")).list);
3853
+ return _context27.abrupt("return", {
3854
+ orders: this.compactOrderListByIdentity(orderList.map(function (order) {
3855
+ return _this24.normalizeRemoteSyncedOrder(order);
3856
+ }), "".concat(source, ".snapshotNoDb")).list,
3857
+ persisted: false
3858
+ });
3759
3859
  case 3:
3760
3860
  remoteSnapshot = cloneDeep(orderList).map(function (order) {
3761
3861
  return _this24.normalizeOrderCollectionsForIngress(order, "".concat(source, ".remoteIngress"));
@@ -3763,8 +3863,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3763
3863
  mergedSnapshot = this.compactOrderListByIdentity(remoteSnapshot.map(function (order) {
3764
3864
  return _this24.normalizeRemoteSyncedOrder(order);
3765
3865
  }), "".concat(source, ".remoteSnapshot")).list;
3766
- _context27.prev = 5;
3767
- _context27.next = 8;
3866
+ persisted = false;
3867
+ _context27.prev = 6;
3868
+ _context27.next = 9;
3768
3869
  return this.runInOrderSQLiteSaveQueue( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee26() {
3769
3870
  var existingOrders, protectedLocalOrders, _iterator33, _step33, rawCurrentOrder, currentOrder, protectedIndex, currentNeedsProtection, orderListSnapshot;
3770
3871
  return _regeneratorRuntime().wrap(function _callee26$(_context26) {
@@ -3877,23 +3978,27 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3877
3978
  }
3878
3979
  }, _callee26, null, [[10, 25, 28, 31]]);
3879
3980
  })));
3880
- case 8:
3881
- _context27.next = 13;
3981
+ case 9:
3982
+ persisted = true;
3983
+ _context27.next = 15;
3882
3984
  break;
3883
- case 10:
3884
- _context27.prev = 10;
3885
- _context27.t0 = _context27["catch"](5);
3985
+ case 12:
3986
+ _context27.prev = 12;
3987
+ _context27.t0 = _context27["catch"](6);
3886
3988
  this.logError('全量保存订单到 SQLite 失败', {
3887
3989
  error: _context27.t0 instanceof Error ? _context27.t0.message : String(_context27.t0),
3888
3990
  orderList: remoteSnapshot.length
3889
3991
  });
3890
- case 13:
3891
- return _context27.abrupt("return", mergedSnapshot);
3892
- case 14:
3992
+ case 15:
3993
+ return _context27.abrupt("return", {
3994
+ orders: mergedSnapshot,
3995
+ persisted: persisted
3996
+ });
3997
+ case 16:
3893
3998
  case "end":
3894
3999
  return _context27.stop();
3895
4000
  }
3896
- }, _callee27, this, [[5, 10]]);
4001
+ }, _callee27, this, [[6, 12]]);
3897
4002
  }));
3898
4003
  function replaceOrdersSnapshotInSQLite(_x20, _x21) {
3899
4004
  return _replaceOrdersSnapshotInSQLite.apply(this, arguments);
@@ -3935,7 +4040,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
3935
4040
  }, _callee28);
3936
4041
  })));
3937
4042
  case 5:
3938
- this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, '');
4043
+ this.clearOrderSnapshotMarker();
3939
4044
  this.emitOrdersChanged([], 'clear');
3940
4045
  case 7:
3941
4046
  case "end":
@@ -568,7 +568,7 @@ export interface OrderChangedPayload {
568
568
  /** 触发来源,便于订阅者区分 pubsub / 远端覆盖 / 清空等场景 */
569
569
  source?: string;
570
570
  }
571
- export type RemoteProductMembershipChangeSource = 'pubsub.bodyUpsert' | 'pubsub.httpRefresh';
571
+ export type RemoteProductMembershipChangeSource = 'pubsub.bodyUpsert' | 'pubsub.httpRefresh' | 'manual.editOpenRemoteCheck';
572
572
  /**
573
573
  * 远端订单快照相对本地订单产生商品成员增删时的广播载荷。
574
574
  * 只表达商品行成员关系变化,不包含数量、价格、备注等字段级修改。
@@ -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
  * 刷新桥接器内的报价单列表。
@@ -78,6 +78,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
78
78
  _defineProperty(_assertThisInitialized(_this), "quotationBridgeLoadedKey", '');
79
79
  _defineProperty(_assertThisInitialized(_this), "quotationBridgeRefreshPromise", void 0);
80
80
  _defineProperty(_assertThisInitialized(_this), "quotationBridgeRefreshKey", void 0);
81
+ _defineProperty(_assertThisInitialized(_this), "quotationBridgeUpdatedCallback", void 0);
81
82
  _defineProperty(_assertThisInitialized(_this), "quotationScheduleCache", new Map());
82
83
  _defineProperty(_assertThisInitialized(_this), "quotationScheduleCacheSource", null);
83
84
  _defineProperty(_assertThisInitialized(_this), "quotationScheduleCacheLoaded", false);
@@ -290,7 +291,9 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
290
291
  value: (function () {
291
292
  var _setupQuotationPriceBridge = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(params) {
292
293
  var _this$otherParams,
293
- _this3 = this;
294
+ _this3 = this,
295
+ _this$quotationPriceB,
296
+ _this$quotationPriceB2;
294
297
  var channel, quotation;
295
298
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {
296
299
  while (1) switch (_context3.prev = _context3.next) {
@@ -351,11 +354,20 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
351
354
  return schedules[0];
352
355
  });
353
356
  }
354
- _context3.next = 13;
357
+ if (params.onQuotationUpdated) {
358
+ this.quotationBridgeUpdatedCallback = params.onQuotationUpdated;
359
+ }
360
+ (_this$quotationPriceB = (_this$quotationPriceB2 = this.quotationPriceBridge).setQuotationListUpdatedListener) === null || _this$quotationPriceB === void 0 || _this$quotationPriceB.call(_this$quotationPriceB2, function () {
361
+ var _this3$quotationBridg;
362
+ _this3.quotationBridgeLoadedKey = _this3.getQuotationBridgeScopeKey();
363
+ _this3.clearPriceCache();
364
+ (_this3$quotationBridg = _this3.quotationBridgeUpdatedCallback) === null || _this3$quotationBridg === void 0 || _this3$quotationBridg.call(_this3);
365
+ });
366
+ _context3.next = 15;
355
367
  return this.refreshQuotationPriceBridge({
356
368
  customer_id: params.customer_id
357
369
  });
358
- case 13:
370
+ case 15:
359
371
  case "end":
360
372
  return _context3.stop();
361
373
  }
@@ -1202,6 +1214,8 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1202
1214
  key: "clearPriceCache",
1203
1215
  value: function clearPriceCache() {
1204
1216
  this.productsPriceCache.clear();
1217
+ this.quotationScheduleCache.clear();
1218
+ this.quotationScheduleCacheLoaded = false;
1205
1219
  console.log('[ProductsModule] 🗑️ 商品价格缓存已清空');
1206
1220
  }
1207
1221
 
@@ -149,41 +149,49 @@ export var ResourceModule = /*#__PURE__*/function (_BaseModule) {
149
149
  while (1) switch (_context2.prev = _context2.next) {
150
150
  case 0:
151
151
  _context2.next = 2;
152
- return this.setupResourceSync();
153
- case 2:
154
- _context2.next = 4;
155
152
  return this.loadResourcesFromSQLite();
156
- case 4:
153
+ case 2:
157
154
  cachedResources = _context2.sent;
158
155
  if (!(cachedResources.length > 0)) {
159
- _context2.next = 12;
156
+ _context2.next = 10;
160
157
  break;
161
158
  }
162
159
  this.store.list = cloneDeep(cachedResources).map(function (item) {
163
160
  return _this3.normalizeResource(item);
164
161
  });
165
162
  this.syncResourcesMap();
166
- _context2.next = 10;
163
+ _context2.next = 8;
167
164
  return this.safeEmit(ResourceHooks.onResourcesChanged, this.store.list);
165
+ case 8:
166
+ // 二次启动优先使用 SQLite。pubsub 注册及远端校准继续在后台执行,
167
+ // setupResourceSync 完成后会合并最新数据并回写 SQLite。
168
+ void this.setupResourceSync().catch(function (error) {
169
+ _this3.logError('后台初始化资源同步失败', error);
170
+ });
171
+ return _context2.abrupt("return");
168
172
  case 10:
169
- _context2.next = 20;
170
- break;
173
+ _context2.next = 12;
174
+ return this.setupResourceSync();
171
175
  case 12:
172
- _context2.next = 14;
176
+ if (!(this.store.list.length === 0)) {
177
+ _context2.next = 21;
178
+ break;
179
+ }
180
+ _context2.next = 15;
173
181
  return this.loadResourcesByServer();
174
- case 14:
182
+ case 15:
175
183
  resources = _context2.sent;
176
184
  if (!(resources.length > 0)) {
177
- _context2.next = 20;
185
+ _context2.next = 21;
178
186
  break;
179
187
  }
180
188
  this.store.list = cloneDeep(resources).map(function (item) {
181
189
  return _this3.normalizeResource(item);
182
190
  });
183
191
  this.syncResourcesMap();
184
- _context2.next = 20;
192
+ _context2.next = 21;
185
193
  return this.safeEmit(ResourceHooks.onResourcesChanged, this.store.list);
186
- case 20:
194
+ case 21:
187
195
  case "end":
188
196
  return _context2.stop();
189
197
  }
@@ -12,8 +12,15 @@ declare class PisellOSCore implements PisellCore {
12
12
  context: BusinessContext;
13
13
  server: any;
14
14
  serverOptions?: ServerOptions;
15
+ private serverModulePromise?;
15
16
  constructor(options?: PisellOSOptions);
16
17
  private initialize;
18
+ /**
19
+ * 仅预加载 Server 模块代码,不创建实例、不注册模块、不请求业务数据。
20
+ * 导入失败会清空 Promise,正式 initializeServer 时仍可重新尝试。
21
+ */
22
+ preloadServerModule(): Promise<void>;
23
+ private loadServerModule;
17
24
  /**
18
25
  * 初始化 Server(公开方法,需要外部显式调用并等待)
19
26
  * Server 配置从构造函数传入的 options.server 中获取