@pisell/pisellos 2.2.264 → 2.2.266

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 (126) hide show
  1. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
  2. package/dist/model/strategy/adapter/dataVariant/adapter.js +167 -0
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
  4. package/dist/model/strategy/adapter/dataVariant/evaluator.js +780 -0
  5. package/dist/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  6. package/dist/model/strategy/adapter/dataVariant/examples.js +277 -0
  7. package/dist/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  8. package/dist/model/strategy/adapter/dataVariant/index.js +4 -0
  9. package/dist/model/strategy/adapter/dataVariant/type.d.ts +148 -0
  10. package/dist/model/strategy/adapter/dataVariant/type.js +54 -0
  11. package/dist/model/strategy/adapter/index.d.ts +4 -0
  12. package/dist/model/strategy/adapter/index.js +5 -1
  13. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +16 -10
  14. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  15. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  16. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +32 -1
  17. package/dist/modules/Discount/index.d.ts +5 -2
  18. package/dist/modules/Discount/index.js +30 -7
  19. package/dist/modules/Discount/types.d.ts +4 -0
  20. package/dist/modules/Order/index.d.ts +41 -10
  21. package/dist/modules/Order/index.js +1379 -810
  22. package/dist/modules/Order/payment-utils.d.ts +26 -0
  23. package/dist/modules/Order/payment-utils.js +225 -0
  24. package/dist/modules/Order/types.d.ts +49 -1
  25. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  26. package/dist/modules/Order/utils/orderCollectionIdentity.js +410 -0
  27. package/dist/modules/Order/utils.d.ts +4 -3
  28. package/dist/modules/Order/utils.js +61 -64
  29. package/dist/modules/Payment/index.d.ts +2 -0
  30. package/dist/modules/Payment/index.js +78 -49
  31. package/dist/modules/Payment/types.d.ts +26 -24
  32. package/dist/modules/Payment/types.js +2 -0
  33. package/dist/modules/Product/types.d.ts +22 -0
  34. package/dist/modules/ProductList/index.d.ts +1 -1
  35. package/dist/modules/ProductList/index.js +4 -2
  36. package/dist/modules/ProductList/types.d.ts +2 -0
  37. package/dist/modules/Rules/index.d.ts +2 -8
  38. package/dist/modules/Rules/index.js +55 -9
  39. package/dist/modules/Rules/types.d.ts +10 -1
  40. package/dist/server/index.d.ts +71 -0
  41. package/dist/server/index.js +2504 -1187
  42. package/dist/server/modules/order/index.d.ts +56 -5
  43. package/dist/server/modules/order/index.js +1718 -834
  44. package/dist/server/modules/order/types.d.ts +15 -3
  45. package/dist/server/modules/order/types.js +1 -1
  46. package/dist/server/modules/products/index.d.ts +31 -8
  47. package/dist/server/modules/products/index.js +549 -390
  48. package/dist/server/modules/products/types.d.ts +18 -0
  49. package/dist/solution/BaseSales/index.d.ts +67 -4
  50. package/dist/solution/BaseSales/index.js +1476 -792
  51. package/dist/solution/BaseSales/types.d.ts +6 -1
  52. package/dist/solution/BaseSales/types.js +1 -1
  53. package/dist/solution/BaseSales/utils/cartPromotion.js +19 -7
  54. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +9 -4
  55. package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
  56. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -1
  57. package/dist/solution/BookingByStep/index.d.ts +1 -1
  58. package/dist/solution/BookingTicket/index.js +94 -54
  59. package/dist/solution/BookingTicket/types.d.ts +2 -0
  60. package/dist/solution/Sales/index.d.ts +1 -0
  61. package/dist/solution/Sales/index.js +10 -2
  62. package/dist/solution/ShopDiscount/index.js +15 -14
  63. package/dist/utils/payment-number.d.ts +9 -0
  64. package/dist/utils/payment-number.js +69 -0
  65. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +50 -0
  66. package/lib/model/strategy/adapter/dataVariant/adapter.js +149 -0
  67. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +89 -0
  68. package/lib/model/strategy/adapter/dataVariant/evaluator.js +583 -0
  69. package/lib/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  70. package/lib/model/strategy/adapter/dataVariant/examples.js +293 -0
  71. package/lib/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  72. package/lib/model/strategy/adapter/dataVariant/index.js +38 -0
  73. package/lib/model/strategy/adapter/dataVariant/type.d.ts +148 -0
  74. package/lib/model/strategy/adapter/dataVariant/type.js +31 -0
  75. package/lib/model/strategy/adapter/index.d.ts +4 -0
  76. package/lib/model/strategy/adapter/index.js +13 -2
  77. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -0
  78. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +1 -0
  79. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  80. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +23 -2
  81. package/lib/modules/Discount/index.d.ts +5 -2
  82. package/lib/modules/Discount/index.js +23 -3
  83. package/lib/modules/Discount/types.d.ts +4 -0
  84. package/lib/modules/Order/index.d.ts +41 -10
  85. package/lib/modules/Order/index.js +514 -122
  86. package/lib/modules/Order/payment-utils.d.ts +26 -0
  87. package/lib/modules/Order/payment-utils.js +224 -0
  88. package/lib/modules/Order/types.d.ts +49 -1
  89. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  90. package/lib/modules/Order/utils/orderCollectionIdentity.js +418 -0
  91. package/lib/modules/Order/utils.d.ts +4 -3
  92. package/lib/modules/Order/utils.js +26 -20
  93. package/lib/modules/Payment/index.d.ts +2 -0
  94. package/lib/modules/Payment/index.js +33 -12
  95. package/lib/modules/Payment/types.d.ts +26 -24
  96. package/lib/modules/Product/types.d.ts +22 -0
  97. package/lib/modules/ProductList/index.d.ts +1 -1
  98. package/lib/modules/ProductList/index.js +4 -2
  99. package/lib/modules/ProductList/types.d.ts +2 -0
  100. package/lib/modules/Rules/index.d.ts +2 -8
  101. package/lib/modules/Rules/index.js +57 -6
  102. package/lib/modules/Rules/types.d.ts +10 -1
  103. package/lib/server/index.d.ts +71 -0
  104. package/lib/server/index.js +1002 -52
  105. package/lib/server/modules/order/index.d.ts +56 -5
  106. package/lib/server/modules/order/index.js +798 -148
  107. package/lib/server/modules/order/types.d.ts +15 -3
  108. package/lib/server/modules/products/index.d.ts +31 -8
  109. package/lib/server/modules/products/index.js +134 -35
  110. package/lib/server/modules/products/types.d.ts +18 -0
  111. package/lib/solution/BaseSales/index.d.ts +67 -4
  112. package/lib/solution/BaseSales/index.js +496 -50
  113. package/lib/solution/BaseSales/types.d.ts +6 -1
  114. package/lib/solution/BaseSales/utils/cartPromotion.js +13 -1
  115. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +9 -4
  116. package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
  117. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +8 -0
  118. package/lib/solution/BookingByStep/index.d.ts +1 -1
  119. package/lib/solution/BookingTicket/index.js +39 -11
  120. package/lib/solution/BookingTicket/types.d.ts +2 -0
  121. package/lib/solution/Sales/index.d.ts +1 -0
  122. package/lib/solution/Sales/index.js +5 -3
  123. package/lib/solution/ShopDiscount/index.js +2 -1
  124. package/lib/utils/payment-number.d.ts +9 -0
  125. package/lib/utils/payment-number.js +64 -0
  126. package/package.json +1 -1
@@ -40,6 +40,9 @@ var import_decimal = __toESM(require("decimal.js"));
40
40
  var import_lodash_es = require("lodash-es");
41
41
  var import_types2 = require("../BookingByStep/types");
42
42
  var import_utils = require("../../modules/Order/utils");
43
+ var import_payment_utils = require("../../modules/Order/payment-utils");
44
+ var import_payment_number = require("../../utils/payment-number");
45
+ var import_orderCollectionIdentity = require("../../modules/Order/utils/orderCollectionIdentity");
43
46
  var import_dayjs = __toESM(require("dayjs"));
44
47
  __reExport(BaseSales_exports, require("./types"), module.exports);
45
48
  var import_Quotation = require("../../modules/Quotation");
@@ -79,8 +82,20 @@ function isBaseSalesHistoricalDiscountEntry(discount) {
79
82
  function getBaseSalesUniqueArrayMetadataKey(key) {
80
83
  if (key === "products" || key === "bookings")
81
84
  return "unique_identification_number";
85
+ return null;
86
+ }
87
+ var BASE_SALES_PERSISTENT_ID_FIELD_BY_KIND = {
88
+ product: "order_detail_id",
89
+ booking: "schedule_event_id",
90
+ payment: "order_payment_id"
91
+ };
92
+ function getBaseSalesOrderCollectionKind(key) {
93
+ if (key === "products")
94
+ return "product";
95
+ if (key === "bookings")
96
+ return "booking";
82
97
  if (key === "payments" || key === "payment")
83
- return "unique_payment_number";
98
+ return "payment";
84
99
  return null;
85
100
  }
86
101
  function isSameBaseSalesOrderRecord(left, right) {
@@ -95,6 +110,121 @@ function isSameBaseSalesOrderRecord(left, right) {
95
110
  (value) => value !== void 0 && value !== null && value !== "" && leftIdentities.has(String(value))
96
111
  );
97
112
  }
113
+ function isBaseSalesBlankValue(value) {
114
+ return value === void 0 || value === null || value === "";
115
+ }
116
+ function mergeBaseSalesProductSnapshotFields(currentItem, loadedItem) {
117
+ var _a, _b, _c;
118
+ const mergedItem = (0, import_lodash_es.cloneDeep)(loadedItem);
119
+ if (isBaseSalesBlankValue(mergedItem.product_cover) && !isBaseSalesBlankValue(currentItem == null ? void 0 : currentItem.product_cover)) {
120
+ mergedItem.product_cover = currentItem.product_cover;
121
+ }
122
+ const currentHolderConfig = (_a = currentItem == null ? void 0 : currentItem.metadata) == null ? void 0 : _a.holder_config;
123
+ if ((((_b = mergedItem.metadata) == null ? void 0 : _b.holder_config) === void 0 || ((_c = mergedItem.metadata) == null ? void 0 : _c.holder_config) === null) && currentHolderConfig !== void 0 && currentHolderConfig !== null) {
124
+ mergedItem.metadata = {
125
+ ...mergedItem.metadata || {},
126
+ holder_config: currentHolderConfig
127
+ };
128
+ }
129
+ return mergedItem;
130
+ }
131
+ function mergeBaseSalesCollectionItem(kind, currentItem, incomingItem, uidRemaps) {
132
+ const currentReferenceUid = (0, import_orderCollectionIdentity.getOrderCollectionReferenceUid)(kind, currentItem);
133
+ const incomingReferenceUid = (0, import_orderCollectionIdentity.getOrderCollectionReferenceUid)(kind, incomingItem);
134
+ const identityMergedItem = (0, import_orderCollectionIdentity.mergeOrderCollectionItems)(
135
+ kind,
136
+ currentItem,
137
+ incomingItem
138
+ );
139
+ const mergedUid = (0, import_orderCollectionIdentity.getOrderCollectionUid)(kind, identityMergedItem);
140
+ if (mergedUid) {
141
+ for (const from of /* @__PURE__ */ new Set([currentReferenceUid, incomingReferenceUid])) {
142
+ if (!from || from === mergedUid)
143
+ continue;
144
+ uidRemaps.push({
145
+ kind,
146
+ from,
147
+ to: mergedUid,
148
+ persistentId: (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, incomingItem) || (0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, currentItem)
149
+ });
150
+ }
151
+ }
152
+ const mergedItem = mergedUid ? (0, import_orderCollectionIdentity.setOrderCollectionUid)(kind, incomingItem, mergedUid) : (0, import_lodash_es.cloneDeep)(incomingItem);
153
+ const persistentIdField = BASE_SALES_PERSISTENT_ID_FIELD_BY_KIND[kind];
154
+ if (isBaseSalesBlankValue(mergedItem[persistentIdField]) && !isBaseSalesBlankValue(identityMergedItem[persistentIdField])) {
155
+ mergedItem[persistentIdField] = identityMergedItem[persistentIdField];
156
+ }
157
+ return kind === "product" ? mergeBaseSalesProductSnapshotFields(currentItem, mergedItem) : mergedItem;
158
+ }
159
+ function mergeBaseSalesOrderCollection(kind, currentValue, incomingValue, strategy, uidRemaps) {
160
+ if (kind === "payment") {
161
+ return (0, import_payment_utils.mergeOrderPaymentListsByIdentity)(
162
+ currentValue,
163
+ incomingValue,
164
+ strategy === "preserve-local" ? { preserveUnmatchedExisting: true } : {
165
+ preserveUnmatchedExistingWhen: (payment) => (0, import_payment_utils.isIdentifiedPendingOrderPayment)(payment) || !(0, import_orderCollectionIdentity.getOrderCollectionPersistentId)("payment", payment)
166
+ }
167
+ );
168
+ }
169
+ const currentItems = (0, import_orderCollectionIdentity.normalizeOrderCollection)(kind, currentValue, {
170
+ ensureUid: false
171
+ }).items;
172
+ const incomingItems = (0, import_orderCollectionIdentity.normalizeOrderCollection)(kind, incomingValue, {
173
+ ensureUid: false
174
+ }).items;
175
+ if (strategy === "authoritative-incoming") {
176
+ const result2 = (0, import_lodash_es.cloneDeep)(incomingItems);
177
+ currentItems.forEach((currentItem) => {
178
+ const incomingIndex = result2.findIndex(
179
+ (incomingItem) => (0, import_orderCollectionIdentity.isSameOrderCollectionItem)(kind, currentItem, incomingItem)
180
+ );
181
+ if (incomingIndex !== -1) {
182
+ result2[incomingIndex] = mergeBaseSalesCollectionItem(
183
+ kind,
184
+ currentItem,
185
+ result2[incomingIndex],
186
+ uidRemaps
187
+ );
188
+ return;
189
+ }
190
+ if (!(0, import_orderCollectionIdentity.getOrderCollectionPersistentId)(kind, currentItem)) {
191
+ result2.push((0, import_lodash_es.cloneDeep)(currentItem));
192
+ }
193
+ });
194
+ return result2;
195
+ }
196
+ const result = (0, import_lodash_es.cloneDeep)(currentItems);
197
+ incomingItems.forEach((incomingItem) => {
198
+ const currentIndex = result.findIndex(
199
+ (currentItem) => (0, import_orderCollectionIdentity.isSameOrderCollectionItem)(kind, currentItem, incomingItem)
200
+ );
201
+ if (currentIndex !== -1) {
202
+ result[currentIndex] = mergeBaseSalesCollectionItem(
203
+ kind,
204
+ result[currentIndex],
205
+ incomingItem,
206
+ uidRemaps
207
+ );
208
+ return;
209
+ }
210
+ result.push((0, import_lodash_es.cloneDeep)(incomingItem));
211
+ });
212
+ return result;
213
+ }
214
+ function normalizeBaseSalesRecordCollections(sourceRecord, options) {
215
+ const normalizedRecord = (0, import_orderCollectionIdentity.normalizeOrderCollections)(
216
+ (0, import_lodash_es.cloneDeep)(sourceRecord || {}),
217
+ options
218
+ ).order;
219
+ if (Array.isArray(normalizedRecord.payment)) {
220
+ normalizedRecord.payment = (0, import_orderCollectionIdentity.normalizeOrderCollection)(
221
+ "payment",
222
+ normalizedRecord.payment,
223
+ options
224
+ ).items;
225
+ }
226
+ return normalizedRecord;
227
+ }
98
228
  function getBaseSalesMetadataUid(item, metadataKey) {
99
229
  var _a;
100
230
  const uid = ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a[metadataKey]) ?? (item == null ? void 0 : item[metadataKey]);
@@ -124,14 +254,39 @@ function mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey) {
124
254
  loadedValue.forEach(appendOrReplaceByUid);
125
255
  return result;
126
256
  }
127
- function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord) {
128
- if (!currentTempOrder)
129
- return loadedRecord;
257
+ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord, strategy) {
258
+ const normalizedLoadedRecord = normalizeBaseSalesRecordCollections(
259
+ loadedRecord || {},
260
+ { ensureUid: false }
261
+ );
262
+ if (!currentTempOrder) {
263
+ return normalizeBaseSalesRecordCollections(normalizedLoadedRecord);
264
+ }
265
+ const normalizedCurrentTempOrder = normalizeBaseSalesRecordCollections(
266
+ currentTempOrder,
267
+ { ensureUid: false }
268
+ );
269
+ const uidRemaps = [];
130
270
  const mergedRecord = (0, import_lodash_es.mergeWith)(
131
- (0, import_lodash_es.cloneDeep)(currentTempOrder),
132
- (0, import_lodash_es.cloneDeep)(loadedRecord || {}),
271
+ normalizedCurrentTempOrder,
272
+ normalizedLoadedRecord,
133
273
  (currentValue, loadedValue, key) => {
274
+ const collectionKind = getBaseSalesOrderCollectionKind(key);
275
+ if (collectionKind && Array.isArray(loadedValue)) {
276
+ return mergeBaseSalesOrderCollection(
277
+ collectionKind,
278
+ Array.isArray(currentValue) ? currentValue : [],
279
+ loadedValue,
280
+ strategy,
281
+ uidRemaps
282
+ );
283
+ }
134
284
  if (Array.isArray(currentValue) && Array.isArray(loadedValue)) {
285
+ if (key === "payments" || key === "payment") {
286
+ return (0, import_payment_utils.mergeOrderPaymentListsByIdentity)(currentValue, loadedValue, {
287
+ preserveUnmatchedExisting: true
288
+ });
289
+ }
135
290
  const metadataKey = getBaseSalesUniqueArrayMetadataKey(key);
136
291
  if (metadataKey) {
137
292
  return mergeBaseSalesUniqueArray(currentValue, loadedValue, metadataKey);
@@ -150,7 +305,21 @@ function mergeSalesDetailRecordWithTempOrder(currentTempOrder, loadedRecord) {
150
305
  }
151
306
  );
152
307
  delete mergedRecord.request_unique_idempotency_token;
153
- return mergedRecord;
308
+ return normalizeBaseSalesRecordCollections(
309
+ (0, import_orderCollectionIdentity.applyOrderCollectionUidRemaps)(mergedRecord, uidRemaps)
310
+ );
311
+ }
312
+ function filterPendingPaymentsFromLoadedSalesDetail(sourceRecord) {
313
+ if (!sourceRecord || typeof sourceRecord !== "object")
314
+ return sourceRecord;
315
+ const record = { ...sourceRecord };
316
+ if (Array.isArray(sourceRecord.payments)) {
317
+ record.payments = sourceRecord.payments.filter((payment) => !(0, import_payment_utils.isPendingOrderPayment)(payment));
318
+ }
319
+ if (Array.isArray(sourceRecord.payment)) {
320
+ record.payment = sourceRecord.payment.filter((payment) => !(0, import_payment_utils.isPendingOrderPayment)(payment));
321
+ }
322
+ return record;
154
323
  }
155
324
  var BaseSalesImpl = class extends import_BaseModule.BaseModule {
156
325
  constructor(name, version) {
@@ -163,6 +332,11 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
163
332
  order: void 0
164
333
  };
165
334
  this.otherParams = {};
335
+ /**
336
+ * 由已在初始化阶段解析过设备短号的业务解决方案写入。
337
+ * 未设置时,支付编号仍按原逻辑实时读取设备信息。
338
+ */
339
+ this.paymentNumberDevicePrefix = null;
166
340
  // 当前缓存中已加载的最新 SalesDetail;只读 getter 走它对外暴露详情数据。
167
341
  this.currentSalesDetail = null;
168
342
  this.discountConfigCacheKey = null;
@@ -172,9 +346,13 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
172
346
  this.queuedAutoPaymentSync = false;
173
347
  this.autoPaymentSyncFlushing = false;
174
348
  this.autoPaymentSyncTimer = null;
175
- this.salesDetailLoadInFlight = false;
349
+ this.salesDetailLoadInFlightCount = 0;
350
+ this.salesDetailLoadSequence = 0;
351
+ this.salesDetailHydrateQueue = Promise.resolve();
176
352
  this.serverOrderChangeUnsubscribe = null;
177
353
  this.serverOrderChangeHydrateInFlight = null;
354
+ this.queuedServerOrderChanges = [];
355
+ this.serverOrderChangeSyncEnabled = false;
178
356
  }
179
357
  /**
180
358
  * 子类可覆盖此方法以追加/收敛要注册的子模块。
@@ -248,19 +426,59 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
248
426
  ].filter(Boolean);
249
427
  return currentRecords.some((record) => isSameBaseSalesOrderRecord(record, order));
250
428
  }
429
+ setServerOrderChangeSyncEnabled(enabled) {
430
+ this.serverOrderChangeSyncEnabled = enabled;
431
+ if (!enabled)
432
+ this.queuedServerOrderChanges = [];
433
+ }
434
+ queueLatestServerOrderChange(order) {
435
+ const snapshot = (0, import_lodash_es.cloneDeep)(order);
436
+ const existingIndex = this.queuedServerOrderChanges.findIndex(
437
+ (queued) => isSameBaseSalesOrderRecord(queued, snapshot)
438
+ );
439
+ if (existingIndex >= 0) {
440
+ this.queuedServerOrderChanges[existingIndex] = snapshot;
441
+ return;
442
+ }
443
+ this.queuedServerOrderChanges.push(snapshot);
444
+ }
445
+ async drainQueuedServerOrderChanges() {
446
+ if (!this.serverOrderChangeSyncEnabled || this.salesDetailLoadInFlightCount > 0 || this.serverOrderChangeHydrateInFlight || this.queuedServerOrderChanges.length === 0)
447
+ return;
448
+ const changedOrders = this.queuedServerOrderChanges;
449
+ this.queuedServerOrderChanges = [];
450
+ await this.syncCurrentSalesDetailFromServerOrderChange({ changedOrders });
451
+ }
251
452
  async syncCurrentSalesDetailFromServerOrderChange(payload) {
252
453
  const changedOrders = Array.isArray(payload) ? payload : Array.isArray(payload == null ? void 0 : payload.changedOrders) ? payload.changedOrders : (payload == null ? void 0 : payload.data) && typeof payload.data === "object" ? [payload.data] : [];
253
- if (this.salesDetailLoadInFlight || this.serverOrderChangeHydrateInFlight)
454
+ if (!this.serverOrderChangeSyncEnabled)
455
+ return;
456
+ if (this.salesDetailLoadInFlightCount > 0) {
457
+ changedOrders.forEach(
458
+ (order) => this.queueLatestServerOrderChange(order)
459
+ );
254
460
  return;
461
+ }
255
462
  const changedOrder = changedOrders.find(
256
463
  (order) => this.isCurrentSalesOrderRecord(order)
257
464
  );
258
465
  if (!changedOrder)
259
466
  return;
467
+ if (this.serverOrderChangeHydrateInFlight) {
468
+ this.queueLatestServerOrderChange(changedOrder);
469
+ return;
470
+ }
260
471
  if (!this.store.order)
261
472
  return;
262
473
  this.serverOrderChangeHydrateInFlight = (async () => {
263
- const sales = await this.store.order.hydrateTempOrderFromRecord(changedOrder, {
474
+ var _a, _b;
475
+ const currentTempOrder = (_b = (_a = this.store.order).getTempOrder) == null ? void 0 : _b.call(_a);
476
+ const record = mergeSalesDetailRecordWithTempOrder(
477
+ currentTempOrder,
478
+ changedOrder,
479
+ "authoritative-incoming"
480
+ );
481
+ const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
264
482
  recalcOnHydrate: false
265
483
  });
266
484
  this.currentSalesDetail = sales;
@@ -270,6 +488,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
270
488
  await this.serverOrderChangeHydrateInFlight;
271
489
  } finally {
272
490
  this.serverOrderChangeHydrateInFlight = null;
491
+ await this.drainQueuedServerOrderChanges();
273
492
  }
274
493
  }
275
494
  registerServerOrderChangeSync() {
@@ -279,13 +498,42 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
279
498
  if (!effects || typeof effects.on !== "function")
280
499
  return;
281
500
  this.serverOrderChangeUnsubscribe = effects.on(SERVER_ORDER_CHANGED_EVENT, (payload) => {
282
- void this.syncCurrentSalesDetailFromServerOrderChange(payload).catch((error) => {
501
+ return this.syncCurrentSalesDetailFromServerOrderChange(payload).catch((error) => {
283
502
  this.logError("sync sales detail from server order change failed", {
284
503
  error: error instanceof Error ? error.message : String(error)
285
504
  });
286
505
  });
287
506
  });
288
507
  }
508
+ async hydrateLatestLoadedSalesDetail(record, loadSequence) {
509
+ let hydratedSales = null;
510
+ let skippedBeforeHydrate = false;
511
+ const hydrateTask = async () => {
512
+ if (loadSequence !== this.salesDetailLoadSequence) {
513
+ skippedBeforeHydrate = true;
514
+ return;
515
+ }
516
+ if (!this.store.order)
517
+ throw new Error("order 模块未初始化");
518
+ const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
519
+ recalcOnHydrate: false
520
+ });
521
+ hydratedSales = sales;
522
+ if (loadSequence !== this.salesDetailLoadSequence)
523
+ return;
524
+ this.currentSalesDetail = sales;
525
+ await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
526
+ };
527
+ const queuedTask = this.salesDetailHydrateQueue.then(hydrateTask, hydrateTask);
528
+ this.salesDetailHydrateQueue = queuedTask.then(
529
+ () => void 0,
530
+ () => void 0
531
+ );
532
+ await queuedTask;
533
+ if (skippedBeforeHydrate)
534
+ return record;
535
+ return hydratedSales || this.currentSalesDetail || record;
536
+ }
289
537
  hydrateOrderPaymentNames(payments) {
290
538
  if (!payments.length)
291
539
  return [];
@@ -619,6 +867,27 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
619
867
  const coreData = (_f = (_d = (_c = app == null ? void 0 : app.models) == null ? void 0 : _c.getStore) == null ? void 0 : (_e = _d.call(_c)).getDataByModel) == null ? void 0 : _f.call(_e, "core", "core");
620
868
  return coreData == null ? void 0 : coreData[key];
621
869
  }
870
+ /**
871
+ * 复用业务解决方案初始化时已解析的支付设备短号。
872
+ * 空值会清除缓存,使后续支付恢复实时读取设备信息的兼容路径。
873
+ */
874
+ setPaymentNumberDevicePrefix(prefix) {
875
+ const normalized = String(prefix ?? "").trim();
876
+ this.paymentNumberDevicePrefix = normalized || null;
877
+ }
878
+ getPaymentNumberDevicePrefixSync() {
879
+ if (!this.appPlugin)
880
+ return "LOCAL";
881
+ return (0, import_payment_number.resolvePaymentNumberDevicePrefixFromDeviceId)((key) => this.getAppData(key));
882
+ }
883
+ getPaymentNumberDevicePrefixAsync() {
884
+ if (!this.appPlugin)
885
+ return Promise.resolve("LOCAL");
886
+ if (this.paymentNumberDevicePrefix) {
887
+ return Promise.resolve(this.paymentNumberDevicePrefix);
888
+ }
889
+ return (0, import_payment_number.resolvePaymentNumberDevicePrefix)((key) => this.getAppData(key));
890
+ }
622
891
  syncAppDataToTempOrder(tempOrder) {
623
892
  const isPriceIncludeTax = this.getAppData("is_price_include_tax");
624
893
  const taxCountryCode = this.getAppData("tax_country_code");
@@ -659,6 +928,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
659
928
  var _a, _b;
660
929
  this.core = core;
661
930
  this.initializeOptions = options || {};
931
+ this.paymentNumberDevicePrefix = null;
662
932
  this.otherParams = options.otherParams || {};
663
933
  this.cacheId = (_a = this.otherParams) == null ? void 0 : _a.cacheId;
664
934
  this.reusedSharedSubModuleNames.clear();
@@ -720,6 +990,9 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
720
990
  }
721
991
  });
722
992
  this.currentSalesDetail = null;
993
+ this.paymentNumberDevicePrefix = null;
994
+ this.queuedServerOrderChanges = [];
995
+ this.salesDetailLoadSequence += 1;
723
996
  await this.core.effects.emit(`${this.name}:onDestroy`, {});
724
997
  super.destroy();
725
998
  }
@@ -733,7 +1006,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
733
1006
  async loadSalesDetail(orderIdOrParams) {
734
1007
  if (!this.store.order)
735
1008
  throw new Error("order 模块未初始化");
736
- this.salesDetailLoadInFlight = true;
1009
+ const loadSequence = ++this.salesDetailLoadSequence;
1010
+ this.salesDetailLoadInFlightCount += 1;
737
1011
  try {
738
1012
  const params = typeof orderIdOrParams === "object" ? orderIdOrParams : { orderId: orderIdOrParams };
739
1013
  const externalSaleNumber = params.externalSaleNumber || params.external_sale_number;
@@ -750,17 +1024,31 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
750
1024
  const message = loadedRecord && (loadedRecord.message || loadedRecord.msg) || `加载销售详情失败: ${lookup}`;
751
1025
  throw new Error(message);
752
1026
  }
753
- const remoteRecord = preloadedSalesDetail ?? loadedRecord.data;
1027
+ const remoteRecord = filterPendingPaymentsFromLoadedSalesDetail(
1028
+ preloadedSalesDetail ?? loadedRecord.data
1029
+ );
754
1030
  const currentTempOrder = params.merge ? this.store.order.getTempOrder() : null;
755
- const record = params.merge ? mergeSalesDetailRecordWithTempOrder(currentTempOrder, remoteRecord) : remoteRecord;
756
- const sales = await this.store.order.hydrateTempOrderFromRecord(record, {
757
- recalcOnHydrate: false
758
- });
759
- this.currentSalesDetail = sales;
760
- await this.core.effects.emit(`${this.name}:onSalesOrderLoaded`, { sales });
761
- return sales;
1031
+ const mergedRecord = params.merge ? mergeSalesDetailRecordWithTempOrder(
1032
+ currentTempOrder,
1033
+ remoteRecord,
1034
+ "preserve-local"
1035
+ ) : remoteRecord;
1036
+ const record = filterPendingPaymentsFromLoadedSalesDetail(mergedRecord);
1037
+ return await this.hydrateLatestLoadedSalesDetail(record, loadSequence);
762
1038
  } finally {
763
- this.salesDetailLoadInFlight = false;
1039
+ this.salesDetailLoadInFlightCount = Math.max(
1040
+ 0,
1041
+ this.salesDetailLoadInFlightCount - 1
1042
+ );
1043
+ if (this.salesDetailLoadInFlightCount === 0) {
1044
+ try {
1045
+ await this.drainQueuedServerOrderChanges();
1046
+ } catch (error) {
1047
+ this.logError("drain queued server order changes failed", {
1048
+ error: error instanceof Error ? error.message : String(error)
1049
+ });
1050
+ }
1051
+ }
764
1052
  }
765
1053
  }
766
1054
  /** 获取当前已加载的销售详情(只读快照)。未加载过则返回 null。 */
@@ -1094,7 +1382,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1094
1382
  });
1095
1383
  }
1096
1384
  async loadDiscountConfig(params) {
1097
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
1385
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
1098
1386
  if (!this.store.order)
1099
1387
  throw new Error("order 模块未初始化");
1100
1388
  const tempOrder = this.store.order.ensureTempOrder();
@@ -1132,7 +1420,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1132
1420
  if (hasManualDiscountSelection && currentDiscountList.length) {
1133
1421
  return {
1134
1422
  productList: tempOrder.products || [],
1135
- discountList: currentDiscountList
1423
+ discountList: currentDiscountList,
1424
+ availableWalletIds: this.getAvailableWalletIds()
1136
1425
  };
1137
1426
  }
1138
1427
  let nextDiscountList = this.mergeHistoricalDiscountList(
@@ -1161,17 +1450,17 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1161
1450
  });
1162
1451
  return {
1163
1452
  productList: tempOrder.products || [],
1164
- discountList: nextDiscountList
1453
+ discountList: nextDiscountList,
1454
+ availableWalletIds: this.getAvailableWalletIds()
1165
1455
  };
1166
1456
  }
1167
1457
  if (rulesModule) {
1168
- const holders = ((_l = tempOrder.holder) == null ? void 0 : _l.form_record) || [];
1169
- const orderTotalAmount = Number(((_m = orderStore.summary) == null ? void 0 : _m.total_amount) || 0);
1458
+ const orderTotalAmount = Number(((_l = orderStore.summary) == null ? void 0 : _l.total_amount) || 0);
1170
1459
  console.log("[BaseSales.applyDiscountConfig.calcDiscount]");
1171
1460
  const result = rulesModule.calcDiscount({
1172
1461
  productList: tempOrder.products,
1173
1462
  discountList: nextDiscountList,
1174
- holders,
1463
+ holders: [],
1175
1464
  isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1176
1465
  orderTotalAmount
1177
1466
  }) || { productList: tempOrder.products, discountList: nextDiscountList };
@@ -1182,8 +1471,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1182
1471
  );
1183
1472
  }
1184
1473
  for (const product of tempOrder.products || []) {
1185
- const productUid = (_n = product.metadata) == null ? void 0 : _n.unique_identification_number;
1186
- const runtimeOrigin = productUid ? (_q = (_p = (_o = tempOrder._extend) == null ? void 0 : _o.productsByUid) == null ? void 0 : _p[productUid]) == null ? void 0 : _q.origin : void 0;
1474
+ const productUid = (_m = product.metadata) == null ? void 0 : _m.unique_identification_number;
1475
+ const runtimeOrigin = productUid ? (_p = (_o = (_n = tempOrder._extend) == null ? void 0 : _n.productsByUid) == null ? void 0 : _o[productUid]) == null ? void 0 : _p.origin : void 0;
1187
1476
  if ((runtimeOrigin == null ? void 0 : runtimeOrigin.isManualDiscount) || isBaseSalesManualProductDiscountProduct(product))
1188
1477
  continue;
1189
1478
  const totalPerUnitDiscount = (product.discount_list || []).reduce(
@@ -1191,7 +1480,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1191
1480
  0
1192
1481
  );
1193
1482
  const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
1194
- const sourcePrice = ((_r = product.metadata) == null ? void 0 : _r.source_product_price) ?? (((_s = product.metadata) == null ? void 0 : _s.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
1483
+ const sourcePrice = ((_q = product.metadata) == null ? void 0 : _q.source_product_price) ?? (((_r = product.metadata) == null ? void 0 : _r.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
1195
1484
  const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
1196
1485
  const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
1197
1486
  if (product.metadata) {
@@ -1223,11 +1512,18 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1223
1512
  });
1224
1513
  return {
1225
1514
  productList: tempOrder.products || [],
1226
- discountList: nextDiscountList
1515
+ discountList: nextDiscountList,
1516
+ availableWalletIds: this.getAvailableWalletIds()
1227
1517
  };
1228
1518
  }
1519
+ getAvailableWalletIds() {
1520
+ var _a;
1521
+ if (!((_a = this.store.order) == null ? void 0 : _a.getAvailableWalletIds))
1522
+ return [];
1523
+ return this.store.order.getAvailableWalletIds();
1524
+ }
1229
1525
  async bestDiscount(cb) {
1230
- var _a, _b, _c, _d;
1526
+ var _a, _b, _c;
1231
1527
  if (!this.store.order)
1232
1528
  throw new Error("order 模块未初始化");
1233
1529
  const tempOrder = this.store.order.ensureTempOrder();
@@ -1246,13 +1542,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1246
1542
  };
1247
1543
  await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
1248
1544
  if (rulesModule) {
1249
- const holders = ((_c = tempOrder.holder) == null ? void 0 : _c.form_record) || [];
1250
- const orderTotalAmount = Number(((_d = orderStore.summary) == null ? void 0 : _d.total_amount) || 0);
1545
+ const orderTotalAmount = Number(((_c = orderStore.summary) == null ? void 0 : _c.total_amount) || 0);
1251
1546
  console.log("[BaseSales.bestDiscount.calcDiscount]");
1252
1547
  result = rulesModule.calcDiscount({
1253
1548
  productList: tempOrder.products,
1254
1549
  discountList: nextDiscountList,
1255
- holders,
1550
+ holders: [],
1256
1551
  isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1257
1552
  orderTotalAmount
1258
1553
  }) || result;
@@ -1278,6 +1573,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1278
1573
  }
1279
1574
  await this.store.order.recalculateSummary({ createIfMissing: true });
1280
1575
  this.store.order.persistTempOrder();
1576
+ await this.effectsEmit("onDiscountApplied", {
1577
+ productList: tempOrder.products || [],
1578
+ discountList: nextDiscountList,
1579
+ selectedDiscountList: tempOrder.discount_list || [],
1580
+ tempOrder
1581
+ });
1281
1582
  cb == null ? void 0 : cb(result);
1282
1583
  return result;
1283
1584
  }
@@ -1286,6 +1587,30 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1286
1587
  return [];
1287
1588
  return this.store.order.getDiscountList();
1288
1589
  }
1590
+ /** 读取 Discount 模块原始券列表(未经过 bookingTime 等过滤)。 */
1591
+ getOriginalDiscountList() {
1592
+ var _a, _b;
1593
+ if (!this.store.order)
1594
+ return [];
1595
+ const discountModule = (_a = this.store.order.store) == null ? void 0 : _a.discount;
1596
+ return ((_b = discountModule == null ? void 0 : discountModule.getOriginalDiscountList) == null ? void 0 : _b.call(discountModule)) || [];
1597
+ }
1598
+ /**
1599
+ * 同步写入 Discount 模块的 discountList / originalDiscountList。
1600
+ * 供 Holder 补全等场景在 OS store 层更新 machinecode holder 字段。
1601
+ */
1602
+ async replaceDiscountStoreLists(params) {
1603
+ var _a;
1604
+ if (!this.store.order)
1605
+ throw new Error("order 模块未初始化");
1606
+ const discountModule = (_a = this.store.order.store) == null ? void 0 : _a.discount;
1607
+ if (!discountModule)
1608
+ return;
1609
+ if (params.originalDiscountList) {
1610
+ await discountModule.setOriginalDiscountList(params.originalDiscountList);
1611
+ }
1612
+ await discountModule.setDiscountList(params.discountList);
1613
+ }
1289
1614
  async scanPromotionCode(code, customerId) {
1290
1615
  try {
1291
1616
  if (!this.store.order)
@@ -1294,11 +1619,19 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1294
1619
  if (raw.isAvailable) {
1295
1620
  await this.store.order.recalculateSummary({ createIfMissing: true });
1296
1621
  this.store.order.persistTempOrder();
1622
+ const tempOrder = this.store.order.ensureTempOrder();
1623
+ await this.effectsEmit("onDiscountApplied", {
1624
+ productList: tempOrder.products || [],
1625
+ discountList: this.store.order.getDiscountList(),
1626
+ selectedDiscountList: tempOrder.discount_list || [],
1627
+ tempOrder
1628
+ });
1297
1629
  }
1298
1630
  return {
1299
1631
  isAvailable: raw.isAvailable,
1300
1632
  type: raw.type,
1301
- unavailableReason: raw.unavailableReason
1633
+ unavailableReason: raw.unavailableReason,
1634
+ scannedDiscountList: raw.scannedDiscountList
1302
1635
  };
1303
1636
  } catch (error) {
1304
1637
  throw error;
@@ -1306,7 +1639,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1306
1639
  }
1307
1640
  // TODO 需要优化,这段逻辑太长了,里面应该有些历史遗留问题
1308
1641
  async setDiscountSelected(params) {
1309
- var _a, _b, _c, _d, _e, _f, _g, _h;
1642
+ var _a, _b, _c, _d, _e, _f, _g;
1310
1643
  try {
1311
1644
  if (!this.store.order)
1312
1645
  throw new Error("order 模块未初始化");
@@ -1323,17 +1656,16 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1323
1656
  const orderStore = this.store.order.store || {};
1324
1657
  const discountModule = orderStore.discount;
1325
1658
  const rulesModule = orderStore.rules;
1326
- const holders = ((_a = tempOrder.holder) == null ? void 0 : _a.form_record) || [];
1327
1659
  let nextDiscountList = updated;
1328
1660
  await (discountModule == null ? void 0 : discountModule.setDiscountList(updated));
1329
1661
  if (rulesModule) {
1330
- const orderTotalAmount = Number(((_b = orderStore.summary) == null ? void 0 : _b.total_amount) || 0);
1662
+ const orderTotalAmount = Number(((_a = orderStore.summary) == null ? void 0 : _a.total_amount) || 0);
1331
1663
  console.log("[BaseSales.setDiscountSelected.calcDiscount]");
1332
1664
  const result = rulesModule.calcDiscount(
1333
1665
  {
1334
1666
  productList: tempOrder.products,
1335
1667
  discountList: updated,
1336
- holders,
1668
+ holders: [],
1337
1669
  isFormSubject: (product) => (0, import_utils.resolveIsFormSubject)(tempOrder, product),
1338
1670
  orderTotalAmount
1339
1671
  },
@@ -1373,8 +1705,8 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1373
1705
  return rid != null && selectedResourceIds.has(rid);
1374
1706
  });
1375
1707
  for (const product of tempOrder.products) {
1376
- const productUid = (_c = product.metadata) == null ? void 0 : _c.unique_identification_number;
1377
- const runtimeOrigin = productUid ? (_f = (_e = (_d = tempOrder._extend) == null ? void 0 : _d.productsByUid) == null ? void 0 : _e[productUid]) == null ? void 0 : _f.origin : void 0;
1708
+ const productUid = (_b = product.metadata) == null ? void 0 : _b.unique_identification_number;
1709
+ const runtimeOrigin = productUid ? (_e = (_d = (_c = tempOrder._extend) == null ? void 0 : _c.productsByUid) == null ? void 0 : _d[productUid]) == null ? void 0 : _e.origin : void 0;
1378
1710
  if ((runtimeOrigin == null ? void 0 : runtimeOrigin.isManualDiscount) || isBaseSalesManualProductDiscountProduct(product))
1379
1711
  continue;
1380
1712
  product.discount_list = filterSelectedDiscountDetails(product.discount_list);
@@ -1398,7 +1730,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1398
1730
  0
1399
1731
  );
1400
1732
  const optionSum = (0, import_utils.sumOptionUnitPrice)((0, import_utils.getProductSkuOptions)(product));
1401
- const sourcePrice = ((_g = product.metadata) == null ? void 0 : _g.source_product_price) ?? (((_h = product.metadata) == null ? void 0 : _h.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
1733
+ const sourcePrice = ((_f = product.metadata) == null ? void 0 : _f.source_product_price) ?? (((_g = product.metadata) == null ? void 0 : _g.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
1402
1734
  const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
1403
1735
  const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
1404
1736
  if (product.metadata) {
@@ -1452,6 +1784,12 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1452
1784
  }
1453
1785
  await this.store.order.recalculateSummary({ createIfMissing: true });
1454
1786
  this.store.order.persistTempOrder();
1787
+ await this.effectsEmit("onDiscountApplied", {
1788
+ productList: tempOrder.products || [],
1789
+ discountList: result.discountList || [],
1790
+ selectedDiscountList: tempOrder.discount_list || [],
1791
+ tempOrder
1792
+ });
1455
1793
  } catch (error) {
1456
1794
  throw error;
1457
1795
  }
@@ -1486,6 +1824,20 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1486
1824
  };
1487
1825
  return this.store.order.submitTempOrder(submitParams);
1488
1826
  }
1827
+ async saveSalesOrderDraft(params) {
1828
+ var _a, _b, _c, _d;
1829
+ if (!this.store.order) {
1830
+ throw new Error("BaseSales 解决方案需要 order 模块支持");
1831
+ }
1832
+ return this.store.order.saveTempOrderAsDraft({
1833
+ cacheId: this.cacheId,
1834
+ platform: (params == null ? void 0 : params.platform) ?? ((_a = this.otherParams) == null ? void 0 : _a.platform),
1835
+ businessCode: (params == null ? void 0 : params.businessCode) ?? ((_b = this.otherParams) == null ? void 0 : _b.businessCode) ?? ((_c = this.otherParams) == null ? void 0 : _c.business_code),
1836
+ channel: (params == null ? void 0 : params.channel) ?? this.getSubmitOrderSalesChannel(),
1837
+ type: (params == null ? void 0 : params.type) ?? ((_d = this.otherParams) == null ? void 0 : _d.type),
1838
+ ...(params == null ? void 0 : params.enhancePayload) !== void 0 ? { enhancePayload: params.enhancePayload } : {}
1839
+ });
1840
+ }
1489
1841
  async submitTempOrderAsync(params) {
1490
1842
  var _a, _b, _c, _d;
1491
1843
  if (!this.store.order) {
@@ -1686,8 +2038,29 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1686
2038
  }
1687
2039
  }
1688
2040
  }
1689
- /** 追加单个支付项到当前订单。 */
2041
+ /**
2042
+ * 同步兼容入口。无法等待 IoT 短号时,按调用当下的 device_id 或 LOCAL 生成。
2043
+ */
1690
2044
  addOrderPayment(payment) {
2045
+ const hasPaymentNumber = String(
2046
+ payment.payment_number || ""
2047
+ ).trim() !== "";
2048
+ return this.addOrderPaymentWithDevicePrefix(
2049
+ payment,
2050
+ hasPaymentNumber ? "LOCAL" : this.getPaymentNumberDevicePrefixSync()
2051
+ );
2052
+ }
2053
+ /**
2054
+ * 创建新支付项时优先使用业务解决方案初始化阶段缓存的设备短号;
2055
+ * 未缓存的通用 BaseSales 保持实时读取设备信息的兼容语义。
2056
+ */
2057
+ async addOrderPaymentAsync(payment) {
2058
+ const paymentRecord = payment;
2059
+ const hasPaymentNumber = String(paymentRecord.payment_number || "").trim() !== "";
2060
+ const devicePrefix = hasPaymentNumber ? "LOCAL" : await this.getPaymentNumberDevicePrefixAsync();
2061
+ return this.addOrderPaymentWithDevicePrefix(payment, devicePrefix);
2062
+ }
2063
+ addOrderPaymentWithDevicePrefix(payment, devicePrefix) {
1691
2064
  var _a;
1692
2065
  if (!this.store.order)
1693
2066
  throw new Error("order 模块未初始化");
@@ -1704,21 +2077,26 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1704
2077
  if (shopWalletPassId !== void 0 && shopWalletPassId !== null) {
1705
2078
  metadata.shop_wallet_pass_id = shopWalletPassId;
1706
2079
  }
1707
- if (!metadata.unique_payment_number) {
1708
- metadata.unique_payment_number = (0, import_utils.createUuidV4)();
1709
- }
2080
+ const normalizedPaymentRecord = (0, import_payment_utils.ensureOrderPaymentNumber)(
2081
+ paymentRecord,
2082
+ devicePrefix,
2083
+ import_utils.createUuidV4
2084
+ );
1710
2085
  const paymentTimestamp = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
1711
2086
  const paymentTime = paymentRecord.payment_time ?? paymentTimestamp;
1712
2087
  const createdAt = paymentRecord.created_at ?? paymentTimestamp;
1713
2088
  const serviceCharge = paymentRecord.service_charge && typeof paymentRecord.service_charge === "object" ? paymentRecord.service_charge : null;
1714
2089
  const calculatedServiceFee = serviceCharge ? new import_decimal.default(paymentRecord.origin_amount ?? paymentRecord.amount ?? 0).times(serviceCharge.percentage || 0).plus(serviceCharge.amount || 0).toDecimalPlaces(2).toFixed(2) : void 0;
1715
2090
  const payments = this.store.order.addOrderPayment({
1716
- ...paymentRecord,
2091
+ ...normalizedPaymentRecord,
1717
2092
  ...calculatedServiceFee !== void 0 ? { service_fee: calculatedServiceFee } : {},
1718
2093
  metadata,
1719
2094
  payment_time: paymentTime,
1720
2095
  created_at: createdAt
1721
2096
  });
2097
+ if (paymentRecord.status === "payment_pending") {
2098
+ return payments;
2099
+ }
1722
2100
  const amountSnapshot = this.store.order.getOrderAmountSnapshot();
1723
2101
  const syncState = this.store.order.getOrderSyncState();
1724
2102
  if (amountSnapshot) {
@@ -1740,10 +2118,73 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1740
2118
  return payments;
1741
2119
  }
1742
2120
  /** 更新当前订单中的指定支付项。 */
1743
- updateOrderPayment(paymentIdentity, updates) {
2121
+ async updateOrderPayment(paymentIdentity, updates, options = {}) {
2122
+ var _a, _b, _c;
1744
2123
  if (!this.store.order)
1745
2124
  throw new Error("order 模块未初始化");
1746
- return this.store.order.updateOrderPayment(paymentIdentity, updates);
2125
+ const matchMode = options.matchBy === "compat" || options.matchBy === "legacy" ? "compat" : "payment_number";
2126
+ const previousMatch = (0, import_payment_utils.resolveOrderPaymentIdentity)(
2127
+ this.store.order.getOrderPayments(),
2128
+ paymentIdentity,
2129
+ matchMode
2130
+ );
2131
+ const previousPayment = previousMatch == null ? void 0 : previousMatch.payment;
2132
+ if ((previousPayment == null ? void 0 : previousPayment.status) === "paid" && !options.applyUpdatesWhenPaid) {
2133
+ const currentPayments = this.store.order.getOrderPayments();
2134
+ let syncResult2;
2135
+ if (options.submitWhenPaid && options.forceSubmitIfPaid) {
2136
+ syncResult2 = await this.syncPaymentsToOrder({
2137
+ payments: currentPayments,
2138
+ paymentStatus: this.getPaymentStatusForSync(currentPayments),
2139
+ submitWhenPaid: true,
2140
+ smallTicketDataFlag: options.smallTicketDataFlag ?? 1
2141
+ });
2142
+ }
2143
+ return {
2144
+ updated: false,
2145
+ payment: previousPayment,
2146
+ payments: currentPayments,
2147
+ summary: ((_a = this.store.order.getOrderAmountSnapshot()) == null ? void 0 : _a.summary) || null,
2148
+ ...syncResult2 !== void 0 ? { syncResult: syncResult2 } : {}
2149
+ };
2150
+ }
2151
+ const result = await this.store.order.updateOrderPayment(paymentIdentity, updates, {
2152
+ matchBy: matchMode
2153
+ });
2154
+ let draftResult;
2155
+ let draftError;
2156
+ if (options.persistDraft !== false) {
2157
+ try {
2158
+ draftResult = await this.saveSalesOrderDraft();
2159
+ } catch (error) {
2160
+ draftError = error;
2161
+ this.logError("updateOrderPayment: 保存支付草稿失败", {
2162
+ paymentIdentity,
2163
+ error: error instanceof Error ? error.message : String(error)
2164
+ });
2165
+ if (!options.submitWhenPaid)
2166
+ throw error;
2167
+ }
2168
+ }
2169
+ const becamePaid = (previousPayment == null ? void 0 : previousPayment.status) !== "paid" && ((_b = result.payment) == null ? void 0 : _b.status) === "paid";
2170
+ const shouldSubmit = Boolean(
2171
+ options.submitWhenPaid && ((_c = result.payment) == null ? void 0 : _c.status) === "paid" && (becamePaid || options.forceSubmitIfPaid)
2172
+ );
2173
+ let syncResult;
2174
+ if (shouldSubmit) {
2175
+ syncResult = await this.syncPaymentsToOrder({
2176
+ payments: result.payments,
2177
+ paymentStatus: this.getPaymentStatusForSync(result.payments),
2178
+ submitWhenPaid: true,
2179
+ smallTicketDataFlag: options.smallTicketDataFlag ?? 1
2180
+ });
2181
+ }
2182
+ return {
2183
+ ...result,
2184
+ ...draftResult !== void 0 ? { draftResult } : {},
2185
+ ...draftError !== void 0 ? { draftError } : {},
2186
+ ...syncResult !== void 0 ? { syncResult } : {}
2187
+ };
1747
2188
  }
1748
2189
  /** 删除当前订单中的指定支付项。 */
1749
2190
  deleteOrderPayment(paymentIdentity) {
@@ -1757,6 +2198,11 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1757
2198
  throw new Error("order 模块未初始化");
1758
2199
  return this.store.order.updateVoucherOrderPayments(payments, options);
1759
2200
  }
2201
+ async updateVoucherOrderPaymentsAsync(payments, options) {
2202
+ if (!this.store.order)
2203
+ throw new Error("order 模块未初始化");
2204
+ return this.store.order.updateVoucherOrderPaymentsAsync(payments, options);
2205
+ }
1760
2206
  confirmPendingVoucherPayments() {
1761
2207
  if (!this.store.order)
1762
2208
  throw new Error("order 模块未初始化");