@pisell/pisellos 2.2.260 → 2.2.262

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 (107) hide show
  1. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +1 -0
  2. package/dist/model/strategy/adapter/dataVariant/adapter.js +15 -0
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +2 -0
  4. package/dist/model/strategy/adapter/dataVariant/evaluator.js +25 -0
  5. package/dist/model/strategy/adapter/dataVariant/examples.js +1 -6
  6. package/dist/model/strategy/adapter/dataVariant/type.d.ts +2 -0
  7. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  8. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +23 -13
  9. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  10. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  11. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +32 -1
  12. package/dist/modules/Discount/index.d.ts +5 -2
  13. package/dist/modules/Discount/index.js +30 -7
  14. package/dist/modules/Discount/types.d.ts +4 -0
  15. package/dist/modules/Order/index.d.ts +45 -2
  16. package/dist/modules/Order/index.js +1552 -926
  17. package/dist/modules/Order/types.d.ts +36 -2
  18. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  19. package/dist/modules/Order/utils/bundleDiscountHydration.js +144 -0
  20. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  21. package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
  22. package/dist/modules/Order/utils.d.ts +8 -3
  23. package/dist/modules/Order/utils.js +136 -56
  24. package/dist/modules/Rules/index.d.ts +4 -10
  25. package/dist/modules/Rules/index.js +63 -12
  26. package/dist/modules/Rules/types.d.ts +12 -2
  27. package/dist/modules/SalesSummary/index.d.ts +7 -3
  28. package/dist/modules/SalesSummary/index.js +67 -39
  29. package/dist/modules/SalesSummary/types.d.ts +1 -0
  30. package/dist/modules/SalesSummary/utils.js +2 -1
  31. package/dist/modules/SurchargeList/index.d.ts +6 -4
  32. package/dist/modules/SurchargeList/index.js +62 -39
  33. package/dist/modules/SurchargeList/types.d.ts +6 -2
  34. package/dist/server/index.d.ts +8 -0
  35. package/dist/server/index.js +1365 -911
  36. package/dist/server/modules/order/index.d.ts +32 -7
  37. package/dist/server/modules/order/index.js +551 -464
  38. package/dist/server/modules/order/types.d.ts +4 -0
  39. package/dist/server/modules/products/index.d.ts +5 -1
  40. package/dist/server/modules/products/index.js +384 -315
  41. package/dist/server/modules/products/types.d.ts +4 -0
  42. package/dist/solution/BaseSales/index.d.ts +42 -2
  43. package/dist/solution/BaseSales/index.js +1416 -775
  44. package/dist/solution/BaseSales/types.d.ts +7 -1
  45. package/dist/solution/BaseSales/types.js +3 -2
  46. package/dist/solution/BaseSales/utils/cartPromotion.js +19 -7
  47. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
  48. package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
  49. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +20 -4
  50. package/dist/solution/BookingByStep/index.d.ts +1 -1
  51. package/dist/solution/BookingTicket/index.d.ts +8 -0
  52. package/dist/solution/BookingTicket/index.js +212 -31
  53. package/dist/solution/ShopDiscount/index.js +15 -14
  54. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +1 -0
  55. package/lib/model/strategy/adapter/dataVariant/adapter.js +10 -0
  56. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +2 -0
  57. package/lib/model/strategy/adapter/dataVariant/evaluator.js +20 -1
  58. package/lib/model/strategy/adapter/dataVariant/examples.js +0 -2
  59. package/lib/model/strategy/adapter/dataVariant/type.d.ts +2 -0
  60. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  61. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +16 -1
  62. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +1 -0
  63. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  64. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +23 -2
  65. package/lib/modules/Discount/index.d.ts +5 -2
  66. package/lib/modules/Discount/index.js +23 -3
  67. package/lib/modules/Discount/types.d.ts +4 -0
  68. package/lib/modules/Order/index.d.ts +45 -2
  69. package/lib/modules/Order/index.js +720 -116
  70. package/lib/modules/Order/types.d.ts +36 -2
  71. package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  72. package/lib/modules/Order/utils/bundleDiscountHydration.js +139 -0
  73. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  74. package/lib/modules/Order/utils/orderCollectionIdentity.js +415 -0
  75. package/lib/modules/Order/utils.d.ts +8 -3
  76. package/lib/modules/Order/utils.js +104 -18
  77. package/lib/modules/Rules/index.d.ts +4 -10
  78. package/lib/modules/Rules/index.js +61 -9
  79. package/lib/modules/Rules/types.d.ts +12 -2
  80. package/lib/modules/SalesSummary/index.d.ts +7 -3
  81. package/lib/modules/SalesSummary/index.js +28 -11
  82. package/lib/modules/SalesSummary/types.d.ts +1 -0
  83. package/lib/modules/SalesSummary/utils.js +2 -0
  84. package/lib/modules/SurchargeList/index.d.ts +6 -4
  85. package/lib/modules/SurchargeList/index.js +41 -21
  86. package/lib/modules/SurchargeList/types.d.ts +6 -2
  87. package/lib/server/index.d.ts +8 -0
  88. package/lib/server/index.js +336 -11
  89. package/lib/server/modules/order/index.d.ts +32 -7
  90. package/lib/server/modules/order/index.js +298 -189
  91. package/lib/server/modules/order/types.d.ts +4 -0
  92. package/lib/server/modules/products/index.d.ts +5 -1
  93. package/lib/server/modules/products/index.js +21 -0
  94. package/lib/server/modules/products/types.d.ts +4 -0
  95. package/lib/solution/BaseSales/index.d.ts +42 -2
  96. package/lib/solution/BaseSales/index.js +535 -108
  97. package/lib/solution/BaseSales/types.d.ts +7 -1
  98. package/lib/solution/BaseSales/types.js +2 -1
  99. package/lib/solution/BaseSales/utils/cartPromotion.js +13 -1
  100. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
  101. package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
  102. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -6
  103. package/lib/solution/BookingByStep/index.d.ts +1 -1
  104. package/lib/solution/BookingTicket/index.d.ts +8 -0
  105. package/lib/solution/BookingTicket/index.js +134 -8
  106. package/lib/solution/ShopDiscount/index.js +2 -1
  107. package/package.json +1 -1
@@ -33,6 +33,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
33
33
  import { cloneDeep } from 'lodash-es';
34
34
  import dayjs from 'dayjs';
35
35
  import { BaseModule } from "../../../modules/BaseModule";
36
+ import { applyOrderCollectionUidRemaps, getOrderCollectionPersistentId, getOrderCollectionReferenceUid, getOrderCollectionUid, isSameOrderCollectionItem, mergeOrderCollectionItems, normalizeOrderCollections } from "../../../modules/Order/utils/orderCollectionIdentity";
36
37
  import { OrderHooks } from "./types";
37
38
 
38
39
  /**
@@ -49,6 +50,19 @@ var ORDER_SILENT_REFRESH_MIN_INTERVAL_MS = 30000;
49
50
  /** 视为「业务侧刚写入」的来源,pubsub 回声可跳过 SQLite */
50
51
  var ORDER_BUSINESS_WRITE_SOURCES = new Set(['upsertOrdersFromRemote', 'upsertPendingSyncOrders', 'overwriteExistingOrder', 'markOrderSyncedByExternalSaleNumber']);
51
52
 
53
+ /**
54
+ * 合并热路径全表去重自检开关:默认关闭。
55
+ * 开启后每次合并会额外对整张 store 做一次 O(n^2) 重复检测并告警,
56
+ * 仅用于排查增量身份索引是否遗漏了重复订单,不应在生产常开。
57
+ */
58
+ var ORDER_MERGE_SELF_CHECK = false;
59
+ var ORDER_AUTHORITATIVE_COLLECTION_FIELDS = ['products', 'bookings', 'payments'];
60
+ var ORDER_COLLECTION_KIND_BY_FIELD = {
61
+ products: 'product',
62
+ bookings: 'booking',
63
+ payments: 'payment'
64
+ };
65
+
52
66
  /**
53
67
  * Order 模块 - 基础框架
54
68
  */
@@ -68,8 +82,6 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
68
82
  _defineProperty(_assertThisInitialized(_this), "syncTimer", void 0);
69
83
  _defineProperty(_assertThisInitialized(_this), "isProcessingSyncBatch", false);
70
84
  _defineProperty(_assertThisInitialized(_this), "isIdlePhase", true);
71
- // Map<resource_id, OrderId[]> 资源到订单的倒排索引
72
- _defineProperty(_assertThisInitialized(_this), "resourceIdIndex", new Map());
73
85
  _defineProperty(_assertThisInitialized(_this), "logger", void 0);
74
86
  // LoggerManager 实例
75
87
  _defineProperty(_assertThisInitialized(_this), "storage", void 0);
@@ -228,6 +240,104 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
228
240
  }
229
241
  }
230
242
 
243
+ /**
244
+ * 在订单进入内存或 SQLite 前统一压缩子项强身份重复并补齐协议 UID。
245
+ * 仅记录计数与订单标识,不输出商品、预约、支付或客户明细。
246
+ */
247
+ }, {
248
+ key: "normalizeOrderCollectionsForIngress",
249
+ value: function normalizeOrderCollectionsForIngress(order, source) {
250
+ var result = normalizeOrderCollections(order);
251
+ var kinds = ['product', 'booking', 'payment'];
252
+ var hasChanges = kinds.some(function (kind) {
253
+ var stats = result.stats[kind];
254
+ return stats.backfilledUidCount > 0 || stats.collapsedDuplicateCount > 0 || stats.uidConflictCount > 0 || stats.anonymousRowCount > 0;
255
+ });
256
+ if (hasChanges) {
257
+ var _order$order_id, _external_sale_number;
258
+ var summarize = function summarize(stats) {
259
+ return {
260
+ backfilled_uid_count: stats.backfilledUidCount,
261
+ collapsed_duplicate_count: stats.collapsedDuplicateCount,
262
+ uid_conflict_count: stats.uidConflictCount,
263
+ anonymous_row_count: stats.anonymousRowCount
264
+ };
265
+ };
266
+ var context = {
267
+ source: source,
268
+ order_id: (_order$order_id = order === null || order === void 0 ? void 0 : order.order_id) !== null && _order$order_id !== void 0 ? _order$order_id : null,
269
+ external_sale_number: (_external_sale_number = order === null || order === void 0 ? void 0 : order.external_sale_number) !== null && _external_sale_number !== void 0 ? _external_sale_number : null,
270
+ products: summarize(result.stats.product),
271
+ bookings: summarize(result.stats.booking),
272
+ payments: summarize(result.stats.payment)
273
+ };
274
+ var hasUnsafeIdentity = kinds.some(function (kind) {
275
+ var stats = result.stats[kind];
276
+ return stats.uidConflictCount > 0 || stats.anonymousRowCount > 0;
277
+ });
278
+ if (hasUnsafeIdentity) {
279
+ this.logWarning('订单子项身份存在冲突或匿名行', context);
280
+ } else {
281
+ this.logInfo('订单子项身份已规范化', context);
282
+ }
283
+ }
284
+ return result.order;
285
+ }
286
+
287
+ /**
288
+ * incoming 决定权威成员集合;同一持久化行仍从 existing 补齐 incoming 省略的本地展示字段。
289
+ */
290
+ }, {
291
+ key: "mergeAuthoritativeOrderCollection",
292
+ value: function mergeAuthoritativeOrderCollection(field, existing, incoming) {
293
+ var uidRemaps = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
294
+ var kind = ORDER_COLLECTION_KIND_BY_FIELD[field];
295
+ var existingItems = Array.isArray(existing) ? existing : [];
296
+ return incoming.map(function (incomingItem) {
297
+ var existingItem = existingItems.find(function (item) {
298
+ return isSameOrderCollectionItem(kind, item, incomingItem);
299
+ });
300
+ if (!existingItem) return cloneDeep(incomingItem);
301
+ var mergedItem = mergeOrderCollectionItems(kind, existingItem, incomingItem);
302
+ var mergedUid = getOrderCollectionUid(kind, mergedItem);
303
+ if (mergedUid) {
304
+ var _iterator = _createForOfIteratorHelper(new Set([getOrderCollectionReferenceUid(kind, existingItem), getOrderCollectionReferenceUid(kind, incomingItem)])),
305
+ _step;
306
+ try {
307
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
308
+ var from = _step.value;
309
+ if (!from || from === mergedUid) continue;
310
+ uidRemaps.push({
311
+ kind: kind,
312
+ from: from,
313
+ to: mergedUid,
314
+ persistentId: getOrderCollectionPersistentId(kind, incomingItem) || getOrderCollectionPersistentId(kind, existingItem)
315
+ });
316
+ }
317
+ } catch (err) {
318
+ _iterator.e(err);
319
+ } finally {
320
+ _iterator.f();
321
+ }
322
+ }
323
+ return mergedItem;
324
+ });
325
+ }
326
+ }, {
327
+ key: "reconcileOverwriteOrderCollections",
328
+ value: function reconcileOverwriteOrderCollections(existing, incoming) {
329
+ var reconciled = cloneDeep(incoming);
330
+ var existingRecord = existing;
331
+ var incomingRecord = incoming;
332
+ var uidRemaps = [];
333
+ for (var _i = 0, _ORDER_AUTHORITATIVE_ = ORDER_AUTHORITATIVE_COLLECTION_FIELDS; _i < _ORDER_AUTHORITATIVE_.length; _i++) {
334
+ var field = _ORDER_AUTHORITATIVE_[_i];
335
+ if (!Array.isArray(incomingRecord[field])) continue;
336
+ reconciled[field] = this.mergeAuthoritativeOrderCollection(field, existingRecord[field], incomingRecord[field], uidRemaps);
337
+ }
338
+ return this.normalizeOrderCollectionsForIngress(applyOrderCollectionUidRemaps(reconciled, uidRemaps), 'overwriteExistingOrder.reconciled');
339
+ }
340
+
231
341
  /**
232
342
  * 记录订单最近一次 SQLite 写入,供 pubsub 回声去重使用。
233
343
  *
@@ -238,11 +348,11 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
238
348
  key: "recordRecentSqliteWrite",
239
349
  value: function recordRecentSqliteWrite(source, orders) {
240
350
  var now = Date.now();
241
- var _iterator = _createForOfIteratorHelper(orders),
242
- _step;
351
+ var _iterator2 = _createForOfIteratorHelper(orders),
352
+ _step2;
243
353
  try {
244
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
245
- var order = _step.value;
354
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
355
+ var order = _step2.value;
246
356
  var storageKey = this.getOrderStorageKey(order);
247
357
  if (!storageKey) continue;
248
358
  this.recentSqliteWriteByStorageKey.set(storageKey, {
@@ -251,9 +361,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
251
361
  });
252
362
  }
253
363
  } catch (err) {
254
- _iterator.e(err);
364
+ _iterator2.e(err);
255
365
  } finally {
256
- _iterator.f();
366
+ _iterator2.f();
257
367
  }
258
368
  }
259
369
 
@@ -276,11 +386,11 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
276
386
  var now = Date.now();
277
387
  var toWrite = [];
278
388
  var skipped = [];
279
- var _iterator2 = _createForOfIteratorHelper(orders),
280
- _step2;
389
+ var _iterator3 = _createForOfIteratorHelper(orders),
390
+ _step3;
281
391
  try {
282
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
283
- var order = _step2.value;
392
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
393
+ var order = _step3.value;
284
394
  var storageKey = this.getOrderStorageKey(order);
285
395
  if (!storageKey) {
286
396
  toWrite.push(order);
@@ -296,9 +406,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
296
406
  }
297
407
  var recent = this.recentSqliteWriteByStorageKey.get(storageKey);
298
408
  if (recent && ORDER_BUSINESS_WRITE_SOURCES.has(recent.source) && now - recent.ts < ORDER_SQLITE_DEDUPE_MS) {
299
- var _order$order_id;
409
+ var _order$order_id2;
300
410
  skipped.push({
301
- orderId: (_order$order_id = order.order_id) !== null && _order$order_id !== void 0 ? _order$order_id : null,
411
+ orderId: (_order$order_id2 = order.order_id) !== null && _order$order_id2 !== void 0 ? _order$order_id2 : null,
302
412
  storageKey: storageKey,
303
413
  reason: 'skip_pubsub_echo_after_business_write',
304
414
  lastSource: recent.source,
@@ -309,9 +419,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
309
419
  toWrite.push(order);
310
420
  }
311
421
  } catch (err) {
312
- _iterator2.e(err);
422
+ _iterator3.e(err);
313
423
  } finally {
314
- _iterator2.f();
424
+ _iterator3.f();
315
425
  }
316
426
  return {
317
427
  toWrite: toWrite,
@@ -331,11 +441,11 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
331
441
  var now = Date.now();
332
442
  var toFetch = [];
333
443
  var skipped = [];
334
- var _iterator3 = _createForOfIteratorHelper(ids),
335
- _step3;
444
+ var _iterator4 = _createForOfIteratorHelper(ids),
445
+ _step4;
336
446
  try {
337
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
338
- var id = _step3.value;
447
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
448
+ var id = _step4.value;
339
449
  var existing = this.getOrderByOrderId(id);
340
450
  if (!existing) {
341
451
  toFetch.push(id);
@@ -354,9 +464,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
354
464
  toFetch.push(id);
355
465
  }
356
466
  } catch (err) {
357
- _iterator3.e(err);
467
+ _iterator4.e(err);
358
468
  } finally {
359
- _iterator3.f();
469
+ _iterator4.f();
360
470
  }
361
471
  return {
362
472
  toFetch: toFetch,
@@ -443,9 +553,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
443
553
  var appPlugin = this.core.getPlugin('app');
444
554
  var app = appPlugin === null || appPlugin === void 0 ? void 0 : appPlugin.getApp();
445
555
  if (app) {
446
- var _this$store$createdAt;
447
556
  var coreData = app.data.store.getStore().getDataByModel('core');
448
- if (!((_this$store$createdAt = this.store.createdAtQuery) !== null && _this$store$createdAt !== void 0 && _this$store$createdAt.sales_time_between) && coreData !== null && coreData !== void 0 && coreData.core) {
557
+ if (coreData !== null && coreData !== void 0 && coreData.core) {
449
558
  var today = dayjs();
450
559
  if (coreData !== null && coreData !== void 0 && coreData.core.operating_day_boundary) {
451
560
  var operatingDayBoundary = coreData.core.operating_day_boundary;
@@ -774,28 +883,19 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
774
883
  }
775
884
  return silentRefresh;
776
885
  }())
777
- }, {
778
- key: "getOrdersByResourceId",
779
- value: function getOrdersByResourceId(resourceId) {
780
- var _this8 = this;
781
- var ids = this.resourceIdIndex.get(String(resourceId)) || [];
782
- return ids.map(function (id) {
783
- return _this8.store.map.get(id);
784
- }).filter(function (order) {
785
- return !!order;
786
- });
787
- }
788
886
  }, {
789
887
  key: "normalizeOrderForMemoryList",
790
888
  value: function normalizeOrderForMemoryList(order) {
791
- var externalSaleNumber = order === null || order === void 0 ? void 0 : order.external_sale_number;
792
- if ((order === null || order === void 0 ? void 0 : order.order_id) !== undefined && (order === null || order === void 0 ? void 0 : order.order_id) !== null && (order === null || order === void 0 ? void 0 : order.order_id) !== '') {
793
- return order;
889
+ var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'normalizeOrderForMemoryList';
890
+ var normalizedOrder = this.normalizeOrderCollectionsForIngress(order, source);
891
+ var externalSaleNumber = normalizedOrder === null || normalizedOrder === void 0 ? void 0 : normalizedOrder.external_sale_number;
892
+ if ((normalizedOrder === null || normalizedOrder === void 0 ? void 0 : normalizedOrder.order_id) !== undefined && (normalizedOrder === null || normalizedOrder === void 0 ? void 0 : normalizedOrder.order_id) !== null && (normalizedOrder === null || normalizedOrder === void 0 ? void 0 : normalizedOrder.order_id) !== '') {
893
+ return normalizedOrder;
794
894
  }
795
895
  if (externalSaleNumber === undefined || externalSaleNumber === null || externalSaleNumber === '') {
796
- return order;
896
+ return normalizedOrder;
797
897
  }
798
- return _objectSpread(_objectSpread({}, order), {}, {
898
+ return _objectSpread(_objectSpread({}, normalizedOrder), {}, {
799
899
  order_id: externalSaleNumber
800
900
  });
801
901
  }
@@ -808,8 +908,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
808
908
  key: "overwriteExistingOrder",
809
909
  value: (function () {
810
910
  var _overwriteExistingOrder = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(fresh) {
811
- var _this9 = this;
812
- var orderId, key;
911
+ var _this8 = this;
912
+ var orderId, key, normalizedFresh, existingOrder, reconciledFresh;
813
913
  return _regeneratorRuntime().wrap(function _callee8$(_context8) {
814
914
  while (1) switch (_context8.prev = _context8.next) {
815
915
  case 0:
@@ -839,26 +939,31 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
839
939
  orderId: orderId,
840
940
  storeOrderCountBefore: this.store.list.length
841
941
  });
942
+ normalizedFresh = this.normalizeOrderForMemoryList(fresh, 'overwriteExistingOrder.incoming');
943
+ existingOrder = this.store.map.get(key);
944
+ reconciledFresh = this.reconcileOverwriteOrderCollections(existingOrder, normalizedFresh);
842
945
  this.store.list = this.store.list.map(function (order) {
843
946
  var id = order === null || order === void 0 ? void 0 : order.order_id;
844
- if (id === undefined || id === null) return order;
845
- return _this9.getIdKey(id) === key ? fresh : order;
947
+ if (id === undefined || id === null) {
948
+ return _this8.normalizeOrderForMemoryList(order, 'overwriteExistingOrder.existingMemory');
949
+ }
950
+ return _this8.getIdKey(id) === key ? reconciledFresh : _this8.normalizeOrderForMemoryList(order, 'overwriteExistingOrder.existingMemory');
846
951
  });
847
952
  this.syncOrdersMap();
848
- _context8.next = 13;
849
- return this.updateOrderInSQLite(fresh, 'overwriteExistingOrder');
850
- case 13:
953
+ _context8.next = 16;
954
+ return this.updateOrderInSQLite(reconciledFresh, 'overwriteExistingOrder');
955
+ case 16:
851
956
  this.logInfo('overwriteExistingOrder-结束', {
852
957
  orderId: orderId,
853
958
  storeOrderCountAfter: this.store.list.length
854
959
  });
855
- _context8.next = 16;
856
- return this.emitOrdersChanged([fresh], 'overwriteExistingOrder');
857
- case 16:
960
+ _context8.next = 19;
961
+ return this.emitOrdersChanged([reconciledFresh], 'overwriteExistingOrder');
962
+ case 19:
858
963
  return _context8.abrupt("return", {
859
964
  overwritten: true
860
965
  });
861
- case 17:
966
+ case 20:
862
967
  case "end":
863
968
  return _context8.stop();
864
969
  }
@@ -908,7 +1013,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
908
1013
  key: "markOrderSyncedByExternalSaleNumber",
909
1014
  value: function () {
910
1015
  var _markOrderSyncedByExternalSaleNumber = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(params) {
911
- var _this10 = this,
1016
+ var _this9 = this,
912
1017
  _existing$external_sa,
913
1018
  _nextOrder$order_id;
914
1019
  var externalSaleNumber, key, targetIndex, existing, nextOrder, storageKey;
@@ -929,7 +1034,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
929
1034
  targetIndex = this.store.list.findIndex(function (order) {
930
1035
  var value = order === null || order === void 0 ? void 0 : order.external_sale_number;
931
1036
  if (value === undefined || value === null || value === '') return false;
932
- return _this10.getIdKey(value) === key;
1037
+ return _this9.getIdKey(value) === key;
933
1038
  });
934
1039
  if (!(targetIndex < 0)) {
935
1040
  _context10.next = 9;
@@ -986,7 +1091,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
986
1091
  key: "upsertPendingSyncOrders",
987
1092
  value: (function () {
988
1093
  var _upsertPendingSyncOrders = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(pendingOrders) {
989
- var pendingMap, memoryPendingMap, _iterator4, _step4, order, storageKey, patchedOrders, mergeActions, updatedList, _iterator5, _step5, _step5$value, _storageKey, pendingOrder, matchIndex, _iterator6, _step6, _step6$value, _storageKey2, _order;
1094
+ var _this10 = this;
1095
+ var pendingMap, memoryPendingMap, _iterator5, _step5, order, normalizedOrder, storageKey, mergeActions, updatedList, identityKeyToIndex, index, _iterator6, _step6, key, _iterator7, _step7, _step7$value, _storageKey, pendingOrder, matchIndex, existingOrder, mergedOrder, pendingSnapshot, insertIndex, patchedOrders;
990
1096
  return _regeneratorRuntime().wrap(function _callee11$(_context11) {
991
1097
  while (1) switch (_context11.prev = _context11.next) {
992
1098
  case 0:
@@ -999,119 +1105,134 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
999
1105
  case 3:
1000
1106
  pendingMap = new Map();
1001
1107
  memoryPendingMap = new Map();
1002
- _iterator4 = _createForOfIteratorHelper(pendingOrders);
1108
+ _iterator5 = _createForOfIteratorHelper(pendingOrders);
1003
1109
  _context11.prev = 6;
1004
- _iterator4.s();
1110
+ _iterator5.s();
1005
1111
  case 8:
1006
- if ((_step4 = _iterator4.n()).done) {
1007
- _context11.next = 17;
1112
+ if ((_step5 = _iterator5.n()).done) {
1113
+ _context11.next = 18;
1008
1114
  break;
1009
1115
  }
1010
- order = _step4.value;
1011
- storageKey = this.getOrderStorageKey(order);
1116
+ order = _step5.value;
1117
+ normalizedOrder = this.normalizeOrderCollectionsForIngress(order, 'upsertPendingSyncOrders.incoming');
1118
+ storageKey = this.getOrderStorageKey(normalizedOrder);
1012
1119
  if (storageKey) {
1013
- _context11.next = 13;
1120
+ _context11.next = 14;
1014
1121
  break;
1015
1122
  }
1016
- return _context11.abrupt("continue", 15);
1017
- case 13:
1018
- pendingMap.set(storageKey, order);
1019
- memoryPendingMap.set(storageKey, this.normalizeOrderForMemoryList(order));
1020
- case 15:
1123
+ return _context11.abrupt("continue", 16);
1124
+ case 14:
1125
+ pendingMap.set(storageKey, normalizedOrder);
1126
+ memoryPendingMap.set(storageKey, this.normalizeOrderForMemoryList(normalizedOrder, 'upsertPendingSyncOrders.memory'));
1127
+ case 16:
1021
1128
  _context11.next = 8;
1022
1129
  break;
1023
- case 17:
1024
- _context11.next = 22;
1130
+ case 18:
1131
+ _context11.next = 23;
1025
1132
  break;
1026
- case 19:
1027
- _context11.prev = 19;
1133
+ case 20:
1134
+ _context11.prev = 20;
1028
1135
  _context11.t0 = _context11["catch"](6);
1029
- _iterator4.e(_context11.t0);
1030
- case 22:
1031
- _context11.prev = 22;
1032
- _iterator4.f();
1033
- return _context11.finish(22);
1034
- case 25:
1136
+ _iterator5.e(_context11.t0);
1137
+ case 23:
1138
+ _context11.prev = 23;
1139
+ _iterator5.f();
1140
+ return _context11.finish(23);
1141
+ case 26:
1035
1142
  if (!(pendingMap.size === 0)) {
1036
- _context11.next = 28;
1143
+ _context11.next = 29;
1037
1144
  break;
1038
1145
  }
1039
1146
  this.logError('upsertPendingSyncOrders-订单缺少可落库标识', {
1040
1147
  count: pendingOrders.length
1041
1148
  });
1042
1149
  return _context11.abrupt("return");
1043
- case 28:
1150
+ case 29:
1044
1151
  this.logInfo('upsertPendingSyncOrders-开始', {
1045
1152
  count: pendingMap.size
1046
1153
  });
1047
- patchedOrders = _toConsumableArray(pendingMap.values());
1048
1154
  mergeActions = {};
1049
- updatedList = _toConsumableArray(this.store.list);
1050
- _iterator5 = _createForOfIteratorHelper(memoryPendingMap.entries());
1051
- _context11.prev = 33;
1052
- _iterator5.s();
1053
- case 35:
1054
- if ((_step5 = _iterator5.n()).done) {
1055
- _context11.next = 46;
1155
+ updatedList = this.store.list.map(function (order) {
1156
+ return _this10.normalizeOrderForMemoryList(order, 'upsertPendingSyncOrders.existingMemory');
1157
+ }); // 与 mergeOrdersToStore 一致:基于身份键(field:value)建立索引,把「查找已存在订单」
1158
+ // 从 O(n) 线性扫描降为 O(1),整体复杂度由 O(n^2) 降为 O(n + m)。
1159
+ identityKeyToIndex = new Map();
1160
+ for (index = 0; index < updatedList.length; index += 1) {
1161
+ _iterator6 = _createForOfIteratorHelper(this.getOrderIdentityMatchKeys(updatedList[index]));
1162
+ try {
1163
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
1164
+ key = _step6.value;
1165
+ // 同一 key 命中多张时保留最靠前的下标,与原 findIndex「取首个匹配」一致
1166
+ if (!identityKeyToIndex.has(key)) identityKeyToIndex.set(key, index);
1167
+ }
1168
+ } catch (err) {
1169
+ _iterator6.e(err);
1170
+ } finally {
1171
+ _iterator6.f();
1172
+ }
1173
+ }
1174
+ _iterator7 = _createForOfIteratorHelper(memoryPendingMap.entries());
1175
+ _context11.prev = 35;
1176
+ _iterator7.s();
1177
+ case 37:
1178
+ if ((_step7 = _iterator7.n()).done) {
1179
+ _context11.next = 55;
1056
1180
  break;
1057
1181
  }
1058
- _step5$value = _slicedToArray(_step5.value, 2), _storageKey = _step5$value[0], pendingOrder = _step5$value[1];
1059
- matchIndex = this.findOrderIndexByIdentity(updatedList, pendingOrder);
1060
- if (!(matchIndex < 0)) {
1061
- _context11.next = 40;
1182
+ _step7$value = _slicedToArray(_step7.value, 2), _storageKey = _step7$value[0], pendingOrder = _step7$value[1];
1183
+ matchIndex = this.lookupOrderIndexByIdentityKeys(identityKeyToIndex, this.getOrderIdentityMatchKeys(pendingOrder));
1184
+ if (!(matchIndex >= 0)) {
1185
+ _context11.next = 49;
1062
1186
  break;
1063
1187
  }
1064
- return _context11.abrupt("continue", 44);
1065
- case 40:
1066
- updatedList[matchIndex] = this.mergeOrderRecords(updatedList[matchIndex], pendingOrder, {
1067
- preferIncomingProducts: true
1068
- });
1069
- pendingMap.delete(_storageKey);
1070
- memoryPendingMap.delete(_storageKey);
1188
+ existingOrder = updatedList[matchIndex];
1189
+ mergedOrder = this.mergeOrderRecords(existingOrder, pendingOrder);
1190
+ updatedList[matchIndex] = mergedOrder;
1191
+ pendingSnapshot = pendingMap.get(_storageKey);
1192
+ if (pendingSnapshot) {
1193
+ pendingMap.set(_storageKey, this.reconcileOverwriteOrderCollections(existingOrder, pendingSnapshot));
1194
+ }
1195
+ // 合并后身份字段可能新增(如挂单拿到 order_id),同步登记,供同批后续 pending 命中同一槽位
1196
+ this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex);
1071
1197
  mergeActions[_storageKey] = 'update';
1072
- case 44:
1073
- _context11.next = 35;
1198
+ return _context11.abrupt("continue", 53);
1199
+ case 49:
1200
+ insertIndex = updatedList.length;
1201
+ updatedList.push(pendingOrder);
1202
+ this.registerOrderIdentityKeys(identityKeyToIndex, pendingOrder, insertIndex);
1203
+ mergeActions[_storageKey] = 'insert';
1204
+ case 53:
1205
+ _context11.next = 37;
1074
1206
  break;
1075
- case 46:
1076
- _context11.next = 51;
1207
+ case 55:
1208
+ _context11.next = 60;
1077
1209
  break;
1078
- case 48:
1079
- _context11.prev = 48;
1080
- _context11.t1 = _context11["catch"](33);
1081
- _iterator5.e(_context11.t1);
1082
- case 51:
1083
- _context11.prev = 51;
1084
- _iterator5.f();
1085
- return _context11.finish(51);
1086
- case 54:
1087
- _iterator6 = _createForOfIteratorHelper(memoryPendingMap.entries());
1088
- try {
1089
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
1090
- _step6$value = _slicedToArray(_step6.value, 2), _storageKey2 = _step6$value[0], _order = _step6$value[1];
1091
- mergeActions[_storageKey2] = 'insert';
1092
- updatedList.push(_order);
1093
- }
1094
- } catch (err) {
1095
- _iterator6.e(err);
1096
- } finally {
1097
- _iterator6.f();
1098
- }
1099
- this.store.list = this.compactOrderListByIdentity(updatedList, 'upsertPendingSyncOrders.store').list;
1210
+ case 57:
1211
+ _context11.prev = 57;
1212
+ _context11.t1 = _context11["catch"](35);
1213
+ _iterator7.e(_context11.t1);
1214
+ case 60:
1215
+ _context11.prev = 60;
1216
+ _iterator7.f();
1217
+ return _context11.finish(60);
1218
+ case 63:
1219
+ patchedOrders = _toConsumableArray(pendingMap.values()); // 增量索引已保证 store 去重不变量,无需再对全表做 O(n^2) 压缩;仅自检开关开启时兜底。
1220
+ this.store.list = this.runOrderStoreSelfCheck(updatedList, 'upsertPendingSyncOrders.store');
1100
1221
  this.syncOrdersMap();
1101
- _context11.next = 60;
1222
+ _context11.next = 68;
1102
1223
  return this.patchOrdersInSQLite(patchedOrders, 'upsertPendingSyncOrders', mergeActions);
1103
- case 60:
1224
+ case 68:
1104
1225
  this.logInfo('upsertPendingSyncOrders-结束', {
1105
1226
  count: patchedOrders.length,
1106
1227
  storeOrderCountAfter: this.store.list.length
1107
1228
  });
1108
- _context11.next = 63;
1229
+ _context11.next = 71;
1109
1230
  return this.emitOrdersChanged(patchedOrders, 'upsertPendingSyncOrders');
1110
- case 63:
1231
+ case 71:
1111
1232
  case "end":
1112
1233
  return _context11.stop();
1113
1234
  }
1114
- }, _callee11, this, [[6, 19, 22, 25], [33, 48, 51, 54]]);
1235
+ }, _callee11, this, [[6, 20, 23, 26], [35, 57, 60, 63]]);
1115
1236
  }));
1116
1237
  function upsertPendingSyncOrders(_x7) {
1117
1238
  return _upsertPendingSyncOrders.apply(this, arguments);
@@ -1188,44 +1309,20 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1188
1309
  }, {
1189
1310
  key: "syncOrdersMap",
1190
1311
  value: function syncOrdersMap() {
1191
- var _this11 = this;
1192
1312
  this.store.map.clear();
1193
- this.resourceIdIndex.clear();
1194
- var _iterator7 = _createForOfIteratorHelper(this.store.list),
1195
- _step7;
1313
+ var _iterator8 = _createForOfIteratorHelper(this.store.list),
1314
+ _step8;
1196
1315
  try {
1197
- var _loop = function _loop() {
1198
- var order = _step7.value;
1199
- var primaryIdentity = _this11.getOrderMapKey(order);
1200
- if (!primaryIdentity) return 1; // continue
1201
- _this11.store.map.set(primaryIdentity, order);
1202
- var resourceIds = _this11.extractResourceIds(order);
1203
- var _iterator8 = _createForOfIteratorHelper(resourceIds),
1204
- _step8;
1205
- try {
1206
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
1207
- var resourceId = _step8.value;
1208
- var key = String(resourceId);
1209
- var existing = _this11.resourceIdIndex.get(key) || [];
1210
- if (existing.some(function (eid) {
1211
- return _this11.getIdKey(eid) === primaryIdentity;
1212
- })) continue;
1213
- existing.push(primaryIdentity);
1214
- _this11.resourceIdIndex.set(key, existing);
1215
- }
1216
- } catch (err) {
1217
- _iterator8.e(err);
1218
- } finally {
1219
- _iterator8.f();
1220
- }
1221
- };
1222
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
1223
- if (_loop()) continue;
1316
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
1317
+ var order = _step8.value;
1318
+ var primaryIdentity = this.getOrderMapKey(order);
1319
+ if (!primaryIdentity) continue;
1320
+ this.store.map.set(primaryIdentity, order);
1224
1321
  }
1225
1322
  } catch (err) {
1226
- _iterator7.e(err);
1323
+ _iterator8.e(err);
1227
1324
  } finally {
1228
- _iterator7.f();
1325
+ _iterator8.f();
1229
1326
  }
1230
1327
  }
1231
1328
  }, {
@@ -1249,7 +1346,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1249
1346
  }, {
1250
1347
  key: "getOrderIdentityEntries",
1251
1348
  value: function getOrderIdentityEntries(order) {
1252
- var _this12 = this;
1349
+ var _this11 = this;
1253
1350
  if (!order) return [];
1254
1351
  var record = order;
1255
1352
  var candidates = [{
@@ -1266,10 +1363,10 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1266
1363
  value: record.shop_order_number
1267
1364
  }];
1268
1365
  var entries = [];
1269
- var _loop2 = function _loop2() {
1270
- var candidate = _candidates[_i];
1271
- if (_this12.isBlankIdentityValue(candidate.value)) return 0; // continue
1272
- var key = _this12.getIdKey(candidate.value);
1366
+ var _loop = function _loop() {
1367
+ var candidate = _candidates[_i2];
1368
+ if (_this11.isBlankIdentityValue(candidate.value)) return 0; // continue
1369
+ var key = _this11.getIdKey(candidate.value);
1273
1370
  if (entries.some(function (entry) {
1274
1371
  return entry.field === candidate.field && entry.key === key;
1275
1372
  })) return 0; // continue
@@ -1279,8 +1376,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1279
1376
  });
1280
1377
  },
1281
1378
  _ret;
1282
- for (var _i = 0, _candidates = candidates; _i < _candidates.length; _i++) {
1283
- _ret = _loop2();
1379
+ for (var _i2 = 0, _candidates = candidates; _i2 < _candidates.length; _i2++) {
1380
+ _ret = _loop();
1284
1381
  if (_ret === 0) continue;
1285
1382
  }
1286
1383
  return entries;
@@ -1303,32 +1400,13 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1303
1400
  }
1304
1401
  return keys;
1305
1402
  }
1306
- }, {
1307
- key: "extractResourceIds",
1308
- value: function extractResourceIds(order) {
1309
- var ids = new Set();
1310
- var visitResources = function visitResources(resources) {
1311
- if (!Array.isArray(resources)) return;
1312
- resources.forEach(function (resource) {
1313
- var rid = resource === null || resource === void 0 ? void 0 : resource.relation_id;
1314
- if (rid !== undefined && rid !== null && rid !== '') ids.add(String(rid));
1315
- if (Array.isArray(resource === null || resource === void 0 ? void 0 : resource.children)) visitResources(resource.children);
1316
- });
1317
- };
1318
- if (Array.isArray(order === null || order === void 0 ? void 0 : order.bookings)) {
1319
- order.bookings.forEach(function (booking) {
1320
- return visitResources((booking === null || booking === void 0 ? void 0 : booking.resources) || []);
1321
- });
1322
- }
1323
- return _toConsumableArray(ids);
1324
- }
1325
1403
  }, {
1326
1404
  key: "getOrderDateKey",
1327
1405
  value: function getOrderDateKey(order) {
1328
1406
  var _order$bookings, _order$bookings2;
1329
1407
  var candidates = [order === null || order === void 0 ? void 0 : order.schedule_date, order === null || order === void 0 ? void 0 : order.create_date, order === null || order === void 0 ? void 0 : order.created_at, order === null || order === void 0 || (_order$bookings = order.bookings) === null || _order$bookings === void 0 || (_order$bookings = _order$bookings[0]) === null || _order$bookings === void 0 ? void 0 : _order$bookings.start_date, order === null || order === void 0 || (_order$bookings2 = order.bookings) === null || _order$bookings2 === void 0 || (_order$bookings2 = _order$bookings2[0]) === null || _order$bookings2 === void 0 ? void 0 : _order$bookings2.select_date];
1330
- for (var _i2 = 0, _candidates2 = candidates; _i2 < _candidates2.length; _i2++) {
1331
- var v = _candidates2[_i2];
1408
+ for (var _i3 = 0, _candidates2 = candidates; _i3 < _candidates2.length; _i3++) {
1409
+ var v = _candidates2[_i3];
1332
1410
  if (!v) continue;
1333
1411
  var text = String(v);
1334
1412
  if (!text) continue;
@@ -1355,7 +1433,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1355
1433
  }, {
1356
1434
  key: "setupOrderSync",
1357
1435
  value: function setupOrderSync() {
1358
- var _this13 = this;
1436
+ var _this12 = this;
1359
1437
  if (!this.orderDataSource) return;
1360
1438
  this.orderDataSource.run({
1361
1439
  pubsub: {
@@ -1363,22 +1441,22 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1363
1441
  var _message$id, _message$order_id, _message$type;
1364
1442
  console.log('orderDataSource', res);
1365
1443
  var pubsubReceivedAt = Date.now();
1366
- var message = _this13.normalizeOrderSyncMessage(res);
1444
+ var message = _this12.normalizeOrderSyncMessage(res);
1367
1445
  if (!message) return;
1368
1446
  message._pubsubReceivedAt = pubsubReceivedAt;
1369
- _this13.pendingSyncMessages.push(message);
1370
- var throttleMs = _this13.getOrderSyncThrottleMs();
1371
- var routeInfo = _this13.resolveSyncMessageRoute(message);
1372
- _this13.logInfo('orderSync-收到消息并入队', {
1447
+ _this12.pendingSyncMessages.push(message);
1448
+ var throttleMs = _this12.getOrderSyncThrottleMs();
1449
+ var routeInfo = _this12.resolveSyncMessageRoute(message);
1450
+ _this12.logInfo('orderSync-收到消息并入队', {
1373
1451
  id: (_message$id = message.id) !== null && _message$id !== void 0 ? _message$id : null,
1374
1452
  order_id: (_message$order_id = message.order_id) !== null && _message$order_id !== void 0 ? _message$order_id : null,
1375
1453
  type: (_message$type = message.type) !== null && _message$type !== void 0 ? _message$type : null,
1376
- pendingCount: _this13.pendingSyncMessages.length,
1454
+ pendingCount: _this12.pendingSyncMessages.length,
1377
1455
  throttleMs: throttleMs,
1378
1456
  pubsubReceivedAt: new Date(pubsubReceivedAt).toISOString(),
1379
1457
  fullMessage: JSON.stringify(message)
1380
1458
  });
1381
- _this13.scheduleOrderSyncThrottle();
1459
+ _this12.scheduleOrderSyncThrottle();
1382
1460
  }
1383
1461
  }
1384
1462
  }).catch(function () {
@@ -1395,7 +1473,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1395
1473
  }, {
1396
1474
  key: "scheduleOrderSyncThrottle",
1397
1475
  value: function scheduleOrderSyncThrottle() {
1398
- var _this14 = this;
1476
+ var _this13 = this;
1399
1477
  if (this.isProcessingSyncBatch) return;
1400
1478
  if (this.isIdlePhase) {
1401
1479
  this.isIdlePhase = false;
@@ -1406,8 +1484,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1406
1484
  if (this.syncTimer) return;
1407
1485
  var throttleMs = this.getOrderSyncThrottleMs();
1408
1486
  this.syncTimer = setTimeout(function () {
1409
- _this14.syncTimer = undefined;
1410
- void _this14.flushOrderSyncMessagesByThrottle();
1487
+ _this13.syncTimer = undefined;
1488
+ void _this13.flushOrderSyncMessagesByThrottle();
1411
1489
  }, throttleMs);
1412
1490
  }
1413
1491
 
@@ -1475,7 +1553,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1475
1553
  key: "processOrderSyncMessages",
1476
1554
  value: (function () {
1477
1555
  var _processOrderSyncMessages = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee14() {
1478
- var _this15 = this;
1556
+ var _this14 = this;
1479
1557
  var messages, batchProcessStartAt, earliestReceivedAt, upsertOrders, refreshIds, uniqueRefreshIds, upsertList, _this$filterRedundant, toFetch, skipped, freshOrders, batchProcessEndAt;
1480
1558
  return _regeneratorRuntime().wrap(function _callee14$(_context14) {
1481
1559
  while (1) switch (_context14.prev = _context14.next) {
@@ -1502,13 +1580,13 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1502
1580
  upsertOrders = new Map();
1503
1581
  refreshIds = [];
1504
1582
  messages.forEach(function (msg, msgIndex) {
1505
- var routeInfo = _this15.resolveSyncMessageRoute(msg);
1583
+ var routeInfo = _this14.resolveSyncMessageRoute(msg);
1506
1584
  var hasBatchIds = routeInfo.hasBatchIds;
1507
1585
  var singleId = routeInfo.singleId;
1508
1586
  var hasSingleId = routeInfo.hasSingleId;
1509
- var normalizedBody = _this15.normalizeOrderSyncPayload(msg.body || msg.data);
1587
+ var normalizedBody = _this14.normalizeOrderSyncPayload(msg.body || msg.data);
1510
1588
  if (routeInfo.route === 'bodyUpsert' && normalizedBody) {
1511
- upsertOrders.set(_this15.getIdKey(normalizedBody.order_id), normalizedBody);
1589
+ upsertOrders.set(_this14.getIdKey(normalizedBody.order_id), normalizedBody);
1512
1590
  return;
1513
1591
  }
1514
1592
  if (hasBatchIds) refreshIds.push.apply(refreshIds, _toConsumableArray(routeInfo.batchIds));else if (routeInfo.route === 'httpRefresh.singleId' && singleId !== null) refreshIds.push(singleId);else if (routeInfo.route === 'httpRefresh.relationIds') refreshIds.push.apply(refreshIds, _toConsumableArray(routeInfo.batchIds));
@@ -1646,94 +1724,140 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1646
1724
  key: "mergeOrdersToStore",
1647
1725
  value: (function () {
1648
1726
  var _mergeOrdersToStore = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee16(freshOrders, source) {
1649
- var normalizedFreshOrders, _iterator10, _step10, order, id, uniqueFreshOrders, uniqueFreshCount, patchedOrders, mergeActions, updatedList, _iterator11, _step11, fresh, matchIndex, storageKey, mergeKey, mergedOrder, insertCount, updateCount;
1727
+ var _this15 = this;
1728
+ var storeOrderCountBefore, normalizedFreshOrders, _iterator10, _step10, order, id, uniqueFreshOrders, uniqueFreshCount, patchedOrders, mergeActions, updatedList, identityKeyToIndex, index, identityKeys, _iterator11, _step11, key, _iterator12, _step12, fresh, freshIdentityKeys, matchIndex, storageKey, mergeKey, existingOrder, _ref2, _existingOrder$order_, _ref3, _external_sale_number2, _existingOrder$paymen, _fresh$payment_status, _existingOrder$need_s, _fresh$need_sync, mergedOrder, insertIndex, insertCount, updateCount;
1650
1729
  return _regeneratorRuntime().wrap(function _callee16$(_context16) {
1651
1730
  while (1) switch (_context16.prev = _context16.next) {
1652
1731
  case 0:
1732
+ storeOrderCountBefore = this.store.list.length;
1653
1733
  this.logInfo('mergeOrdersToStore-开始', {
1654
1734
  freshOrderCount: freshOrders.length,
1655
- storeOrderCountBefore: this.store.list.length,
1735
+ storeOrderCountBefore: storeOrderCountBefore,
1656
1736
  source: source
1657
1737
  });
1658
1738
  this.logDuplicateOrders("".concat(source, ".beforeMerge"), this.store.list);
1659
1739
  normalizedFreshOrders = [];
1660
1740
  _iterator10 = _createForOfIteratorHelper(freshOrders);
1661
- _context16.prev = 4;
1741
+ _context16.prev = 5;
1662
1742
  _iterator10.s();
1663
- case 6:
1743
+ case 7:
1664
1744
  if ((_step10 = _iterator10.n()).done) {
1665
- _context16.next = 14;
1745
+ _context16.next = 15;
1666
1746
  break;
1667
1747
  }
1668
1748
  order = _step10.value;
1669
1749
  id = order === null || order === void 0 ? void 0 : order.order_id;
1670
1750
  if (!(id === undefined || id === null)) {
1671
- _context16.next = 11;
1751
+ _context16.next = 12;
1672
1752
  break;
1673
1753
  }
1674
- return _context16.abrupt("continue", 12);
1675
- case 11:
1676
- normalizedFreshOrders.push(this.normalizeRemoteSyncedOrder(order));
1754
+ return _context16.abrupt("continue", 13);
1677
1755
  case 12:
1678
- _context16.next = 6;
1756
+ normalizedFreshOrders.push(this.normalizeRemoteSyncedOrder(order));
1757
+ case 13:
1758
+ _context16.next = 7;
1679
1759
  break;
1680
- case 14:
1681
- _context16.next = 19;
1760
+ case 15:
1761
+ _context16.next = 20;
1682
1762
  break;
1683
- case 16:
1684
- _context16.prev = 16;
1685
- _context16.t0 = _context16["catch"](4);
1763
+ case 17:
1764
+ _context16.prev = 17;
1765
+ _context16.t0 = _context16["catch"](5);
1686
1766
  _iterator10.e(_context16.t0);
1687
- case 19:
1688
- _context16.prev = 19;
1767
+ case 20:
1768
+ _context16.prev = 20;
1689
1769
  _iterator10.f();
1690
- return _context16.finish(19);
1691
- case 22:
1770
+ return _context16.finish(20);
1771
+ case 23:
1772
+ // 先对本批新单做去重(批内规模 m 很小),保证每条 fresh 身份唯一
1692
1773
  uniqueFreshOrders = this.compactOrderListByIdentity(normalizedFreshOrders, "".concat(source, ".incoming")).list;
1693
1774
  uniqueFreshCount = uniqueFreshOrders.length;
1694
1775
  patchedOrders = [];
1695
1776
  mergeActions = {};
1696
- updatedList = _toConsumableArray(this.store.list);
1697
- _iterator11 = _createForOfIteratorHelper(uniqueFreshOrders);
1698
- _context16.prev = 28;
1699
- _iterator11.s();
1700
- case 30:
1701
- if ((_step11 = _iterator11.n()).done) {
1702
- _context16.next = 46;
1777
+ updatedList = this.store.list.map(function (order) {
1778
+ return _this15.normalizeOrderForMemoryList(order, "".concat(source, ".existingMemory"));
1779
+ }); // 基于身份键(field:value)建立索引,把「查找已存在订单」从 O(n) 线性扫描降为 O(1),
1780
+ // 整体合并复杂度由 O(n^2) 降为 O(n + m)。索引语义与 doOrdersShareIdentity 完全一致:
1781
+ // 任一身份字段(order_id/external_sale_number/order_number/shop_order_number)同值即同一单。
1782
+ identityKeyToIndex = new Map();
1783
+ for (index = 0; index < updatedList.length; index += 1) {
1784
+ identityKeys = this.getOrderIdentityMatchKeys(updatedList[index]);
1785
+ _iterator11 = _createForOfIteratorHelper(identityKeys);
1786
+ try {
1787
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
1788
+ key = _step11.value;
1789
+ // 同一 key 命中多张时保留最靠前的下标,与原 findIndex「取首个匹配」一致
1790
+ if (!identityKeyToIndex.has(key)) identityKeyToIndex.set(key, index);
1791
+ }
1792
+ } catch (err) {
1793
+ _iterator11.e(err);
1794
+ } finally {
1795
+ _iterator11.f();
1796
+ }
1797
+ }
1798
+ _iterator12 = _createForOfIteratorHelper(uniqueFreshOrders);
1799
+ _context16.prev = 31;
1800
+ _iterator12.s();
1801
+ case 33:
1802
+ if ((_step12 = _iterator12.n()).done) {
1803
+ _context16.next = 57;
1703
1804
  break;
1704
1805
  }
1705
- fresh = _step11.value;
1706
- matchIndex = this.findOrderIndexByIdentity(updatedList, fresh);
1806
+ fresh = _step12.value;
1807
+ freshIdentityKeys = this.getOrderIdentityMatchKeys(fresh);
1808
+ matchIndex = this.lookupOrderIndexByIdentityKeys(identityKeyToIndex, freshIdentityKeys);
1707
1809
  storageKey = this.getOrderStorageKey(fresh);
1708
1810
  mergeKey = storageKey || (fresh.order_id !== undefined && fresh.order_id !== null ? this.getIdKey(fresh.order_id) : '');
1709
1811
  if (!(matchIndex >= 0)) {
1710
- _context16.next = 41;
1812
+ _context16.next = 50;
1711
1813
  break;
1712
1814
  }
1713
- mergedOrder = this.mergeOrderRecords(updatedList[matchIndex], fresh);
1815
+ existingOrder = updatedList[matchIndex];
1816
+ if (!(this.isPendingSyncOrder(existingOrder) && this.isRemoteEchoMergeSource(source))) {
1817
+ _context16.next = 44;
1818
+ break;
1819
+ }
1820
+ this.logInfo('mergeOrdersToStore-跳过 pending 订单远端覆盖', {
1821
+ source: source,
1822
+ order_id: (_ref2 = (_existingOrder$order_ = existingOrder.order_id) !== null && _existingOrder$order_ !== void 0 ? _existingOrder$order_ : fresh.order_id) !== null && _ref2 !== void 0 ? _ref2 : null,
1823
+ external_sale_number: (_ref3 = (_external_sale_number2 = existingOrder.external_sale_number) !== null && _external_sale_number2 !== void 0 ? _external_sale_number2 : fresh.external_sale_number) !== null && _ref3 !== void 0 ? _ref3 : null,
1824
+ local_payment_status: (_existingOrder$paymen = existingOrder.payment_status) !== null && _existingOrder$paymen !== void 0 ? _existingOrder$paymen : null,
1825
+ remote_payment_status: (_fresh$payment_status = fresh.payment_status) !== null && _fresh$payment_status !== void 0 ? _fresh$payment_status : null,
1826
+ local_need_sync: (_existingOrder$need_s = existingOrder.need_sync) !== null && _existingOrder$need_s !== void 0 ? _existingOrder$need_s : null,
1827
+ remote_need_sync: (_fresh$need_sync = fresh.need_sync) !== null && _fresh$need_sync !== void 0 ? _fresh$need_sync : null,
1828
+ reason: 'protect_pending_sync_order_from_remote_echo'
1829
+ });
1830
+ return _context16.abrupt("continue", 55);
1831
+ case 44:
1832
+ mergedOrder = this.mergeOrderRecords(existingOrder, fresh);
1714
1833
  updatedList[matchIndex] = mergedOrder;
1834
+ // 合并后身份字段可能新增(如挂单拿到 order_id),同步登记到索引,
1835
+ // 供同批后续 fresh 命中同一槽位,避免重复插入
1836
+ this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex);
1715
1837
  patchedOrders.push(mergedOrder);
1716
1838
  if (mergeKey) mergeActions[mergeKey] = 'update';
1717
- return _context16.abrupt("continue", 44);
1718
- case 41:
1839
+ return _context16.abrupt("continue", 55);
1840
+ case 50:
1841
+ insertIndex = updatedList.length;
1719
1842
  updatedList.push(fresh);
1843
+ this.registerOrderIdentityKeys(identityKeyToIndex, fresh, insertIndex);
1720
1844
  patchedOrders.push(fresh);
1721
1845
  if (mergeKey) mergeActions[mergeKey] = 'insert';
1722
- case 44:
1723
- _context16.next = 30;
1846
+ case 55:
1847
+ _context16.next = 33;
1724
1848
  break;
1725
- case 46:
1726
- _context16.next = 51;
1849
+ case 57:
1850
+ _context16.next = 62;
1727
1851
  break;
1728
- case 48:
1729
- _context16.prev = 48;
1730
- _context16.t1 = _context16["catch"](28);
1731
- _iterator11.e(_context16.t1);
1732
- case 51:
1733
- _context16.prev = 51;
1734
- _iterator11.f();
1735
- return _context16.finish(51);
1736
- case 54:
1852
+ case 59:
1853
+ _context16.prev = 59;
1854
+ _context16.t1 = _context16["catch"](31);
1855
+ _iterator12.e(_context16.t1);
1856
+ case 62:
1857
+ _context16.prev = 62;
1858
+ _iterator12.f();
1859
+ return _context16.finish(62);
1860
+ case 65:
1737
1861
  insertCount = Object.values(mergeActions).filter(function (v) {
1738
1862
  return v === 'insert';
1739
1863
  }).length;
@@ -1745,30 +1869,110 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1745
1869
  updateCount: updateCount,
1746
1870
  storeOrderCountAfter: this.store.list.length
1747
1871
  });
1748
- this.store.list = this.compactOrderListByIdentity(updatedList, "".concat(source, ".store")).list;
1872
+ // 增量索引已保证 store 去重不变量,无需再对全表做 O(n^2) 压缩;
1873
+ // 仅在自检开关开启时做一次兜底校验。
1874
+ this.store.list = this.runOrderStoreSelfCheck(updatedList, "".concat(source, ".store"));
1749
1875
  this.syncOrdersMap();
1750
- _context16.next = 61;
1876
+ _context16.next = 72;
1751
1877
  return this.patchOrdersInSQLite(patchedOrders, source, mergeActions);
1752
- case 61:
1878
+ case 72:
1753
1879
  this.logInfo('mergeOrdersToStore-结束', {
1754
1880
  uniqueFreshCount: uniqueFreshCount,
1755
1881
  storeOrderCountAfter: this.store.list.length,
1756
1882
  insertCount: insertCount,
1757
1883
  updateCount: updateCount
1758
1884
  });
1759
- _context16.next = 64;
1885
+ _context16.next = 75;
1760
1886
  return this.emitOrdersChanged(patchedOrders, source);
1761
- case 64:
1887
+ case 75:
1762
1888
  case "end":
1763
1889
  return _context16.stop();
1764
1890
  }
1765
- }, _callee16, this, [[4, 16, 19, 22], [28, 48, 51, 54]]);
1891
+ }, _callee16, this, [[5, 17, 20, 23], [31, 59, 62, 65]]);
1766
1892
  }));
1767
1893
  function mergeOrdersToStore(_x9, _x10) {
1768
1894
  return _mergeOrdersToStore.apply(this, arguments);
1769
1895
  }
1770
1896
  return mergeOrdersToStore;
1771
- }())
1897
+ }()
1898
+ /**
1899
+ * 在身份索引中查找与目标订单共享任一身份键的已存在订单下标。
1900
+ * 返回所有命中键里最小的下标,等价于原 findOrderIndexByIdentity 的「取首个匹配」语义。
1901
+ *
1902
+ * @example
1903
+ * const idx = this.lookupOrderIndexByIdentityKeys(identityKeyToIndex, freshIdentityKeys)
1904
+ */
1905
+ )
1906
+ }, {
1907
+ key: "lookupOrderIndexByIdentityKeys",
1908
+ value: function lookupOrderIndexByIdentityKeys(identityKeyToIndex, identityKeys) {
1909
+ var matchIndex = -1;
1910
+ var _iterator13 = _createForOfIteratorHelper(identityKeys),
1911
+ _step13;
1912
+ try {
1913
+ for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
1914
+ var key = _step13.value;
1915
+ var index = identityKeyToIndex.get(key);
1916
+ if (index === undefined) continue;
1917
+ if (matchIndex < 0 || index < matchIndex) matchIndex = index;
1918
+ }
1919
+ } catch (err) {
1920
+ _iterator13.e(err);
1921
+ } finally {
1922
+ _iterator13.f();
1923
+ }
1924
+ return matchIndex;
1925
+ }
1926
+ }, {
1927
+ key: "isRemoteEchoMergeSource",
1928
+ value: function isRemoteEchoMergeSource(source) {
1929
+ return source === 'pubsub.bodyUpsert' || source === 'pubsub.httpRefresh';
1930
+ }
1931
+
1932
+ /**
1933
+ * 将订单的全部身份键登记到索引并指向其在列表中的下标。
1934
+ * 合并后订单新增的身份字段(如挂单同步后拿到 order_id)也会被登记。
1935
+ *
1936
+ * @example
1937
+ * this.registerOrderIdentityKeys(identityKeyToIndex, mergedOrder, matchIndex)
1938
+ */
1939
+ }, {
1940
+ key: "registerOrderIdentityKeys",
1941
+ value: function registerOrderIdentityKeys(identityKeyToIndex, order, index) {
1942
+ var identityKeys = this.getOrderIdentityMatchKeys(order);
1943
+ var _iterator14 = _createForOfIteratorHelper(identityKeys),
1944
+ _step14;
1945
+ try {
1946
+ for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
1947
+ var key = _step14.value;
1948
+ identityKeyToIndex.set(key, index);
1949
+ }
1950
+ } catch (err) {
1951
+ _iterator14.e(err);
1952
+ } finally {
1953
+ _iterator14.f();
1954
+ }
1955
+ }
1956
+
1957
+ /**
1958
+ * 合并热路径去重兜底:默认直接返回原列表(增量索引已保证无重复)。
1959
+ * 仅当 ORDER_MERGE_SELF_CHECK 开启时,额外做一次全表压缩并在发现残留重复时告警。
1960
+ */
1961
+ }, {
1962
+ key: "runOrderStoreSelfCheck",
1963
+ value: function runOrderStoreSelfCheck(orders, source) {
1964
+ if (!ORDER_MERGE_SELF_CHECK) return orders;
1965
+ var _this$compactOrderLis = this.compactOrderListByIdentity(orders, source),
1966
+ list = _this$compactOrderLis.list,
1967
+ removedCount = _this$compactOrderLis.removedCount;
1968
+ if (removedCount > 0) {
1969
+ this.logWarning('合并自检发现残留重复订单,已压缩', {
1970
+ source: source,
1971
+ removedCount: removedCount
1972
+ });
1973
+ }
1974
+ return list;
1975
+ }
1772
1976
  }, {
1773
1977
  key: "normalizeOrderSyncMessage",
1774
1978
  value: function normalizeOrderSyncMessage(res) {
@@ -1801,17 +2005,17 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1801
2005
  key: "uniqueOrderIds",
1802
2006
  value: function uniqueOrderIds(ids) {
1803
2007
  var idMap = new Map();
1804
- var _iterator12 = _createForOfIteratorHelper(ids),
1805
- _step12;
2008
+ var _iterator15 = _createForOfIteratorHelper(ids),
2009
+ _step15;
1806
2010
  try {
1807
- for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
1808
- var id = _step12.value;
2011
+ for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
2012
+ var id = _step15.value;
1809
2013
  idMap.set(this.getIdKey(id), id);
1810
2014
  }
1811
2015
  } catch (err) {
1812
- _iterator12.e(err);
2016
+ _iterator15.e(err);
1813
2017
  } finally {
1814
- _iterator12.f();
2018
+ _iterator15.f();
1815
2019
  }
1816
2020
  return _toConsumableArray(idMap.values());
1817
2021
  }
@@ -1898,153 +2102,22 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1898
2102
  if (rightScore >= leftScore) return right;
1899
2103
  return left;
1900
2104
  }
1901
- }, {
1902
- key: "getProductIdentityKeys",
1903
- value: function getProductIdentityKeys(product) {
1904
- var _record$metadata;
1905
- var record = product;
1906
- if (!record) return [];
1907
- var keys = [];
1908
- var metadataUid = (_record$metadata = record.metadata) === null || _record$metadata === void 0 ? void 0 : _record$metadata.unique_identification_number;
1909
- if (!this.isBlankIdentityValue(metadataUid)) keys.push("uid:".concat(String(metadataUid)));
1910
- var topLevelUid = record.unique_identification_number;
1911
- if (!this.isBlankIdentityValue(topLevelUid)) keys.push("uid:".concat(String(topLevelUid)));
1912
- var orderDetailId = record.order_detail_id;
1913
- if (!this.isBlankIdentityValue(orderDetailId)) keys.push("detail:".concat(String(orderDetailId)));
1914
- var bookingUid = record.booking_uid;
1915
- if (!this.isBlankIdentityValue(bookingUid)) keys.push("booking:".concat(String(bookingUid)));
1916
- return keys;
1917
- }
1918
- }, {
1919
- key: "mergeOrderProductLists",
1920
- value: function mergeOrderProductLists(preferred, secondary) {
1921
- var preferredList = Array.isArray(preferred) ? preferred : [];
1922
- var secondaryList = Array.isArray(secondary) ? secondary : [];
1923
- if (secondaryList.length === 0) return preferredList;
1924
- if (preferredList.length === 0) return secondaryList;
1925
- var seenKeys = new Set();
1926
- var _iterator13 = _createForOfIteratorHelper(preferredList),
1927
- _step13;
1928
- try {
1929
- for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
1930
- var item = _step13.value;
1931
- var keys = this.getProductIdentityKeys(item);
1932
- var _iterator15 = _createForOfIteratorHelper(keys),
1933
- _step15;
1934
- try {
1935
- for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
1936
- var key = _step15.value;
1937
- seenKeys.add(key);
1938
- }
1939
- } catch (err) {
1940
- _iterator15.e(err);
1941
- } finally {
1942
- _iterator15.f();
1943
- }
1944
- }
1945
- } catch (err) {
1946
- _iterator13.e(err);
1947
- } finally {
1948
- _iterator13.f();
1949
- }
1950
- var result = _toConsumableArray(preferredList);
1951
- var _iterator14 = _createForOfIteratorHelper(secondaryList),
1952
- _step14;
1953
- try {
1954
- for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
1955
- var _item = _step14.value;
1956
- var _keys = this.getProductIdentityKeys(_item);
1957
- if (_keys.length === 0 || _keys.some(function (key) {
1958
- return seenKeys.has(key);
1959
- })) continue;
1960
- var _iterator16 = _createForOfIteratorHelper(_keys),
1961
- _step16;
1962
- try {
1963
- for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
1964
- var _key = _step16.value;
1965
- seenKeys.add(_key);
1966
- }
1967
- } catch (err) {
1968
- _iterator16.e(err);
1969
- } finally {
1970
- _iterator16.f();
1971
- }
1972
- result.push(cloneDeep(_item));
1973
- }
1974
- } catch (err) {
1975
- _iterator14.e(err);
1976
- } finally {
1977
- _iterator14.f();
1978
- }
1979
- return result;
1980
- }
1981
- }, {
1982
- key: "getPaymentMergeKey",
1983
- value: function getPaymentMergeKey(payment) {
1984
- var _record$metadata2;
1985
- var record = payment;
1986
- if (!record) return '';
1987
- var uniquePaymentNumber = (_record$metadata2 = record.metadata) === null || _record$metadata2 === void 0 ? void 0 : _record$metadata2.unique_payment_number;
1988
- if (!this.isBlankIdentityValue(uniquePaymentNumber)) {
1989
- return "unique:".concat(String(uniquePaymentNumber));
1990
- }
1991
- var orderPaymentId = record.order_payment_id;
1992
- if (!this.isBlankIdentityValue(orderPaymentId)) return "order_payment:".concat(String(orderPaymentId));
1993
- var code = record.code;
1994
- var customPaymentId = record.custom_payment_id;
1995
- if (!this.isBlankIdentityValue(code) && !this.isBlankIdentityValue(customPaymentId)) {
1996
- return "custom:".concat(String(code), "#").concat(String(customPaymentId));
1997
- }
1998
- return '';
1999
- }
2000
- }, {
2001
- key: "mergeOrderPaymentLists",
2002
- value: function mergeOrderPaymentLists(existing, incoming) {
2003
- var _this18 = this;
2004
- var existingList = Array.isArray(existing) ? existing : [];
2005
- var incomingList = Array.isArray(incoming) ? incoming : [];
2006
- if (incomingList.length === 0) return cloneDeep(existingList);
2007
- if (existingList.length === 0) return cloneDeep(incomingList);
2008
- var existingByKey = new Map();
2009
- var _iterator17 = _createForOfIteratorHelper(existingList),
2010
- _step17;
2011
- try {
2012
- for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
2013
- var payment = _step17.value;
2014
- var key = this.getPaymentMergeKey(payment);
2015
- if (!key) continue;
2016
- existingByKey.set(key, payment);
2017
- }
2018
- } catch (err) {
2019
- _iterator17.e(err);
2020
- } finally {
2021
- _iterator17.f();
2022
- }
2023
- return incomingList.map(function (payment) {
2024
- var incomingPayment = payment;
2025
- var key = _this18.getPaymentMergeKey(incomingPayment);
2026
- var existingPayment = key ? existingByKey.get(key) : undefined;
2027
- if (!existingPayment) return cloneDeep(incomingPayment);
2028
- return _objectSpread(_objectSpread(_objectSpread({}, cloneDeep(existingPayment)), cloneDeep(incomingPayment)), {}, {
2029
- metadata: _objectSpread(_objectSpread({}, cloneDeep(existingPayment.metadata || {})), cloneDeep(incomingPayment.metadata || {}))
2030
- });
2031
- });
2032
- }
2033
2105
  }, {
2034
2106
  key: "mergeOrderRecords",
2035
- value: function mergeOrderRecords(existing, incoming, options) {
2107
+ value: function mergeOrderRecords(existing, incoming) {
2036
2108
  var preferred = this.pickPreferredOrder(existing, incoming);
2037
2109
  var secondary = preferred === existing ? incoming : existing;
2038
2110
  var merged = _objectSpread(_objectSpread({}, secondary), preferred);
2039
2111
  var fieldsToPreserve = ['order_id', 'external_sale_number', 'order_number', 'shop_order_number', 'shop_full_order_number'];
2040
- var incomingPatchFields = ['payment_status', 'status', 'shipping_status', 'updated_at', 'shop_discount', 'summary', 'products', 'bookings', 'note', 'customer_id', 'customer_name', 'customer', 'holder', 'contacts_info', 'phone', 'email', 'relation_forms'];
2112
+ var incomingPatchFields = ['payment_status', 'status', 'shipping_status', 'updated_at', 'shop_discount', 'summary', 'note', 'customer_id', 'customer_name', 'customer', 'holder', 'contacts_info', 'phone', 'email', 'relation_forms'];
2041
2113
  var mergedRecord = merged;
2042
2114
  var preferredRecord = preferred;
2043
2115
  var secondaryRecord = secondary;
2116
+ var existingRecord = existing;
2044
2117
  var incomingRecord = incoming;
2045
- var previousRecord = preferred === incoming ? secondaryRecord : preferredRecord;
2046
- for (var _i3 = 0, _fieldsToPreserve = fieldsToPreserve; _i3 < _fieldsToPreserve.length; _i3++) {
2047
- var field = _fieldsToPreserve[_i3];
2118
+ var childUidRemaps = [];
2119
+ for (var _i4 = 0, _fieldsToPreserve = fieldsToPreserve; _i4 < _fieldsToPreserve.length; _i4++) {
2120
+ var field = _fieldsToPreserve[_i4];
2048
2121
  if (!this.isBlankIdentityValue(preferredRecord[field])) {
2049
2122
  mergedRecord[field] = preferredRecord[field];
2050
2123
  continue;
@@ -2053,73 +2126,78 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2053
2126
  mergedRecord[field] = secondaryRecord[field];
2054
2127
  }
2055
2128
  }
2056
- var hasIncomingProducts = Object.prototype.hasOwnProperty.call(incomingRecord, 'products');
2057
- var shouldUseIncomingProductsSnapshot = (options === null || options === void 0 ? void 0 : options.preferIncomingProducts) === true && hasIncomingProducts && incomingRecord.products !== undefined && incomingRecord.products !== null;
2058
- for (var _i4 = 0, _incomingPatchFields = incomingPatchFields; _i4 < _incomingPatchFields.length; _i4++) {
2059
- var _field = _incomingPatchFields[_i4];
2129
+ for (var _i5 = 0, _incomingPatchFields = incomingPatchFields; _i5 < _incomingPatchFields.length; _i5++) {
2130
+ var _field = _incomingPatchFields[_i5];
2060
2131
  if (!Object.prototype.hasOwnProperty.call(incomingRecord, _field)) continue;
2061
2132
  if (incomingRecord[_field] === undefined || incomingRecord[_field] === null) continue;
2062
2133
  if (typeof incomingRecord[_field] === 'string' && incomingRecord[_field] === '') continue;
2063
2134
  mergedRecord[_field] = cloneDeep(incomingRecord[_field]);
2064
2135
  }
2065
- mergedRecord.products = shouldUseIncomingProductsSnapshot ? cloneDeep(incomingRecord.products) : this.mergeOrderProductLists(preferredRecord.products, secondaryRecord.products);
2066
- if (Object.prototype.hasOwnProperty.call(incomingRecord, 'payments')) {
2067
- if (Array.isArray(incomingRecord.payments)) {
2068
- mergedRecord.payments = this.mergeOrderPaymentLists(previousRecord.payments, incomingRecord.payments);
2069
- } else if (incomingRecord.payments !== undefined && incomingRecord.payments !== null) {
2070
- mergedRecord.payments = cloneDeep(incomingRecord.payments);
2136
+
2137
+ // 子项数组遵循完整快照语义:incoming 自有且为数组(包括 [])时权威替换;
2138
+ // 字段缺席或不是数组时视为稀疏 patch,继续保留 existing。
2139
+ for (var _i6 = 0, _ORDER_AUTHORITATIVE_2 = ORDER_AUTHORITATIVE_COLLECTION_FIELDS; _i6 < _ORDER_AUTHORITATIVE_2.length; _i6++) {
2140
+ var _field2 = _ORDER_AUTHORITATIVE_2[_i6];
2141
+ if (Array.isArray(incomingRecord[_field2])) {
2142
+ mergedRecord[_field2] = this.mergeAuthoritativeOrderCollection(_field2, existingRecord[_field2], incomingRecord[_field2], childUidRemaps);
2143
+ continue;
2144
+ }
2145
+ if (Object.prototype.hasOwnProperty.call(existingRecord, _field2)) {
2146
+ mergedRecord[_field2] = cloneDeep(existingRecord[_field2]);
2147
+ } else {
2148
+ delete mergedRecord[_field2];
2071
2149
  }
2072
2150
  }
2073
2151
  if (!this.isPendingSyncOrder(preferred) || !this.isPendingSyncOrder(secondary)) {
2074
2152
  merged.need_sync = 0;
2075
2153
  }
2076
- return merged;
2154
+ return this.normalizeOrderCollectionsForIngress(applyOrderCollectionUidRemaps(merged, childUidRemaps), 'mergeOrderRecords');
2077
2155
  }
2078
2156
  }, {
2079
2157
  key: "summarizeDuplicateOrders",
2080
2158
  value: function summarizeDuplicateOrders(orders) {
2081
2159
  var groups = new Map();
2082
- var _iterator18 = _createForOfIteratorHelper(orders),
2083
- _step18;
2160
+ var _iterator16 = _createForOfIteratorHelper(orders),
2161
+ _step16;
2084
2162
  try {
2085
- for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
2086
- var order = _step18.value;
2087
- var _iterator19 = _createForOfIteratorHelper(this.getOrderIdentityMatchKeys(order)),
2088
- _step19;
2163
+ for (_iterator16.s(); !(_step16 = _iterator16.n()).done;) {
2164
+ var order = _step16.value;
2165
+ var _iterator17 = _createForOfIteratorHelper(this.getOrderIdentityMatchKeys(order)),
2166
+ _step17;
2089
2167
  try {
2090
- for (_iterator19.s(); !(_step19 = _iterator19.n()).done;) {
2091
- var key = _step19.value;
2168
+ for (_iterator17.s(); !(_step17 = _iterator17.n()).done;) {
2169
+ var key = _step17.value;
2092
2170
  var group = groups.get(key) || [];
2093
2171
  group.push(order);
2094
2172
  groups.set(key, group);
2095
2173
  }
2096
2174
  } catch (err) {
2097
- _iterator19.e(err);
2175
+ _iterator17.e(err);
2098
2176
  } finally {
2099
- _iterator19.f();
2177
+ _iterator17.f();
2100
2178
  }
2101
2179
  }
2102
2180
  } catch (err) {
2103
- _iterator18.e(err);
2181
+ _iterator16.e(err);
2104
2182
  } finally {
2105
- _iterator18.f();
2183
+ _iterator16.f();
2106
2184
  }
2107
- return _toConsumableArray(groups.entries()).filter(function (_ref2) {
2108
- var _ref3 = _slicedToArray(_ref2, 2),
2109
- group = _ref3[1];
2110
- return group.length > 1;
2111
- }).slice(0, 20).map(function (_ref4) {
2185
+ return _toConsumableArray(groups.entries()).filter(function (_ref4) {
2112
2186
  var _ref5 = _slicedToArray(_ref4, 2),
2113
- key = _ref5[0],
2114
2187
  group = _ref5[1];
2188
+ return group.length > 1;
2189
+ }).slice(0, 20).map(function (_ref6) {
2190
+ var _ref7 = _slicedToArray(_ref6, 2),
2191
+ key = _ref7[0],
2192
+ group = _ref7[1];
2115
2193
  return {
2116
2194
  key: key,
2117
2195
  count: group.length,
2118
2196
  orders: group.map(function (order) {
2119
- var _order$order_id2, _external_sale_number, _shop_order_number, _shop_full_order_numb, _order$need_sync;
2197
+ var _order$order_id3, _external_sale_number3, _shop_order_number, _shop_full_order_numb, _order$need_sync;
2120
2198
  return {
2121
- order_id: (_order$order_id2 = order.order_id) !== null && _order$order_id2 !== void 0 ? _order$order_id2 : null,
2122
- external_sale_number: (_external_sale_number = order.external_sale_number) !== null && _external_sale_number !== void 0 ? _external_sale_number : null,
2199
+ order_id: (_order$order_id3 = order.order_id) !== null && _order$order_id3 !== void 0 ? _order$order_id3 : null,
2200
+ external_sale_number: (_external_sale_number3 = order.external_sale_number) !== null && _external_sale_number3 !== void 0 ? _external_sale_number3 : null,
2123
2201
  shop_order_number: (_shop_order_number = order.shop_order_number) !== null && _shop_order_number !== void 0 ? _shop_order_number : null,
2124
2202
  shop_full_order_number: (_shop_full_order_numb = order.shop_full_order_number) !== null && _shop_full_order_numb !== void 0 ? _shop_full_order_numb : null,
2125
2203
  need_sync: (_order$need_sync = order.need_sync) !== null && _order$need_sync !== void 0 ? _order$need_sync : null
@@ -2144,23 +2222,24 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2144
2222
  value: function compactOrderListByIdentity(orders, source) {
2145
2223
  var list = [];
2146
2224
  var removedCount = 0;
2147
- var _iterator20 = _createForOfIteratorHelper(orders),
2148
- _step20;
2225
+ var _iterator18 = _createForOfIteratorHelper(orders),
2226
+ _step18;
2149
2227
  try {
2150
- for (_iterator20.s(); !(_step20 = _iterator20.n()).done;) {
2151
- var order = _step20.value;
2152
- var matchIndex = this.findOrderIndexByIdentity(list, order);
2228
+ for (_iterator18.s(); !(_step18 = _iterator18.n()).done;) {
2229
+ var order = _step18.value;
2230
+ var normalizedOrder = this.normalizeOrderCollectionsForIngress(order, "".concat(source, ".order"));
2231
+ var matchIndex = this.findOrderIndexByIdentity(list, normalizedOrder);
2153
2232
  if (matchIndex < 0) {
2154
- list.push(order);
2233
+ list.push(normalizedOrder);
2155
2234
  continue;
2156
2235
  }
2157
- list[matchIndex] = this.mergeOrderRecords(list[matchIndex], order);
2236
+ list[matchIndex] = this.mergeOrderRecords(list[matchIndex], normalizedOrder);
2158
2237
  removedCount += 1;
2159
2238
  }
2160
2239
  } catch (err) {
2161
- _iterator20.e(err);
2240
+ _iterator18.e(err);
2162
2241
  } finally {
2163
- _iterator20.f();
2242
+ _iterator18.f();
2164
2243
  }
2165
2244
  if (removedCount > 0) {
2166
2245
  this.logWarning('订单列表重复项已压缩', {
@@ -2259,6 +2338,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2259
2338
  key: "loadOrdersFromSQLite",
2260
2339
  value: function () {
2261
2340
  var _loadOrdersFromSQLite = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee17() {
2341
+ var _this18 = this;
2262
2342
  var orders;
2263
2343
  return _regeneratorRuntime().wrap(function _callee17$(_context17) {
2264
2344
  while (1) switch (_context17.prev = _context17.next) {
@@ -2274,7 +2354,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2274
2354
  return this.dbManager.getAll(INDEXDB_STORE_NAME);
2275
2355
  case 5:
2276
2356
  orders = _context17.sent;
2277
- return _context17.abrupt("return", orders || []);
2357
+ return _context17.abrupt("return", (orders || []).map(function (order) {
2358
+ return _this18.normalizeOrderCollectionsForIngress(order, 'loadOrdersFromSQLite');
2359
+ }));
2278
2360
  case 9:
2279
2361
  _context17.prev = 9;
2280
2362
  _context17.t0 = _context17["catch"](2);
@@ -2298,8 +2380,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2298
2380
  }, {
2299
2381
  key: "normalizeRemoteSyncedOrder",
2300
2382
  value: function normalizeRemoteSyncedOrder(order) {
2301
- if (this.isPendingSyncOrder(order)) return order;
2302
- return _objectSpread(_objectSpread({}, order), {}, {
2383
+ var normalizedOrder = this.normalizeOrderCollectionsForIngress(order, 'normalizeRemoteSyncedOrder');
2384
+ if (this.isPendingSyncOrder(normalizedOrder)) return normalizedOrder;
2385
+ return _objectSpread(_objectSpread({}, normalizedOrder), {}, {
2303
2386
  need_sync: 0
2304
2387
  });
2305
2388
  }
@@ -2310,11 +2393,12 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2310
2393
  var merged = remoteOrders.map(function (order) {
2311
2394
  return _this19.normalizeRemoteSyncedOrder(order);
2312
2395
  });
2313
- var _iterator21 = _createForOfIteratorHelper(existingOrders),
2314
- _step21;
2396
+ var _iterator19 = _createForOfIteratorHelper(existingOrders),
2397
+ _step19;
2315
2398
  try {
2316
- for (_iterator21.s(); !(_step21 = _iterator21.n()).done;) {
2317
- var order = _step21.value;
2399
+ for (_iterator19.s(); !(_step19 = _iterator19.n()).done;) {
2400
+ var rawOrder = _step19.value;
2401
+ var order = this.normalizeOrderCollectionsForIngress(rawOrder, 'mergeRemoteSnapshotWithPendingOrders.existingSQLite');
2318
2402
  if (!this.isPendingSyncOrder(order)) continue;
2319
2403
  var matchIndex = this.findOrderIndexByIdentity(merged, order);
2320
2404
  if (matchIndex >= 0) {
@@ -2325,9 +2409,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2325
2409
  merged.push(order);
2326
2410
  }
2327
2411
  } catch (err) {
2328
- _iterator21.e(err);
2412
+ _iterator19.e(err);
2329
2413
  } finally {
2330
- _iterator21.f();
2414
+ _iterator19.f();
2331
2415
  }
2332
2416
  return this.compactOrderListByIdentity(merged, 'mergeRemoteSnapshotWithPendingOrders').list;
2333
2417
  }
@@ -2395,7 +2479,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2395
2479
  }
2396
2480
  return _context20.abrupt("return");
2397
2481
  case 3:
2398
- ordersSnapshot = cloneDeep(orders).filter(function (order) {
2482
+ ordersSnapshot = cloneDeep(orders).map(function (order) {
2483
+ return _this20.normalizeOrderCollectionsForIngress(order, "".concat(source, ".sqliteIngress"));
2484
+ }).filter(function (order) {
2399
2485
  return _this20.getOrderStorageKey(order);
2400
2486
  });
2401
2487
  if (!(ordersSnapshot.length === 0)) {
@@ -2421,7 +2507,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2421
2507
  _context20.prev = 12;
2422
2508
  _context20.next = 15;
2423
2509
  return this.runInOrderSQLiteSaveQueue( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee19() {
2424
- var writeMethod, _iterator22, _step22, order;
2510
+ var writeMethod, _iterator20, _step20, order;
2425
2511
  return _regeneratorRuntime().wrap(function _callee19$(_context19) {
2426
2512
  while (1) switch (_context19.prev = _context19.next) {
2427
2513
  case 0:
@@ -2458,15 +2544,15 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2458
2544
  break;
2459
2545
  }
2460
2546
  writeMethod = 'update';
2461
- _iterator22 = _createForOfIteratorHelper(compactedToWrite);
2547
+ _iterator20 = _createForOfIteratorHelper(compactedToWrite);
2462
2548
  _context19.prev = 17;
2463
- _iterator22.s();
2549
+ _iterator20.s();
2464
2550
  case 19:
2465
- if ((_step22 = _iterator22.n()).done) {
2551
+ if ((_step20 = _iterator20.n()).done) {
2466
2552
  _context19.next = 25;
2467
2553
  break;
2468
2554
  }
2469
- order = _step22.value;
2555
+ order = _step20.value;
2470
2556
  _context19.next = 23;
2471
2557
  return _this20.dbManager.update(INDEXDB_STORE_NAME, order);
2472
2558
  case 23:
@@ -2478,10 +2564,10 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2478
2564
  case 27:
2479
2565
  _context19.prev = 27;
2480
2566
  _context19.t0 = _context19["catch"](17);
2481
- _iterator22.e(_context19.t0);
2567
+ _iterator20.e(_context19.t0);
2482
2568
  case 30:
2483
2569
  _context19.prev = 30;
2484
- _iterator22.f();
2570
+ _iterator20.f();
2485
2571
  return _context19.finish(30);
2486
2572
  case 33:
2487
2573
  _this20.recordRecentSqliteWrite(source, compactedToWrite);
@@ -2540,7 +2626,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2540
2626
  }
2541
2627
  return _context22.abrupt("return");
2542
2628
  case 2:
2543
- orderSnapshot = cloneDeep(order);
2629
+ orderSnapshot = this.normalizeOrderCollectionsForIngress(cloneDeep(order), "".concat(source, ".sqliteIngress"));
2544
2630
  _context22.prev = 3;
2545
2631
  _context22.next = 6;
2546
2632
  return this.runInOrderSQLiteSaveQueue( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21() {
@@ -2642,7 +2728,9 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2642
2728
  return _this22.normalizeRemoteSyncedOrder(order);
2643
2729
  }), "".concat(source, ".snapshotNoDb")).list);
2644
2730
  case 2:
2645
- remoteSnapshot = cloneDeep(orderList);
2731
+ remoteSnapshot = cloneDeep(orderList).map(function (order) {
2732
+ return _this22.normalizeOrderCollectionsForIngress(order, "".concat(source, ".remoteIngress"));
2733
+ });
2646
2734
  mergedSnapshot = this.compactOrderListByIdentity(remoteSnapshot.map(function (order) {
2647
2735
  return _this22.normalizeRemoteSyncedOrder(order);
2648
2736
  }), "".concat(source, ".remoteSnapshot")).list;
@@ -2741,12 +2829,11 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2741
2829
  case 0:
2742
2830
  this.store.list = [];
2743
2831
  this.store.map = new Map();
2744
- this.resourceIdIndex.clear();
2745
2832
  if (!this.dbManager) {
2746
- _context26.next = 6;
2833
+ _context26.next = 5;
2747
2834
  break;
2748
2835
  }
2749
- _context26.next = 6;
2836
+ _context26.next = 5;
2750
2837
  return this.runInOrderSQLiteSaveQueue( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee25() {
2751
2838
  return _regeneratorRuntime().wrap(function _callee25$(_context25) {
2752
2839
  while (1) switch (_context25.prev = _context25.next) {
@@ -2759,10 +2846,10 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
2759
2846
  }
2760
2847
  }, _callee25);
2761
2848
  })));
2762
- case 6:
2849
+ case 5:
2763
2850
  this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, '');
2764
2851
  this.emitOrdersChanged([], 'clear');
2765
- case 8:
2852
+ case 7:
2766
2853
  case "end":
2767
2854
  return _context26.stop();
2768
2855
  }