@pisell/pisellos 2.2.315 → 2.2.316

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 (97) hide show
  1. package/dist/model/strategy/adapter/promotion/evaluator.js +89 -104
  2. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
  3. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +28 -4
  4. package/dist/modules/Holder/utils.d.ts +2 -0
  5. package/dist/modules/Holder/utils.js +32 -2
  6. package/dist/modules/OpenData/contactInfo.d.ts +20 -0
  7. package/dist/modules/OpenData/contactInfo.js +70 -0
  8. package/dist/modules/OpenData/index.d.ts +1 -0
  9. package/dist/modules/OpenData/index.js +1 -0
  10. package/dist/modules/OpenData/types.d.ts +9 -0
  11. package/dist/modules/Order/holderRelations.d.ts +14 -0
  12. package/dist/modules/Order/holderRelations.js +154 -0
  13. package/dist/modules/Order/index.d.ts +2 -2
  14. package/dist/modules/Order/index.js +89 -44
  15. package/dist/modules/Order/types.d.ts +19 -1
  16. package/dist/modules/Order/types.js +2 -0
  17. package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
  18. package/dist/modules/Order/utils/discountProductLineIdentity.js +142 -7
  19. package/dist/modules/Order/utils/orderCollectionIdentity.js +24 -10
  20. package/dist/modules/Order/utils.d.ts +2 -1
  21. package/dist/modules/Order/utils.js +36 -10
  22. package/dist/modules/Rules/index.js +62 -61
  23. package/dist/server/index.js +36 -28
  24. package/dist/server/modules/order/index.d.ts +4 -0
  25. package/dist/server/modules/order/index.js +255 -190
  26. package/dist/server/modules/order/types.d.ts +3 -0
  27. package/dist/server/modules/products/index.d.ts +28 -7
  28. package/dist/server/modules/products/index.js +1297 -770
  29. package/dist/server/modules/products/replication.d.ts +8 -0
  30. package/dist/server/modules/products/replication.js +69 -0
  31. package/dist/server/modules/products/types.d.ts +12 -1
  32. package/dist/server/modules/products/types.js +4 -0
  33. package/dist/shared/receipt/small-ticket.js +24 -12
  34. package/dist/shared/receipt/templateVisibility.d.ts +3 -0
  35. package/dist/shared/receipt/templateVisibility.js +6 -2
  36. package/dist/shared/sales/loadSalesOrderSnapshot.js +1 -1
  37. package/dist/solution/BaseSales/index.d.ts +4 -0
  38. package/dist/solution/BaseSales/index.js +1116 -935
  39. package/dist/solution/BaseSales/types.d.ts +2 -1
  40. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
  41. package/dist/solution/BaseSales/utils/parseSalesResponse.js +7 -3
  42. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -4
  43. package/dist/solution/BookingByStep/index.d.ts +1 -1
  44. package/dist/solution/BookingTicket/index.d.ts +15 -1
  45. package/dist/solution/BookingTicket/index.js +784 -501
  46. package/dist/solution/ScanOrder/index.js +65 -31
  47. package/dist/solution/ScanOrder/types.d.ts +3 -0
  48. package/dist/solution/UnifiedBookingSales/index.js +1 -1
  49. package/lib/model/strategy/adapter/promotion/evaluator.js +9 -14
  50. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.d.ts +3 -1
  51. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +17 -1
  52. package/lib/modules/Holder/utils.d.ts +2 -0
  53. package/lib/modules/Holder/utils.js +27 -1
  54. package/lib/modules/OpenData/contactInfo.d.ts +20 -0
  55. package/lib/modules/OpenData/contactInfo.js +56 -0
  56. package/lib/modules/OpenData/index.d.ts +1 -0
  57. package/lib/modules/OpenData/index.js +12 -0
  58. package/lib/modules/OpenData/types.d.ts +9 -0
  59. package/lib/modules/Order/holderRelations.d.ts +14 -0
  60. package/lib/modules/Order/holderRelations.js +98 -0
  61. package/lib/modules/Order/index.d.ts +2 -2
  62. package/lib/modules/Order/index.js +44 -12
  63. package/lib/modules/Order/types.d.ts +19 -1
  64. package/lib/modules/Order/types.js +1 -0
  65. package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +1 -1
  66. package/lib/modules/Order/utils/discountProductLineIdentity.js +51 -2
  67. package/lib/modules/Order/utils/orderCollectionIdentity.js +5 -0
  68. package/lib/modules/Order/utils.d.ts +2 -1
  69. package/lib/modules/Order/utils.js +28 -6
  70. package/lib/modules/Rules/index.js +2 -1
  71. package/lib/server/index.js +8 -2
  72. package/lib/server/modules/order/index.d.ts +4 -0
  73. package/lib/server/modules/order/index.js +46 -4
  74. package/lib/server/modules/order/types.d.ts +3 -0
  75. package/lib/server/modules/products/index.d.ts +28 -7
  76. package/lib/server/modules/products/index.js +226 -63
  77. package/lib/server/modules/products/replication.d.ts +8 -0
  78. package/lib/server/modules/products/replication.js +30 -0
  79. package/lib/server/modules/products/types.d.ts +12 -1
  80. package/lib/server/modules/products/types.js +3 -0
  81. package/lib/shared/receipt/small-ticket.js +22 -13
  82. package/lib/shared/receipt/templateVisibility.d.ts +3 -0
  83. package/lib/shared/receipt/templateVisibility.js +6 -2
  84. package/lib/shared/sales/loadSalesOrderSnapshot.js +1 -1
  85. package/lib/solution/BaseSales/index.d.ts +4 -0
  86. package/lib/solution/BaseSales/index.js +68 -2
  87. package/lib/solution/BaseSales/types.d.ts +2 -1
  88. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -1
  89. package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -0
  90. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +16 -8
  91. package/lib/solution/BookingByStep/index.d.ts +1 -1
  92. package/lib/solution/BookingTicket/index.d.ts +15 -1
  93. package/lib/solution/BookingTicket/index.js +132 -3
  94. package/lib/solution/ScanOrder/index.js +59 -20
  95. package/lib/solution/ScanOrder/types.d.ts +3 -0
  96. package/lib/solution/UnifiedBookingSales/index.js +1 -1
  97. package/package.json +1 -1
@@ -595,7 +595,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
595
595
  generateIdempotencyToken(): string;
596
596
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
597
597
  createOrder(params: CommitOrderParams['query']): {
598
- type: "appointment_booking" | "virtual";
598
+ type: "virtual" | "appointment_booking";
599
599
  platform: string;
600
600
  sales_channel: string;
601
601
  order_sales_channel: string;
@@ -673,6 +673,6 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
673
673
  getOrderInfo(order_id: number): Promise<any>;
674
674
  getVouchers(): any[];
675
675
  }
676
- export type { AddProductToOrderOptions, OrderMetaList, PointCardSnapshotItem, VirtualCurrencySnapshotItem, RemoveProductsFromOrderOptions, SalesNote, SalesNoteDraftInput, SalesNoteLocalizedSelection, SalesNoteLocalizedText, SalesNoteRelation, SalesNoteTextInput, SetSalesNoteInput, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
676
+ export type { OrderHolderRelation, AddProductToOrderOptions, OrderMetaList, PointCardSnapshotItem, VirtualCurrencySnapshotItem, RemoveProductsFromOrderOptions, SalesNote, SalesNoteDraftInput, SalesNoteLocalizedSelection, SalesNoteLocalizedText, SalesNoteRelation, SalesNoteTextInput, SetSalesNoteInput, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, } from './types';
677
677
  export { isFulfillmentTimingBooking } from './pickupTiming';
678
678
  export type { PickupTimingBooking, PickupTimingBookingInput, PickupTimingBookingMetadata, PickupTimingSelectionMode, PickupTimingSource, } from './pickupTiming';
@@ -16,6 +16,7 @@ var _BaseModule = require("../BaseModule");
16
16
  var _types = require("./types");
17
17
  var _utils = require("./utils");
18
18
  var _utils2 = require("../Product/utils");
19
+ var _holderRelations = require("./holderRelations");
19
20
  var _weighedProduct = require("./utils/weighedProduct");
20
21
  var _pickupTiming = require("./pickupTiming");
21
22
  var _dayjs = _interopRequireDefault(require("dayjs"));
@@ -543,7 +544,7 @@ class OrderModule extends _BaseModule.BaseModule {
543
544
  this.store.rules = rules;
544
545
  }
545
546
  createDefaultRulesHooks() {
546
- return (0, _utils.createDefaultOrderRulesHooks)(() => this.store.tempOrder?.bookings || []);
547
+ return (0, _utils.createDefaultOrderRulesHooks)(() => this.store.tempOrder?.bookings || [], () => this.store.tempOrder?.holder_relations);
547
548
  }
548
549
 
549
550
  /**
@@ -857,7 +858,7 @@ class OrderModule extends _BaseModule.BaseModule {
857
858
  discount_list: (0, _utils.normalizeOrderProductDiscountList)((0, _manualProductDiscount.syncManualProductDiscountProductNum)(mergedProduct.discount_list, mergedProduct.num))
858
859
  };
859
860
  }));
860
- (0, _discountProductLineIdentity.ensureUniqueProductLineUids)(tempOrder);
861
+ (0, _discountProductLineIdentity.ensureUniqueProductLineUids)(tempOrder, discountList);
861
862
  (0, _discountProductLineIdentity.consolidateDiscountFreeProductLines)(tempOrder);
862
863
  }
863
864
  if (result?.discountList) {
@@ -1118,7 +1119,9 @@ class OrderModule extends _BaseModule.BaseModule {
1118
1119
  * sessionStorage 的 cacheId 分桶。写入失败由 BaseModule 静默降级。
1119
1120
  */
1120
1121
  persistTempOrder() {
1121
- if (!this.sessionStoragePersistEnabled || !this.store.tempOrder) return;
1122
+ if (!this.store.tempOrder) return;
1123
+ (0, _holderRelations.ensureHolderRelationUuids)(this.store.tempOrder);
1124
+ if (!this.sessionStoragePersistEnabled) return;
1122
1125
  this.checkSaveCache({
1123
1126
  cacheId: this.cacheId,
1124
1127
  fatherModule: this.fatherModule,
@@ -1827,7 +1830,10 @@ class OrderModule extends _BaseModule.BaseModule {
1827
1830
  source_product_price: this.normalizeFingerprintMoney(metadata.source_product_price),
1828
1831
  main_product_selling_price: this.normalizeFingerprintMoney(metadata.main_product_selling_price),
1829
1832
  main_product_original_price: this.normalizeFingerprintMoney(metadata.main_product_original_price),
1830
- product_discount_difference: this.normalizeFingerprintMoney(metadata.product_discount_difference)
1833
+ product_discount_difference: this.normalizeFingerprintMoney(metadata.product_discount_difference),
1834
+ ...(!(0, _holderRelations.hasProductBooking)(product) ? {
1835
+ holder_relations: this.normalizeFingerprintValue((0, _holderRelations.getProductHolderRelations)(this.store.tempOrder || {}, product))
1836
+ } : {})
1831
1837
  },
1832
1838
  product_sku: this.normalizeFingerprintValue({
1833
1839
  code: sku.code ?? '',
@@ -1863,7 +1869,7 @@ class OrderModule extends _BaseModule.BaseModule {
1863
1869
  items.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
1864
1870
  return JSON.stringify(items);
1865
1871
  }
1866
- buildProductStructuralFingerprintItem(product) {
1872
+ buildProductStructuralFingerprintItem(product, order = this.store.tempOrder || {}) {
1867
1873
  const sku = product?.product_sku || {};
1868
1874
  const metadata = product?.metadata || {};
1869
1875
  const discountTypes = (product?.discount_list || []).map(discount => discount?.type ?? discount?.tag);
@@ -1878,7 +1884,10 @@ class OrderModule extends _BaseModule.BaseModule {
1878
1884
  unique_identification_number: metadata.unique_identification_number ?? product?.unique_identification_number ?? '',
1879
1885
  price_override: metadata.price_override ?? '',
1880
1886
  is_manual_discount: metadata.is_manual_discount ?? '',
1881
- product_discount_reason: metadata.product_discount_reason ?? ''
1887
+ product_discount_reason: metadata.product_discount_reason ?? '',
1888
+ ...(!(0, _holderRelations.hasProductBooking)(product) ? {
1889
+ holder_relations: this.normalizeFingerprintValue((0, _holderRelations.getProductHolderRelations)(order, product))
1890
+ } : {})
1882
1891
  },
1883
1892
  product_sku: this.normalizeFingerprintValue({
1884
1893
  code: sku.code ?? '',
@@ -1916,8 +1925,8 @@ class OrderModule extends _BaseModule.BaseModule {
1916
1925
  })))
1917
1926
  };
1918
1927
  }
1919
- buildOrderProductsStructuralFingerprint(products) {
1920
- const items = (products || []).map(product => this.buildProductStructuralFingerprintItem(product));
1928
+ buildOrderProductsStructuralFingerprint(products, order = this.store.tempOrder || {}) {
1929
+ const items = (products || []).map(product => this.buildProductStructuralFingerprintItem(product, order));
1921
1930
  items.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
1922
1931
  return JSON.stringify(items);
1923
1932
  }
@@ -1984,7 +1993,7 @@ class OrderModule extends _BaseModule.BaseModule {
1984
1993
  const manualDepositOverride = this.getManualDepositOverride(tempOrder);
1985
1994
  if (currentFingerprint !== snapshot.productFingerprint) {
1986
1995
  const currentStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(tempOrder.products);
1987
- const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(Array.isArray(snapshot.products) ? snapshot.products : []);
1996
+ const snapshotStructuralFingerprint = this.buildOrderProductsStructuralFingerprint(Array.isArray(snapshot.products) ? snapshot.products : [], snapshot);
1988
1997
  if (currentStructuralFingerprint !== snapshotStructuralFingerprint) return null;
1989
1998
  }
1990
1999
  let summary = {
@@ -2205,9 +2214,16 @@ class OrderModule extends _BaseModule.BaseModule {
2205
2214
  product.metadata = metadata;
2206
2215
  return String(uid);
2207
2216
  }
2208
- sanitizeOrderProductForTempOrder(product) {
2217
+ sanitizeOrderProductForTempOrder(product, deferHolderCleanup = false) {
2209
2218
  if (product.metadata && typeof product.metadata === 'object') {
2210
2219
  delete product.metadata.origin;
2220
+ if (!deferHolderCleanup && !(0, _holderRelations.hasProductBooking)(product)) {
2221
+ delete product.metadata.holder;
2222
+ delete product.metadata.holder_id;
2223
+ }
2224
+ }
2225
+ if (product._extend?.holder_relations !== undefined) {
2226
+ delete product._extend.holder_relations;
2211
2227
  }
2212
2228
  return product;
2213
2229
  }
@@ -3006,6 +3022,7 @@ class OrderModule extends _BaseModule.BaseModule {
3006
3022
  const nextCustomerId = tempOrder.customer_id ?? null;
3007
3023
  if (String(previousCustomerId ?? '') !== String(nextCustomerId ?? '')) {
3008
3024
  this.clearCustomerWalletState(tempOrder);
3025
+ (0, _holderRelations.removeProductHolderRelations)(tempOrder, tempOrder.products.filter(product => !(0, _holderRelations.hasProductBooking)(product)));
3009
3026
  }
3010
3027
  this.persistTempOrder();
3011
3028
  return {
@@ -3569,10 +3586,13 @@ class OrderModule extends _BaseModule.BaseModule {
3569
3586
  const hasIncomingProductNote = this.hasOrderProductLineNote(normalizedIncoming);
3570
3587
  const hasIncomingManualProductDiscount = isManualProductDiscountProduct(normalizedIncoming);
3571
3588
  const hasIncomingBookingUid = this.hasLinkedBookingUid(productToAdd) || this.hasLinkedBookingUid(normalizedIncoming);
3589
+ const holderRelationsPatch = !hasIncomingBookingUid ? productToAdd._extend?.holder_relations : undefined;
3590
+ const hasIncomingHolder = Array.isArray(holderRelationsPatch) && holderRelationsPatch.length > 0;
3572
3591
  const isIncomingCustomItem = productToAdd.metadata?.origin?.isCustomItem === true || productToAdd._origin?.isCustomItem === true;
3573
- const shouldForceNewLine = disableMerge || !!booking || hasIncomingGoodPass || isIncomingPersistedEntitlementPass || hasIncomingBookingUid || isIncomingCustomItem || isWeighingProduct;
3592
+ const shouldForceNewLine = disableMerge || !!booking || hasIncomingGoodPass || isIncomingPersistedEntitlementPass || hasIncomingBookingUid || hasIncomingHolder || isIncomingCustomItem || isWeighingProduct;
3574
3593
  const matchedIndex = shouldForceNewLine ? -1 : tempOrder.products.findIndex(item => {
3575
3594
  if (this.hasGoodPassDiscount(item)) return false;
3595
+ if ((0, _holderRelations.getProductHolderRelations)(tempOrder, item).length > 0 || (0, _utils.hasAssignedHolderId)(item.metadata?.holder_id)) return false;
3576
3596
  const isRuntimeEntitlementPass = this.isRuntimeEntitlementAppend(item, tempOrder);
3577
3597
  if (isIncomingEntitlementAppend !== isRuntimeEntitlementPass) {
3578
3598
  return false;
@@ -3663,6 +3683,7 @@ class OrderModule extends _BaseModule.BaseModule {
3663
3683
  if (linked) {
3664
3684
  tempOrder.bookings = [...(tempOrder.bookings || []), linked.booking];
3665
3685
  }
3686
+ (0, _holderRelations.replaceProductHolderRelations)(tempOrder, committedProduct, holderRelationsPatch);
3666
3687
  return committedProduct;
3667
3688
  };
3668
3689
  if (!matchedProduct) {
@@ -3772,6 +3793,7 @@ class OrderModule extends _BaseModule.BaseModule {
3772
3793
  }));
3773
3794
  const mutationSnapshot = salesNoteDrafts.length > 0 ? {
3774
3795
  products: (0, _lodashEs.cloneDeep)(tempOrder.products || []),
3796
+ holder_relations: (0, _lodashEs.cloneDeep)(tempOrder.holder_relations),
3775
3797
  bookings: (0, _lodashEs.cloneDeep)(tempOrder.bookings || []),
3776
3798
  notes: (0, _lodashEs.cloneDeep)(tempOrder.notes || []),
3777
3799
  extend: (0, _lodashEs.cloneDeep)(tempOrder._extend || {})
@@ -3796,6 +3818,7 @@ class OrderModule extends _BaseModule.BaseModule {
3796
3818
  const rollbackProductAndNotesMutation = () => {
3797
3819
  if (!mutationSnapshot) return;
3798
3820
  tempOrder.products = mutationSnapshot.products;
3821
+ if (mutationSnapshot.holder_relations === undefined) delete tempOrder.holder_relations;else tempOrder.holder_relations = mutationSnapshot.holder_relations;
3799
3822
  tempOrder.bookings = mutationSnapshot.bookings;
3800
3823
  tempOrder.notes = mutationSnapshot.notes;
3801
3824
  tempOrder._extend = mutationSnapshot.extend;
@@ -4280,6 +4303,7 @@ class OrderModule extends _BaseModule.BaseModule {
4280
4303
  if (uid) reapplyWeighedDiscountProductUids?.push(String(uid));
4281
4304
  }
4282
4305
  tempOrder.products[productIndex] = normalizedProduct;
4306
+ (0, _holderRelations.replaceProductHolderRelations)(tempOrder, normalizedProduct, updates._extend?.holder_relations);
4283
4307
  this.syncTempOrderHolderFromBookings(tempOrder);
4284
4308
  this.captureProductRuntime(tempOrder, updates, tempOrder.products[productIndex], tempOrder.products[productIndex].metadata?.unique_identification_number);
4285
4309
  return tempOrder.products[productIndex].metadata?.unique_identification_number;
@@ -4557,6 +4581,7 @@ class OrderModule extends _BaseModule.BaseModule {
4557
4581
  tempOrder.products = nextProductIndex >= 0 ? [...productsWithoutRemaining.slice(0, nextProductIndex), remainingProduct, ...productsWithoutRemaining.slice(nextProductIndex)] : [...productsWithoutRemaining, remainingProduct];
4558
4582
  }
4559
4583
  }
4584
+ (0, _holderRelations.removeProductHolderRelations)(tempOrder, productsBeforeRemove.filter(product => !tempOrder.products.includes(product)));
4560
4585
  this.removeSalesNotesForMissingProductLines(tempOrder);
4561
4586
  if (isCurrentOrder) {
4562
4587
  await this.finalizeProductOrderMutation(tempOrder, {
@@ -4582,6 +4607,7 @@ class OrderModule extends _BaseModule.BaseModule {
4582
4607
  async clearOrderCartLines() {
4583
4608
  const tempOrder = this.ensureTempOrder();
4584
4609
  this.ensureSalesNotesLoadedForMutation(tempOrder);
4610
+ (0, _holderRelations.removeProductHolderRelations)(tempOrder, tempOrder.products);
4585
4611
  tempOrder.products = [];
4586
4612
  tempOrder.bookings = [];
4587
4613
  (0, _virtualSettlement.releaseTempOrderSettlementState)(tempOrder);
@@ -4611,6 +4637,7 @@ class OrderModule extends _BaseModule.BaseModule {
4611
4637
  async clearOrderForSettlementSwitch() {
4612
4638
  const tempOrder = this.ensureTempOrder();
4613
4639
  this.ensureSalesNotesLoadedForMutation(tempOrder);
4640
+ (0, _holderRelations.removeProductHolderRelations)(tempOrder, tempOrder.products);
4614
4641
  tempOrder.products = [];
4615
4642
  tempOrder.bookings = [];
4616
4643
  this.removeSalesNotesForMissingProductLines(tempOrder);
@@ -5354,6 +5381,7 @@ class OrderModule extends _BaseModule.BaseModule {
5354
5381
  originalSalesSnapshot: {
5355
5382
  summary: (0, _lodashEs.cloneDeep)(this.store.summary),
5356
5383
  products: (0, _lodashEs.cloneDeep)(nextTempOrder.products || []),
5384
+ holder_relations: (0, _lodashEs.cloneDeep)(nextTempOrder.holder_relations),
5357
5385
  bookings: (0, _lodashEs.cloneDeep)(nextTempOrder.bookings || []),
5358
5386
  payments: (0, _lodashEs.cloneDeep)(nextTempOrder.payments || []),
5359
5387
  surcharges: (0, _lodashEs.cloneDeep)(nextTempOrder.surcharges || []),
@@ -5506,6 +5534,9 @@ class OrderModule extends _BaseModule.BaseModule {
5506
5534
  nextTempOrder.metadata = raw.metadata && typeof raw.metadata === 'object' ? {
5507
5535
  ...raw.metadata
5508
5536
  } : {};
5537
+ const holderRelations = (0, _holderRelations.restoreLegacyHolderRelations)(raw);
5538
+ if (holderRelations === undefined) delete nextTempOrder.holder_relations;else nextTempOrder.holder_relations = (0, _lodashEs.cloneDeep)(holderRelations);
5539
+ (0, _holderRelations.ensureHolderRelationUuids)(nextTempOrder);
5509
5540
  nextTempOrder.holder = raw.holder && typeof raw.holder === 'object' ? {
5510
5541
  ...raw.holder
5511
5542
  } : null;
@@ -5583,6 +5614,7 @@ class OrderModule extends _BaseModule.BaseModule {
5583
5614
  }
5584
5615
  tempOrderExtend.productsByUid = productsByUid;
5585
5616
  this.hydrateLinkedBookingIdentity(nextTempOrder);
5617
+ nextTempOrder.products.forEach(product => this.sanitizeOrderProductForTempOrder(product));
5586
5618
  if (options?.ensureIdentity !== false) {
5587
5619
  this.ensureExternalSaleNumber(nextTempOrder);
5588
5620
  }
@@ -5743,7 +5775,7 @@ class OrderModule extends _BaseModule.BaseModule {
5743
5775
  };
5744
5776
  if (result.metadata) delete result.metadata.price_schema_version;
5745
5777
  const restored = (0, _bundleDiscountHydration.restoreHydratedBundleDiscounts)(result, _utils.normalizeOrderProductDiscountList);
5746
- return this.sanitizeOrderProductForTempOrder(this.normalizeVirtualSettlementProductIfEnabled(restored));
5778
+ return this.sanitizeOrderProductForTempOrder(this.normalizeVirtualSettlementProductIfEnabled(restored), true);
5747
5779
  }
5748
5780
  getLastOrderInfo() {
5749
5781
  return this.store?.lastOrderInfo;
@@ -243,6 +243,11 @@ export interface OrderProduct extends OrderProductIdentity {
243
243
  product_cover?: string;
244
244
  metadata: Record<string, any>;
245
245
  note?: string;
246
+ /** 仅作按行更新输入;正式数据保存于订单顶层。 */
247
+ _extend?: {
248
+ holder_relations?: OrderHolderRelation[];
249
+ [key: string]: any;
250
+ };
246
251
  }
247
252
  export interface OrderSummary {
248
253
  product_quantity: number;
@@ -340,6 +345,17 @@ export interface SalesNotesMutationSnapshot {
340
345
  }
341
346
  export type SalesNoteProtocolRelation = SalesNoteRelation;
342
347
  export type SalesNoteProtocol = SalesNote;
348
+ /** 后端关系及 metadata 均为开放对象,未知字段必须往返保留。 */
349
+ export interface OrderHolderRelation {
350
+ /** 关系自身的 UUID;新选择/旧草稿可缺省,入单与提交时由 OS 补齐。 */
351
+ uuid?: string;
352
+ relation_model: string;
353
+ relation_uuid: string;
354
+ holder_type: 'form' | 'customer';
355
+ holder_id: number;
356
+ metadata?: Record<string, any>;
357
+ [key: string]: any;
358
+ }
343
359
  export interface OrderTempOrder {
344
360
  order_id: number | null;
345
361
  external_sale_number: string;
@@ -379,6 +395,7 @@ export interface OrderTempOrder {
379
395
  created_at: string | undefined;
380
396
  request_unique_idempotency_token?: string;
381
397
  products: OrderProduct[];
398
+ holder_relations?: OrderHolderRelation[];
382
399
  notes: SalesNote[];
383
400
  bookings: any[];
384
401
  payments: any[];
@@ -398,7 +415,7 @@ export interface OrderTempOrder {
398
415
  [key: string]: any;
399
416
  };
400
417
  }
401
- export interface OrderSubmitProduct extends Omit<OrderProduct, 'unique_identification_number' | 'num'> {
418
+ export interface OrderSubmitProduct extends Omit<OrderProduct, 'unique_identification_number' | 'num' | '_extend'> {
402
419
  product_quantity: number;
403
420
  payment_price: string;
404
421
  product_sku: OrderProductSku;
@@ -607,6 +624,7 @@ export interface SubmitSalesOrderParams {
607
624
  schedule_date: string;
608
625
  created_at?: string | undefined;
609
626
  products: OrderSubmitProduct[];
627
+ holder_relations?: OrderHolderRelation[];
610
628
  bookings: OrderSubmitBooking[];
611
629
  payments: any[];
612
630
  vouchers: any[];
@@ -63,6 +63,7 @@ let OrderHooks = exports.OrderHooks = /*#__PURE__*/function (OrderHooks) {
63
63
  * Sales Notes 乐观写入前的可恢复快照。
64
64
  * 该对象应视为 opaque token,只用于原样传回 restoreSalesNotesMutationSnapshot。
65
65
  */
66
+ /** 后端关系及 metadata 均为开放对象,未知字段必须往返保留。 */
66
67
  /**
67
68
  * 添加商品行时的顺序控制。
68
69
  * 默认追加到 products 尾部;预约数量同步可插入到既有预约组的最新行之后,
@@ -31,7 +31,7 @@ export declare const DISCOUNT_SPLIT_ORIGIN_UID_KEY = "discountSplitOriginUid";
31
31
  * 没有 UID 的裸商品不会被补写 UID。这是为了兼容 Rules/mock 的历史协议形状;
32
32
  * 正常 Order 写路径会在 normalize 阶段提前创建 UID。
33
33
  */
34
- export declare function ensureUniqueProductLineUids(tempOrder: OrderTempOrder): void;
34
+ export declare function ensureUniqueProductLineUids(tempOrder: OrderTempOrder, discounts?: Array<Record<string, any>>): void;
35
35
  /**
36
36
  * 把券移除后已经恢复原价的同源折扣拆分行重新合并。
37
37
  *
@@ -9,6 +9,7 @@ exports.ensureUniqueProductLineUids = ensureUniqueProductLineUids;
9
9
  var _lodashEs = require("lodash-es");
10
10
  var _utils = require("../../../solution/ScanOrder/utils");
11
11
  var _orderCollectionIdentity = require("./orderCollectionIdentity");
12
+ var _holderRelations = require("../holderRelations");
12
13
  /**
13
14
  * 商品券拆行的身份与回并工具。
14
15
  *
@@ -72,16 +73,20 @@ function ensureProductsByUid(tempOrder) {
72
73
  * 没有 UID 的裸商品不会被补写 UID。这是为了兼容 Rules/mock 的历史协议形状;
73
74
  * 正常 Order 写路径会在 normalize 阶段提前创建 UID。
74
75
  */
75
- function ensureUniqueProductLineUids(tempOrder) {
76
+ function ensureUniqueProductLineUids(tempOrder, discounts = []) {
76
77
  // usedUids 只描述本次 Rules 返回的商品集合,不能直接依赖 productsByUid:
77
78
  // productsByUid 可能还保留已删除行的历史 runtime,历史 UID 不应导致当前行被改号。
78
79
  const usedUids = new Set();
79
80
  const productsByUid = ensureProductsByUid(tempOrder);
81
+ const splitGroups = new Map();
80
82
  tempOrder.products = (tempOrder.products || []).map(product => {
81
83
  const sourceUid = getProductLineUid(product);
82
84
  // 单测 mock 或兼容旧 Rules 时可能返回没有 UID 的裸商品。
83
85
  // 这里不主动补 UID,避免一个“校验重复”的工具意外改变旧协议对象形状。
84
86
  if (!sourceUid) return product;
87
+ const group = splitGroups.get(sourceUid) || [];
88
+ group.push(product);
89
+ splitGroups.set(sourceUid, group);
85
90
 
86
91
  // 实际场景:可乐 ×5 首次进入 Rules 时只有一行。
87
92
  // 使用三张券后 Rules 可能返回「可乐 ×2 + 三条可乐 ×1」,但四条都复制原 UID。
@@ -122,6 +127,50 @@ function ensureUniqueProductLineUids(tempOrder) {
122
127
  usedUids.add(splitUid);
123
128
  return product;
124
129
  });
130
+
131
+ // 仅按本次券上的明确 Holder 分配迁移。数组顺序不能代表券对应的人。
132
+ // 未能明确分配时保留原 UID,不把整组关系复制给每一个拆分行。
133
+ for (const [sourceUid, products] of splitGroups) {
134
+ if (products.length < 2) continue;
135
+ const relations = (0, _holderRelations.getProductHolderRelations)(tempOrder, {
136
+ metadata: {
137
+ unique_identification_number: sourceUid
138
+ }
139
+ });
140
+ if (!relations.length || relations.some(relation => relation.holder_type !== 'form')) continue;
141
+ const assignments = new Map();
142
+ let remaining = [...relations];
143
+ let ambiguous = false;
144
+ for (const product of products) {
145
+ const holderIds = new Set();
146
+ for (const item of product.discount_list || []) {
147
+ const discount = discounts.find(candidate => String(candidate.id) === String(item.discount?.resource_id));
148
+ if (discount?.holder?.holder_type !== 'form') continue;
149
+ const value = discount.holder.holder_id;
150
+ (Array.isArray(value) ? value : [value]).forEach(id => {
151
+ const recordId = id && typeof id === 'object' ? id.form_record_id : id;
152
+ if (recordId !== undefined && recordId !== null && recordId !== '') holderIds.add(String(recordId));
153
+ });
154
+ }
155
+ if (!holderIds.size) continue;
156
+ const assigned = remaining.filter(relation => holderIds.has(String(relation.holder_id)));
157
+ if (assigned.length !== Number(product.num)) {
158
+ ambiguous = true;
159
+ break;
160
+ }
161
+ assignments.set(product, assigned);
162
+ remaining = remaining.filter(relation => !assigned.includes(relation));
163
+ }
164
+ const unassigned = products.filter(product => !assignments.has(product));
165
+ if (ambiguous || unassigned.length > 1) continue;
166
+ if (unassigned.length === 1) {
167
+ if (remaining.length !== Number(unassigned[0].num)) continue;
168
+ assignments.set(unassigned[0], remaining);
169
+ } else if (remaining.length) continue;
170
+ for (const [product, assigned] of assignments) {
171
+ for (const relation of assigned) relation.relation_uuid = String(getProductLineUid(product));
172
+ }
173
+ }
125
174
  }
126
175
 
127
176
  /**
@@ -154,7 +203,7 @@ function consolidateDiscountFreeProductLines(tempOrder) {
154
203
  // - 手动改价/备注:用户显式表达了不同价格或不同制作要求;
155
204
  // - 称重商品:每次称重的净重和金额属于独立交易事实;
156
205
  // - 预约/holder/历史订单行:分别关联预约、持有人或后端 order_detail。
157
- const hasMergeBoundary = hasDiscount || Boolean(product.metadata?._giftInfo || product._giftInfo) || Boolean(product.metadata?._promotion) || isManualProductDiscountLine(product) || hasProductLineNote(product) || Number(product.product_sku?.open_sold_weight || 0) === 1 || product.metadata?.is_edit_for_runtime === true || bookingId !== undefined && bookingId !== null && bookingId !== 0 && bookingId !== '0' || bookingUid !== undefined && bookingUid !== null && String(bookingUid) !== '' || holderId !== undefined && holderId !== null && String(holderId) !== '' || orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '';
206
+ const hasMergeBoundary = hasDiscount || Boolean(product.metadata?._giftInfo || product._giftInfo) || Boolean(product.metadata?._promotion) || isManualProductDiscountLine(product) || hasProductLineNote(product) || Number(product.product_sku?.open_sold_weight || 0) === 1 || product.metadata?.is_edit_for_runtime === true || bookingId !== undefined && bookingId !== null && bookingId !== 0 && bookingId !== '0' || bookingUid !== undefined && bookingUid !== null && String(bookingUid) !== '' || (0, _holderRelations.getProductHolderRelations)(tempOrder, product).length > 0 || holderId !== undefined && holderId !== null && String(holderId) !== '' || orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '';
158
207
  if (hasMergeBoundary) {
159
208
  consolidatedProducts.push(product);
160
209
  continue;
@@ -331,6 +331,11 @@ function applyOrderCollectionUidRemaps(sourceOrder, uidRemaps) {
331
331
  }
332
332
  // 冲突 UID 仍由第一条持有;赠品父引用缺少可用的持久化行定位时不能全局改写。
333
333
  if (remap.scope !== 'linked-owner') {
334
+ for (const relation of order.holder_relations || []) {
335
+ if (relation.relation_model === 'order_detail' && String(relation.relation_uuid) === remap.from) {
336
+ relation.relation_uuid = remap.to;
337
+ }
338
+ }
334
339
  for (const product of order.products || []) {
335
340
  if (String(product?.metadata?.parent_unique_identification_number || '') === remap.from) {
336
341
  product.metadata = {
@@ -173,7 +173,7 @@ export declare function resolveManualOverrideLineOriginalPrice(params: {
173
173
  * // => -4
174
174
  */
175
175
  export declare function resolveEffectivePerUnitDiscount(product: Record<string, any>): number;
176
- export declare function createDefaultOrderRulesHooks(getBookings?: () => OrderTempOrder['bookings']): RulesParamsHooks;
176
+ export declare function createDefaultOrderRulesHooks(getBookings?: () => OrderTempOrder['bookings'], getHolderRelations?: () => OrderTempOrder['holder_relations']): RulesParamsHooks;
177
177
  /**
178
178
  * 通过 session 类商品的开始时间结束时间生成商品的时长
179
179
  * @param {CartItem} cartItem
@@ -213,6 +213,7 @@ export declare function normalizeBookingSubType(booking: Record<string, any>): s
213
213
  export declare function normalizeSubmitBooking<T extends {
214
214
  metadata?: Record<string, any>;
215
215
  }>(booking: T): T;
216
+ export declare function resolveTableOccupancyDuration(tempOrder: OrderTempOrder): number;
216
217
  /** 提交用人数:有限且为正则向下取整,否则为 1 */
217
218
  export declare function normalizeSubmitCollectPaxValue(value: unknown): number;
218
219
  /** 从临时订单 metadata 解析合成 booking 的 collect_pax */
@@ -109,6 +109,7 @@ Object.defineProperty(exports, "resolveSafeProductNum", {
109
109
  });
110
110
  exports.resolveSubmitCollectPax = resolveSubmitCollectPax;
111
111
  exports.resolveSubmitOrderType = resolveSubmitOrderType;
112
+ exports.resolveTableOccupancyDuration = resolveTableOccupancyDuration;
112
113
  Object.defineProperty(exports, "shouldBuildManualProductDiscount", {
113
114
  enumerable: true,
114
115
  get: function () {
@@ -128,6 +129,7 @@ Object.defineProperty(exports, "syncManualProductDiscountProductNum", {
128
129
  return _manualProductDiscount.syncManualProductDiscountProductNum;
129
130
  }
130
131
  });
132
+ var _lodashEs = require("lodash-es");
131
133
  var _dayjs = _interopRequireDefault(require("dayjs"));
132
134
  var _customParseFormat = _interopRequireDefault(require("dayjs/plugin/customParseFormat"));
133
135
  var _decimal = _interopRequireDefault(require("decimal.js"));
@@ -138,6 +140,7 @@ var _utils2 = require("../../solution/ScanOrder/utils");
138
140
  var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
139
141
  var _salesNotes = require("./salesNotes");
140
142
  var _pickupTiming = require("./pickupTiming");
143
+ var _holderRelations = require("./holderRelations");
141
144
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
142
145
  _dayjs.default.extend(_customParseFormat.default);
143
146
  const POINT_CARD_SNAPSHOT_TAG = 'point_card';
@@ -832,7 +835,7 @@ function resolveEffectivePerUnitDiscount(product) {
832
835
  if (!Number.isFinite(originalPrice) || !Number.isFinite(finalPrice)) return fromList;
833
836
  return fromList + (originalPrice - finalPrice);
834
837
  }
835
- function createDefaultOrderRulesHooks(getBookings) {
838
+ function createDefaultOrderRulesHooks(getBookings, getHolderRelations) {
836
839
  const getProductStartDate = product => {
837
840
  const productUid = String(product.metadata?.unique_identification_number ?? product.unique_identification_number ?? '');
838
841
  const bookingUid = String(product.booking_uid ?? product.metadata?.booking_uid ?? '');
@@ -950,7 +953,9 @@ function createDefaultOrderRulesHooks(getBookings) {
950
953
  // 勿写死 false:否则 Rules 不会走 total≠origin_total 的手动价推断,
951
954
  // 无券时会把 bundle 价还原成 original_price(手动改价套餐会从 20 回到 30)。
952
955
  isManualDiscount: resolveRulesManualDiscountFlag(metadataAny),
953
- holder_id: product.metadata?.holder_id,
956
+ holder_id: (0, _holderRelations.hasProductBooking)(product) || !getHolderRelations ? product.metadata?.holder_id : (0, _holderRelations.getProductHolderRelations)({
957
+ holder_relations: getHolderRelations()
958
+ }, product).filter(relation => relation.holder_type === 'form').map(relation => relation.holder_id),
954
959
  startDate: getProductStartDate(product),
955
960
  main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(optionSellingSum).toDecimalPlaces(2).toString() : undefined,
956
961
  inPromotion: metadataAny._promotion?.inPromotion === true,
@@ -1241,6 +1246,7 @@ function normalizeSubmitProduct(product, formatOptions = {}) {
1241
1246
  } = product;
1242
1247
  const {
1243
1248
  num,
1249
+ _extend: _productExtend,
1244
1250
  surcharge_fee: _productSurchargeFee,
1245
1251
  discount_amount: _deprecatedDiscountAmount,
1246
1252
  discount_type: _deprecatedDiscountType,
@@ -1427,6 +1433,7 @@ function createDefaultTempOrder(params) {
1427
1433
  request_unique_idempotency_token: '',
1428
1434
  vouchers: [],
1429
1435
  products: [],
1436
+ holder_relations: [],
1430
1437
  notes: [],
1431
1438
  bookings: [],
1432
1439
  payments: [],
@@ -1502,6 +1509,7 @@ function buildSubmitPayload(params) {
1502
1509
  summary,
1503
1510
  enhance
1504
1511
  } = params;
1512
+ (0, _holderRelations.ensureHolderRelationUuids)(tempOrder);
1505
1513
  const scheduleDate = tempOrder.schedule_date || tempOrder.created_at || formatDateTime(now);
1506
1514
  const bookingUuid = (0, _orderCollectionIdentity.createUuidV4)();
1507
1515
  const virtualSettlementMode = tempOrder.metadata?.currency_settlement_config?.settlement_type === 'virtual_currency';
@@ -1541,6 +1549,9 @@ function buildSubmitPayload(params) {
1541
1549
  });
1542
1550
  const payload = {
1543
1551
  ...tempOrderRest,
1552
+ ...(tempOrder.holder_relations !== undefined ? {
1553
+ holder_relations: (0, _lodashEs.cloneDeep)(tempOrder.holder_relations)
1554
+ } : {}),
1544
1555
  customer_id: tempOrder.customer_id ?? 1,
1545
1556
  customer_name: tempOrder.customer_name || 'Walk-In',
1546
1557
  country_calling_code: String(tempOrder.country_calling_code ?? ''),
@@ -1733,15 +1744,24 @@ function hasAssignedHolderId(value) {
1733
1744
  * clearTempOrderHolderAssignments(tempOrder);
1734
1745
  */
1735
1746
  function clearTempOrderHolderAssignments(tempOrder) {
1736
- let changed = false;
1747
+ const previousRelationCount = tempOrder.holder_relations?.length || 0;
1748
+ (0, _holderRelations.removeProductHolderRelations)(tempOrder, (tempOrder.products || []).filter(product => !(0, _holderRelations.hasProductBooking)(product)));
1749
+ let changed = previousRelationCount !== (tempOrder.holder_relations?.length || 0);
1737
1750
  const resetHolderField = (target, key = 'holder_id') => {
1738
1751
  if (!hasAssignedHolderId(target[key])) return;
1739
1752
  target[key] = null;
1740
1753
  changed = true;
1741
1754
  };
1755
+ const clearHolder = target => {
1756
+ resetHolderField(target);
1757
+ if (target.holder !== undefined && target.holder !== null) {
1758
+ target.holder = null;
1759
+ changed = true;
1760
+ }
1761
+ };
1742
1762
  for (const product of tempOrder.products || []) {
1743
1763
  if (product.metadata && typeof product.metadata === 'object') {
1744
- resetHolderField(product.metadata);
1764
+ clearHolder(product.metadata);
1745
1765
  }
1746
1766
  }
1747
1767
  for (const booking of tempOrder.bookings || []) {
@@ -1759,11 +1779,13 @@ function clearTempOrderHolderAssignments(tempOrder) {
1759
1779
  for (const entry of Object.values(productsByUid)) {
1760
1780
  const origin = entry?.origin;
1761
1781
  if (!origin || typeof origin !== 'object') continue;
1782
+ clearHolder(origin);
1762
1783
  if (origin.metadata && typeof origin.metadata === 'object') {
1763
- resetHolderField(origin.metadata);
1784
+ clearHolder(origin.metadata);
1764
1785
  }
1765
1786
  if (origin._extend && typeof origin._extend === 'object') {
1766
- resetHolderField(origin._extend);
1787
+ clearHolder(origin._extend);
1788
+ delete origin._extend.holder_relations;
1767
1789
  }
1768
1790
  }
1769
1791
  }
@@ -8,6 +8,7 @@ var _BaseModule = require("../BaseModule");
8
8
  var _types = require("./types");
9
9
  var _utils = require("../../solution/ShopDiscount/utils");
10
10
  var _utils2 = require("../Cart/utils");
11
+ var _utils3 = require("../Holder/utils");
11
12
  var _decimal = _interopRequireDefault(require("decimal.js"));
12
13
  var _lodashEs = require("lodash-es");
13
14
  var _dayjs = _interopRequireDefault(require("dayjs"));
@@ -59,7 +60,7 @@ class RulesModule extends _BaseModule.BaseModule {
59
60
  if (discount.holder?.holder_type !== 'form') return true;
60
61
 
61
62
  // getProduct 会裁剪商品字段,从原始商品读取配置,套餐子项沿用父商品。
62
- const holderConfig = holderSource?.holder_config ?? holderSource?.metadata?.holder_config ?? holderSource?.origin?.holder_config ?? holderSource?.metadata?.origin?.holder_config ?? holderSource?._origin?.holder_config ?? holderSource?._extend?.holder_config ?? holderSource?._extend?.product?.holder_config ?? holderSource?._extend?.product?.metadata?.holder_config;
63
+ const holderConfig = (0, _utils3.resolveProductHolderConfig)(holderSource);
63
64
  const holderStatus = holderConfig?.status;
64
65
  const holderEnabled = holderStatus === true || ['enable', '1'].includes(String(holderStatus).trim().toLowerCase());
65
66
  if (!holderEnabled || holderConfig?.resource_id === undefined || holderConfig?.resource_id === null || holderConfig?.resource_id === '') {
@@ -540,7 +540,7 @@ class Server {
540
540
 
541
541
  // 监听 ProductsModule 同步完成事件,重新计算并推送查询结果
542
542
  this.core.effects.on(_types2.ProductsHooks.onProductsSyncCompleted, payload => {
543
- this.recomputeAndNotifyProductQuery({
543
+ return this.recomputeAndNotifyProductQuery({
544
544
  changedIds: payload?.changedIds
545
545
  });
546
546
  });
@@ -836,6 +836,9 @@ class Server {
836
836
  need_sync: 0,
837
837
  is_draft_order: 0
838
838
  };
839
+ if (!Array.isArray(fresh.holder_relations) && Array.isArray(checkoutData?.holder_relations)) {
840
+ syncedOrder.holder_relations = (0, _lodashEs.cloneDeep)(checkoutData.holder_relations);
841
+ }
839
842
  await this.order.upsertOrdersFromRemote([syncedOrder], 'checkoutSync');
840
843
  this.logInfo(`${title}: sync_sales 完整订单已同步到本地`, {
841
844
  order_id: fresh.order_id,
@@ -5502,6 +5505,9 @@ class Server {
5502
5505
  if (fresh.order_number !== undefined && fresh.order_number !== null) {
5503
5506
  patch.order_number = fresh.order_number;
5504
5507
  }
5508
+ if (Array.isArray(fresh.holder_relations)) {
5509
+ patch.holder_relations = (0, _lodashEs.cloneDeep)(fresh.holder_relations);
5510
+ }
5505
5511
  return patch;
5506
5512
  }
5507
5513
  buildSyncedOrderForPrint(params) {
@@ -6241,7 +6247,7 @@ class Server {
6241
6247
  const result = await this.computeProductQueryResult(subscriber.context, {
6242
6248
  changedIds: options?.changedIds
6243
6249
  });
6244
- subscriber.callback(result);
6250
+ await subscriber.callback(result);
6245
6251
  this.logInfo('recomputeAndNotifyProductQuery: 已推送', {
6246
6252
  subscriberId
6247
6253
  });
@@ -326,6 +326,10 @@ export declare class OrderModule extends BaseModule implements Module {
326
326
  private getIdentifiedPendingPayments;
327
327
  private shouldProtectLocalOrderFromRemoteSnapshot;
328
328
  private getUnmatchedIdentifiedPendingPayments;
329
+ /** 关系数组是完整快照,不能拼接或按商品子项生成 UID;扩展字段整体保留。 */
330
+ private applyHolderRelationsSnapshot;
331
+ /** 全量拉取缺少关系字段时,仍保留同一订单已有的关系快照。 */
332
+ private preserveOmittedHolderRelations;
329
333
  private mergeOrderRecords;
330
334
  private summarizeDuplicateOrders;
331
335
  private logDuplicateOrders;