@pisell/pisellos 2.2.267 → 2.2.269

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 (121) hide show
  1. package/dist/core/index.d.ts +2 -0
  2. package/dist/core/index.js +7 -0
  3. package/dist/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  4. package/dist/model/strategy/adapter/promotion/adapter.js +23 -0
  5. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  6. package/dist/model/strategy/adapter/promotion/evaluator.js +279 -6
  7. package/dist/model/strategy/adapter/promotion/examples.d.ts +86 -0
  8. package/dist/model/strategy/adapter/promotion/examples.js +99 -0
  9. package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
  10. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  11. package/dist/model/strategy/adapter/promotion/type.d.ts +90 -2
  12. package/dist/model/strategy/adapter/promotion/type.js +45 -0
  13. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +12 -10
  14. package/dist/modules/OpenData/index.d.ts +2 -0
  15. package/dist/modules/OpenData/index.js +8 -0
  16. package/dist/modules/Order/index.d.ts +33 -13
  17. package/dist/modules/Order/index.js +883 -524
  18. package/dist/modules/Order/payment-utils.d.ts +26 -0
  19. package/dist/modules/Order/payment-utils.js +225 -0
  20. package/dist/modules/Order/types.d.ts +56 -4
  21. package/dist/modules/Order/types.js +11 -0
  22. package/dist/modules/Order/utils/orderCollectionIdentity.js +7 -2
  23. package/dist/modules/Order/utils.js +10 -6
  24. package/dist/modules/Payment/index.d.ts +2 -0
  25. package/dist/modules/Payment/index.js +78 -49
  26. package/dist/modules/Payment/types.d.ts +104 -25
  27. package/dist/modules/Payment/types.js +17 -0
  28. package/dist/modules/Payment/walletpass.d.ts +38 -1
  29. package/dist/modules/Payment/walletpass.js +917 -114
  30. package/dist/modules/Rules/index.d.ts +3 -0
  31. package/dist/modules/Rules/index.js +146 -106
  32. package/dist/modules/SalesSummary/utils.js +7 -1
  33. package/dist/server/index.d.ts +16 -0
  34. package/dist/server/index.js +1940 -1043
  35. package/dist/server/modules/index.d.ts +1 -1
  36. package/dist/server/modules/order/index.d.ts +70 -4
  37. package/dist/server/modules/order/index.js +1816 -728
  38. package/dist/server/modules/order/types.d.ts +25 -3
  39. package/dist/server/modules/order/types.js +7 -1
  40. package/dist/solution/BaseSales/index.d.ts +118 -9
  41. package/dist/solution/BaseSales/index.js +1849 -480
  42. package/dist/solution/BaseSales/types.d.ts +55 -1
  43. package/dist/solution/BaseSales/types.js +2 -1
  44. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  45. package/dist/solution/BaseSales/utils/cartPromotion.js +90 -31
  46. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  47. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  48. package/dist/solution/BookingTicket/index.d.ts +8 -16
  49. package/dist/solution/BookingTicket/index.js +138 -52
  50. package/dist/solution/BookingTicket/types.d.ts +4 -0
  51. package/dist/solution/BookingTicket/utils/cartView.js +44 -32
  52. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  53. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +173 -83
  54. package/dist/solution/Sales/index.d.ts +2 -0
  55. package/dist/solution/Sales/index.js +26 -4
  56. package/dist/solution/ScanOrder/index.js +31 -20
  57. package/dist/solution/VenueBooking/index.d.ts +1 -0
  58. package/dist/solution/VenueBooking/index.js +30 -19
  59. package/dist/types/index.d.ts +1 -0
  60. package/dist/utils/payment-number.d.ts +9 -0
  61. package/dist/utils/payment-number.js +69 -0
  62. package/lib/core/index.d.ts +2 -0
  63. package/lib/core/index.js +4 -0
  64. package/lib/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  65. package/lib/model/strategy/adapter/promotion/adapter.js +20 -0
  66. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  67. package/lib/model/strategy/adapter/promotion/evaluator.js +235 -0
  68. package/lib/model/strategy/adapter/promotion/examples.d.ts +86 -0
  69. package/lib/model/strategy/adapter/promotion/examples.js +91 -0
  70. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  71. package/lib/model/strategy/adapter/promotion/type.d.ts +90 -2
  72. package/lib/model/strategy/adapter/promotion/type.js +2 -0
  73. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -1
  74. package/lib/modules/OpenData/index.d.ts +2 -0
  75. package/lib/modules/OpenData/index.js +5 -0
  76. package/lib/modules/Order/index.d.ts +33 -13
  77. package/lib/modules/Order/index.js +306 -79
  78. package/lib/modules/Order/payment-utils.d.ts +26 -0
  79. package/lib/modules/Order/payment-utils.js +224 -0
  80. package/lib/modules/Order/types.d.ts +56 -4
  81. package/lib/modules/Order/utils/orderCollectionIdentity.js +3 -0
  82. package/lib/modules/Order/utils.js +11 -4
  83. package/lib/modules/Payment/index.d.ts +2 -0
  84. package/lib/modules/Payment/index.js +33 -12
  85. package/lib/modules/Payment/types.d.ts +104 -25
  86. package/lib/modules/Payment/types.js +1 -0
  87. package/lib/modules/Payment/walletpass.d.ts +38 -1
  88. package/lib/modules/Payment/walletpass.js +730 -21
  89. package/lib/modules/Rules/index.d.ts +3 -0
  90. package/lib/modules/Rules/index.js +54 -21
  91. package/lib/modules/SalesSummary/utils.js +5 -1
  92. package/lib/server/index.d.ts +16 -0
  93. package/lib/server/index.js +670 -18
  94. package/lib/server/modules/index.d.ts +1 -1
  95. package/lib/server/modules/order/index.d.ts +70 -4
  96. package/lib/server/modules/order/index.js +818 -69
  97. package/lib/server/modules/order/types.d.ts +25 -3
  98. package/lib/server/modules/order/types.js +1 -0
  99. package/lib/solution/BaseSales/index.d.ts +118 -9
  100. package/lib/solution/BaseSales/index.js +902 -38
  101. package/lib/solution/BaseSales/types.d.ts +55 -1
  102. package/lib/solution/BaseSales/types.js +2 -1
  103. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  104. package/lib/solution/BaseSales/utils/cartPromotion.js +63 -12
  105. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  106. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  107. package/lib/solution/BookingTicket/index.d.ts +8 -16
  108. package/lib/solution/BookingTicket/index.js +63 -9
  109. package/lib/solution/BookingTicket/types.d.ts +4 -0
  110. package/lib/solution/BookingTicket/utils/cartView.js +43 -30
  111. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  112. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +37 -5
  113. package/lib/solution/Sales/index.d.ts +2 -0
  114. package/lib/solution/Sales/index.js +20 -6
  115. package/lib/solution/ScanOrder/index.js +8 -0
  116. package/lib/solution/VenueBooking/index.d.ts +1 -0
  117. package/lib/solution/VenueBooking/index.js +8 -0
  118. package/lib/types/index.d.ts +1 -0
  119. package/lib/utils/payment-number.d.ts +9 -0
  120. package/lib/utils/payment-number.js +64 -0
  121. package/package.json +1 -1
@@ -0,0 +1,26 @@
1
+ export type OrderPaymentTransactionStatus = 'success' | 'fail';
2
+ export interface OrderPaymentTransaction {
3
+ number: string;
4
+ status: OrderPaymentTransactionStatus;
5
+ }
6
+ export type OrderPaymentIdentityType = 'order_payment_id' | 'payment_number' | 'unique_payment_number';
7
+ export interface OrderPaymentIdentityMatch<T> {
8
+ index: number;
9
+ payment: T;
10
+ matchedBy: OrderPaymentIdentityType;
11
+ }
12
+ export declare function getOrderPaymentIdentityKeys(payment: unknown): string[];
13
+ export declare function isPendingOrderPayment(payment: unknown): boolean;
14
+ export declare function isIdentifiedPendingOrderPayment(payment: unknown): boolean;
15
+ export declare function hasOrderPaymentIdentityOverlap(left: unknown, right: unknown): boolean;
16
+ export declare function resolveOrderPaymentIdentity<T extends Record<string, any>>(payments: T[] | null | undefined, identity: string | number, mode?: 'payment_number' | 'compat'): OrderPaymentIdentityMatch<T> | null;
17
+ export declare function ensureOrderPaymentNumber<T extends Record<string, any>>(payment: T, devicePrefix: string, createPaymentNumber: () => string): T & {
18
+ payment_number: string;
19
+ };
20
+ export declare function mergeOrderPaymentTransactions(current: unknown, incoming: unknown): OrderPaymentTransaction[];
21
+ export declare function mergeOrderPaymentRecord<T extends Record<string, any>>(payment: T, updates: Record<string, any>): T;
22
+ export declare function mergeOrderPaymentSnapshot<T extends Record<string, any>>(current: T, incoming: T): T;
23
+ export declare function mergeOrderPaymentListsByIdentity<T extends Record<string, any>>(existing: T[] | null | undefined, incoming: T[] | null | undefined, options?: {
24
+ preserveUnmatchedExisting?: boolean;
25
+ preserveUnmatchedExistingWhen?: (payment: T) => boolean;
26
+ }): T[];
@@ -0,0 +1,224 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/modules/Order/payment-utils.ts
20
+ var payment_utils_exports = {};
21
+ __export(payment_utils_exports, {
22
+ ensureOrderPaymentNumber: () => ensureOrderPaymentNumber,
23
+ getOrderPaymentIdentityKeys: () => getOrderPaymentIdentityKeys,
24
+ hasOrderPaymentIdentityOverlap: () => hasOrderPaymentIdentityOverlap,
25
+ isIdentifiedPendingOrderPayment: () => isIdentifiedPendingOrderPayment,
26
+ isPendingOrderPayment: () => isPendingOrderPayment,
27
+ mergeOrderPaymentListsByIdentity: () => mergeOrderPaymentListsByIdentity,
28
+ mergeOrderPaymentRecord: () => mergeOrderPaymentRecord,
29
+ mergeOrderPaymentSnapshot: () => mergeOrderPaymentSnapshot,
30
+ mergeOrderPaymentTransactions: () => mergeOrderPaymentTransactions,
31
+ resolveOrderPaymentIdentity: () => resolveOrderPaymentIdentity
32
+ });
33
+ module.exports = __toCommonJS(payment_utils_exports);
34
+ var PAYMENT_IDENTITY_TYPES = [
35
+ "payment_number",
36
+ "order_payment_id",
37
+ "unique_payment_number"
38
+ ];
39
+ function normalizePaymentIdentityValue(value) {
40
+ if (value === void 0 || value === null || value === "")
41
+ return null;
42
+ return String(value);
43
+ }
44
+ function getPaymentIdentityValue(payment, type) {
45
+ var _a;
46
+ if (type === "unique_payment_number") {
47
+ return (_a = payment == null ? void 0 : payment.metadata) == null ? void 0 : _a.unique_payment_number;
48
+ }
49
+ return payment == null ? void 0 : payment[type];
50
+ }
51
+ function getOrderPaymentIdentityKeys(payment) {
52
+ const record = payment;
53
+ if (!record)
54
+ return [];
55
+ return PAYMENT_IDENTITY_TYPES.flatMap((type) => {
56
+ const value = normalizePaymentIdentityValue(getPaymentIdentityValue(record, type));
57
+ return value === null ? [] : [`${type}:${value}`];
58
+ });
59
+ }
60
+ function isPendingOrderPayment(payment) {
61
+ const record = payment;
62
+ return String((record == null ? void 0 : record.status) || "").toLowerCase() === "payment_pending";
63
+ }
64
+ function isIdentifiedPendingOrderPayment(payment) {
65
+ return isPendingOrderPayment(payment) && getOrderPaymentIdentityKeys(payment).length > 0;
66
+ }
67
+ function hasOrderPaymentIdentityOverlap(left, right) {
68
+ const leftKeys = new Set(getOrderPaymentIdentityKeys(left));
69
+ if (leftKeys.size === 0)
70
+ return false;
71
+ return getOrderPaymentIdentityKeys(right).some((key) => leftKeys.has(key));
72
+ }
73
+ function resolveOrderPaymentIdentity(payments, identity, mode = "payment_number") {
74
+ const target = String(identity);
75
+ const identityTypes = mode === "payment_number" ? ["payment_number"] : PAYMENT_IDENTITY_TYPES;
76
+ const matchesByIndex = /* @__PURE__ */ new Map();
77
+ for (const type of identityTypes) {
78
+ (payments || []).forEach((payment, index) => {
79
+ const value = normalizePaymentIdentityValue(getPaymentIdentityValue(payment, type));
80
+ if (value === target && !matchesByIndex.has(index)) {
81
+ matchesByIndex.set(index, { index, payment, matchedBy: type });
82
+ }
83
+ });
84
+ }
85
+ const matches = [...matchesByIndex.values()];
86
+ if (matches.length > 1) {
87
+ throw new Error(`支付项身份存在歧义: ${target}`);
88
+ }
89
+ return matches[0] || null;
90
+ }
91
+ function ensureOrderPaymentNumber(payment, devicePrefix, createPaymentNumber) {
92
+ const existing = normalizePaymentIdentityValue(payment.payment_number);
93
+ if (existing)
94
+ return { ...payment, payment_number: existing };
95
+ const uuid = normalizePaymentIdentityValue(payment.uuid) || createPaymentNumber();
96
+ const prefix = normalizePaymentIdentityValue(devicePrefix) || "LOCAL";
97
+ return { ...payment, payment_number: `${prefix}_${uuid}` };
98
+ }
99
+ function mergeOrderPaymentTransactions(current, incoming) {
100
+ const records = /* @__PURE__ */ new Map();
101
+ const append = (value) => {
102
+ if (!Array.isArray(value))
103
+ return;
104
+ value.forEach((item) => {
105
+ const number = item && typeof item === "object" ? String(item.number || "") : "";
106
+ const status = item && typeof item === "object" ? item.status : void 0;
107
+ if (!number || status !== "success" && status !== "fail")
108
+ return;
109
+ const previous = records.get(number);
110
+ if ((previous == null ? void 0 : previous.status) === "success" && status === "fail")
111
+ return;
112
+ records.set(number, { number, status });
113
+ });
114
+ };
115
+ append(current);
116
+ append(incoming);
117
+ return [...records.values()];
118
+ }
119
+ function mergeOrderPaymentRecord(payment, updates) {
120
+ const currentMetadata = payment.metadata || {};
121
+ const incomingMetadata = updates.metadata || {};
122
+ const transactions = mergeOrderPaymentTransactions(
123
+ currentMetadata.transactions,
124
+ incomingMetadata.transactions
125
+ );
126
+ const currentPaid = payment.status === "paid";
127
+ const nextStatus = currentPaid && updates.status !== "paid" ? "paid" : updates.status ?? payment.status;
128
+ return {
129
+ ...payment,
130
+ ...updates,
131
+ status: nextStatus,
132
+ updated_at: updates.updated_at ?? payment.updated_at,
133
+ metadata: {
134
+ ...currentMetadata,
135
+ ...incomingMetadata,
136
+ ...transactions.length > 0 || Array.isArray(incomingMetadata.transactions) ? { transactions } : {}
137
+ }
138
+ };
139
+ }
140
+ function mergeOrderPaymentSnapshot(current, incoming) {
141
+ const currentMetadata = current.metadata || {};
142
+ const incomingMetadata = incoming.metadata || {};
143
+ const currentUniquePaymentNumber = normalizePaymentIdentityValue(
144
+ currentMetadata.unique_payment_number
145
+ );
146
+ const incomingUniquePaymentNumber = normalizePaymentIdentityValue(
147
+ incomingMetadata.unique_payment_number
148
+ );
149
+ const incomingOrderPaymentId = normalizePaymentIdentityValue(
150
+ incoming.order_payment_id
151
+ );
152
+ const incomingFallbackPrefix = incomingOrderPaymentId ? `os-fallback:payment:order-payment:${incomingOrderPaymentId}` : null;
153
+ const incomingUsesDerivedUniquePaymentNumber = Boolean(
154
+ incomingUniquePaymentNumber && incomingFallbackPrefix && (incomingUniquePaymentNumber === incomingFallbackPrefix || incomingUniquePaymentNumber.startsWith(`${incomingFallbackPrefix}:conflict:`))
155
+ );
156
+ const transactions = mergeOrderPaymentTransactions(
157
+ currentMetadata.transactions,
158
+ incomingMetadata.transactions
159
+ );
160
+ return {
161
+ ...current,
162
+ ...incoming,
163
+ order_payment_id: normalizePaymentIdentityValue(incoming.order_payment_id) !== null ? incoming.order_payment_id : current.order_payment_id,
164
+ payment_number: incoming.payment_number || current.payment_number,
165
+ metadata: {
166
+ ...currentMetadata,
167
+ ...incomingMetadata,
168
+ ...incomingUsesDerivedUniquePaymentNumber && currentUniquePaymentNumber ? { unique_payment_number: currentUniquePaymentNumber } : {},
169
+ ...transactions.length > 0 ? { transactions } : {}
170
+ }
171
+ };
172
+ }
173
+ function compactOrderPaymentList(payments) {
174
+ const result = [];
175
+ for (const payment of payments) {
176
+ const matchingIndexes = result.flatMap((existing, index) => hasOrderPaymentIdentityOverlap(existing, payment) ? [index] : []);
177
+ if (matchingIndexes.length === 0) {
178
+ result.push(mergeOrderPaymentSnapshot({}, payment));
179
+ continue;
180
+ }
181
+ const firstIndex = matchingIndexes[0];
182
+ let merged = result[firstIndex];
183
+ for (const index of matchingIndexes.slice(1)) {
184
+ merged = mergeOrderPaymentSnapshot(merged, result[index]);
185
+ }
186
+ result[firstIndex] = mergeOrderPaymentSnapshot(merged, payment);
187
+ for (const index of matchingIndexes.slice(1).sort((a, b) => b - a)) {
188
+ result.splice(index, 1);
189
+ }
190
+ }
191
+ return result;
192
+ }
193
+ function mergeOrderPaymentListsByIdentity(existing, incoming, options = {}) {
194
+ const existingList = compactOrderPaymentList([...existing || []]);
195
+ const incomingList = compactOrderPaymentList([...incoming || []]);
196
+ if (options.preserveUnmatchedExisting) {
197
+ return compactOrderPaymentList([...existingList, ...incomingList]);
198
+ }
199
+ const mergedIncoming = incomingList.map((incomingPayment) => {
200
+ const matchingExisting = existingList.filter((existingPayment) => hasOrderPaymentIdentityOverlap(existingPayment, incomingPayment));
201
+ return matchingExisting.reduce(
202
+ (merged, existingPayment) => mergeOrderPaymentSnapshot(existingPayment, merged),
203
+ incomingPayment
204
+ );
205
+ });
206
+ const preservedExisting = options.preserveUnmatchedExistingWhen ? existingList.filter((existingPayment) => {
207
+ var _a;
208
+ return !incomingList.some((incomingPayment) => hasOrderPaymentIdentityOverlap(existingPayment, incomingPayment)) && ((_a = options.preserveUnmatchedExistingWhen) == null ? void 0 : _a.call(options, existingPayment));
209
+ }) : [];
210
+ return compactOrderPaymentList([...mergedIncoming, ...preservedExisting]);
211
+ }
212
+ // Annotate the CommonJS export names for ESM import in node:
213
+ 0 && (module.exports = {
214
+ ensureOrderPaymentNumber,
215
+ getOrderPaymentIdentityKeys,
216
+ hasOrderPaymentIdentityOverlap,
217
+ isIdentifiedPendingOrderPayment,
218
+ isPendingOrderPayment,
219
+ mergeOrderPaymentListsByIdentity,
220
+ mergeOrderPaymentRecord,
221
+ mergeOrderPaymentSnapshot,
222
+ mergeOrderPaymentTransactions,
223
+ resolveOrderPaymentIdentity
224
+ });
@@ -165,6 +165,8 @@ export interface OrderCustomerChangePayload {
165
165
  }
166
166
  export interface OrderScanCodeResult {
167
167
  isAvailable: boolean;
168
+ /** 卡券已加入当前订单折扣列表,但不一定能立即应用。 */
169
+ isAccepted?: boolean;
168
170
  discountList: Discount[];
169
171
  scannedDiscountList: Discount[];
170
172
  type: 'server' | 'clientCalc';
@@ -319,6 +321,24 @@ export interface ReplaceTempOrderOptions {
319
321
  saveDraft?: boolean;
320
322
  }
321
323
  export type AddProductBookingInput = Record<string, any>;
324
+ /**
325
+ * 添加商品行时的顺序控制。
326
+ * 默认追加到 products 尾部;预约数量同步可插入到既有预约组的最新行之后,
327
+ * 避免步进器修改数量改变该组展示位置。
328
+ */
329
+ export interface AddProductToOrderOptions {
330
+ insertAfterProductUid?: string;
331
+ }
332
+ /**
333
+ * 删除商品后的可选位置保持策略。
334
+ * 预约合并行减量时仍删除最新真实行,再把剩余代表行移动到被删除代表行原位置。
335
+ */
336
+ export interface RemoveProductsFromOrderOptions {
337
+ preserveDisplayPosition?: {
338
+ remainingProductUid: string;
339
+ anchorProductUid: string;
340
+ };
341
+ }
322
342
  /** 更新购物车行:仅传 SKU 时命中同 SKU 第一行;多行同 SKU 须传 unique_identification_number / 选项指纹等 */
323
343
  export interface UpdateOrderProductParams {
324
344
  product_id: number | null;
@@ -468,6 +488,8 @@ export interface SubmitSalesOrderParams {
468
488
  export interface PaymentItemData {
469
489
  /** 当前支付项的唯一 ID */
470
490
  uuid: string;
491
+ /** 支付项稳定唯一号 */
492
+ payment_number?: string;
471
493
  /** 当前支付方式付出去多少钱 */
472
494
  amount: string;
473
495
  /** 支付类型代码 */
@@ -490,13 +512,22 @@ export interface PaymentItemData {
490
512
  export interface OrderPaymentMetadata {
491
513
  rounding_rule?: Record<string, any>;
492
514
  unique_payment_number?: string;
515
+ /** 刷卡机设备快照;OS 不解析内部字段,仅透传并持久化 */
516
+ card_reader_snapshot?: Record<string, unknown>;
493
517
  shop_wallet_pass_id?: number | string;
494
518
  actual_paid_amount?: number | string;
495
519
  change_given_amount?: number | string;
520
+ transactions?: OrderPaymentTransaction[];
496
521
  [key: string]: any;
497
522
  }
523
+ export interface OrderPaymentTransaction {
524
+ number: string;
525
+ status: 'success' | 'fail';
526
+ }
498
527
  export interface OrderPaymentData {
499
528
  order_payment_id?: number | string;
529
+ /** 支付项稳定唯一号;历史支付项允许缺失 */
530
+ payment_number?: string;
500
531
  amount: string;
501
532
  code: string;
502
533
  custom_payment_id: number;
@@ -523,6 +554,15 @@ export interface OrderPaymentData {
523
554
  created_at?: string;
524
555
  updated_at?: string;
525
556
  }
557
+ export interface OrderPaymentUpdateOptions {
558
+ matchBy?: 'payment_number' | 'compat' | 'legacy';
559
+ }
560
+ export interface OrderPaymentUpdateResult {
561
+ updated: boolean;
562
+ payment: OrderPaymentData | null;
563
+ payments: OrderPaymentData[];
564
+ summary: OrderSummary | null;
565
+ }
526
566
  export type OrderPaymentSource = PaymentItem | OrderPaymentData | Record<string, any>;
527
567
  export interface MapOrderPaymentsOptions {
528
568
  includeVoided?: boolean;
@@ -673,6 +713,14 @@ export interface OrderModuleAPI {
673
713
  channel?: string;
674
714
  type?: string;
675
715
  }) => OrderSubmitPayload;
716
+ saveTempOrderAsDraft: <T = any>(params?: {
717
+ cacheId?: string;
718
+ platform?: string;
719
+ businessCode?: string;
720
+ channel?: string;
721
+ type?: string;
722
+ enhancePayload?: SubmitPayloadEnhancer;
723
+ }) => Promise<T>;
676
724
  applyLocalPrintOrderNumbers: (order?: Record<string, any> | null) => Promise<OrderTempOrder>;
677
725
  getTempOrderNote: () => string;
678
726
  updateTempOrderNote: {
@@ -685,15 +733,15 @@ export interface OrderModuleAPI {
685
733
  updateTempOrderCustomer: (customer: UpdateTempOrderCustomerInput) => OrderSnapshot['customer'];
686
734
  updateTempOrderBuzzer: (buzzer: string) => string;
687
735
  updateTempOrderContactsInfo: (contactsInfo: Record<string, any> | null) => Record<string, any> | null;
688
- addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput) => Promise<OrderProduct[]>;
736
+ addProductToOrder: (product: Partial<OrderProduct> & OrderProductIdentity, booking?: AddProductBookingInput, options?: AddProductToOrderOptions) => Promise<OrderProduct[]>;
689
737
  updateOrderProduct: (params: UpdateOrderProductParams) => Promise<OrderProduct[]>;
690
738
  /** 批量更新购物车行,末尾仅触发一次促销重算与 summary 刷新 */
691
739
  updateOrderProducts: (paramsList: UpdateOrderProductParams[]) => Promise<OrderProduct[]>;
692
740
  updateOrderProductQuantity: (params: UpdateOrderProductQuantityParams) => Promise<OrderProduct[]>;
693
741
  updateOrderBooking: (params: UpdateOrderBookingParams) => any[];
694
- removeProductFromOrder: (identity: OrderProductIdentity) => Promise<OrderProduct[]>;
742
+ removeProductFromOrder: (identity: OrderProductIdentity, options?: RemoveProductsFromOrderOptions) => Promise<OrderProduct[]>;
695
743
  /** 批量删除购物车行,末尾仅触发一次促销重算与 summary 刷新 */
696
- removeProductsFromOrder: (identities: OrderProductIdentity[]) => Promise<OrderProduct[]>;
744
+ removeProductsFromOrder: (identities: OrderProductIdentity[], options?: RemoveProductsFromOrderOptions) => Promise<OrderProduct[]>;
697
745
  /** @deprecated no-op;OrderModule 不再负责 tempOrder localStorage 持久化。 */
698
746
  persistTempOrder: () => void;
699
747
  /**
@@ -730,11 +778,15 @@ export interface OrderModuleAPI {
730
778
  getOrderPayments: () => OrderPaymentData[];
731
779
  setOrderPayments: (payments: OrderPaymentSource[]) => OrderPaymentData[];
732
780
  addOrderPayment: (payment: OrderPaymentSource) => OrderPaymentData[];
733
- updateOrderPayment: (paymentIdentity: string | number, updates: Partial<OrderPaymentData> & Record<string, any>) => OrderPaymentData[];
781
+ addOrderPaymentAsync: (payment: OrderPaymentSource) => Promise<OrderPaymentData[]>;
782
+ updateOrderPayment: (paymentIdentity: string | number, updates: Partial<OrderPaymentData> & Record<string, any>, options?: OrderPaymentUpdateOptions) => Promise<OrderPaymentUpdateResult>;
734
783
  deleteOrderPayment: (paymentIdentity: string | number) => OrderPaymentData[];
735
784
  updateVoucherOrderPayments: (payments: OrderPaymentSource[], options?: {
736
785
  status?: 'paid' | 'payment_pending';
737
786
  }) => OrderPaymentData[];
787
+ updateVoucherOrderPaymentsAsync: (payments: OrderPaymentSource[], options?: {
788
+ status?: 'paid' | 'payment_pending';
789
+ }) => Promise<OrderPaymentData[]>;
738
790
  confirmPendingVoucherPayments: (options?: {
739
791
  persist?: boolean;
740
792
  recalculateSummary?: boolean;
@@ -220,6 +220,9 @@ function normalizeOrderCollection(kind, items, options) {
220
220
  const persistentId = getOrderCollectionPersistentId(kind, item);
221
221
  let uid = getOrderCollectionUid(kind, item);
222
222
  if (!uid) {
223
+ if (kind === "payment" && !isBlankOrderCollectionIdentity(item == null ? void 0 : item.payment_number)) {
224
+ continue;
225
+ }
223
226
  uid = persistentId ? buildOrderCollectionFallbackUid(kind, persistentId) : allocateAnonymousUid(occupiedUids, createAnonymousUid);
224
227
  item = setOrderCollectionUid(kind, item, uid);
225
228
  result[index] = item;
@@ -444,7 +444,12 @@ function resolveEffectivePerUnitDiscount(product) {
444
444
  (sum, discount) => sum + Number((discount == null ? void 0 : discount.amount) || 0),
445
445
  0
446
446
  );
447
- const hasPromoDiscountItem = discountList.some((item) => (item == null ? void 0 : item.type) === "promotion");
447
+ const hasPromoDiscountItem = discountList.some(
448
+ (item) => {
449
+ var _a, _b;
450
+ return (item == null ? void 0 : item.type) === "promotion" || (item == null ? void 0 : item.type) === "product" && ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.source) === "promotion" && ((_b = item == null ? void 0 : item.metadata) == null ? void 0 : _b.actionType) === "ITEM_REWARD";
451
+ }
452
+ );
448
453
  if (hasPromoDiscountItem)
449
454
  return fromList;
450
455
  const metadata = (product == null ? void 0 : product.metadata) || {};
@@ -965,6 +970,9 @@ function buildSubmitPayload(params) {
965
970
  ...tempOrderRest,
966
971
  customer_id: tempOrder.customer_id ?? 1,
967
972
  customer_name: tempOrder.customer_name || "Walk-In",
973
+ country_calling_code: String(tempOrder.country_calling_code ?? ""),
974
+ phone: String(tempOrder.phone ?? ""),
975
+ email: String(tempOrder.email ?? ""),
968
976
  order_number: tempOrder.order_number ?? null,
969
977
  shop_order_number: tempOrder.shop_order_number ?? null,
970
978
  shop_full_order_number: tempOrder.shop_full_order_number ?? null,
@@ -1020,9 +1028,7 @@ function mapPaymentItemToOrderPayment(paymentItem) {
1020
1028
  const item = paymentItem;
1021
1029
  const customPaymentId = item.custom_payment_id ?? item.id;
1022
1030
  const metadata = item.metadata && typeof item.metadata === "object" ? { ...item.metadata } : {};
1023
- if (item.uuid && !metadata.unique_payment_number) {
1024
- metadata.unique_payment_number = String(item.uuid);
1025
- }
1031
+ const paymentNumber = item.payment_number;
1026
1032
  const paymentMetadataKeys = [
1027
1033
  "rounding_rule",
1028
1034
  "shop_wallet_pass_id",
@@ -1039,6 +1045,7 @@ function mapPaymentItemToOrderPayment(paymentItem) {
1039
1045
  const createdAt = item.created_at ?? timestamp;
1040
1046
  return {
1041
1047
  ...item.order_payment_id !== void 0 ? { order_payment_id: item.order_payment_id } : {},
1048
+ ...paymentNumber !== void 0 && paymentNumber !== null && paymentNumber !== "" ? { payment_number: String(paymentNumber) } : {},
1042
1049
  amount: String(item.amount ?? "0.00"),
1043
1050
  code: String(item.code || ""),
1044
1051
  custom_payment_id: Number(customPaymentId ?? 0),
@@ -20,6 +20,7 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
20
20
  protected defaultVersion: string;
21
21
  request: RequestPlugin;
22
22
  private app;
23
+ private appPlugin;
23
24
  private store;
24
25
  window: WindowPlugin;
25
26
  private dbManager;
@@ -40,6 +41,7 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
40
41
  * paymentModule.updateOtherParams({ fatherModule: 'bookingTicket' });
41
42
  */
42
43
  updateOtherParams(params: Record<string, any>): void;
44
+ private getPaymentNumberAppData;
43
45
  /**
44
46
  * 记录信息日志
45
47
  */
@@ -31,6 +31,9 @@ var import_cash = require("./cash");
31
31
  var import_eftpos = require("./eftpos");
32
32
  var import_walletpass = require("./walletpass");
33
33
  var import_decimal = require("decimal.js");
34
+ var import_payment_utils = require("../Order/payment-utils");
35
+ var import_utils2 = require("../Order/utils");
36
+ var import_payment_number = require("../../utils/payment-number");
34
37
  __reExport(Payment_exports, require("./types"), module.exports);
35
38
  function formatAmount(amount) {
36
39
  try {
@@ -112,15 +115,15 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
112
115
  this.store = options.store;
113
116
  this.otherParams = options.otherParams || {};
114
117
  this.request = core.getPlugin("request");
115
- const appPlugin = core.getPlugin("app");
118
+ this.appPlugin = core.getPlugin("app");
116
119
  this.window = core.getPlugin("window");
117
120
  if (!this.request) {
118
121
  throw new Error("支付模块需要 request 插件支持");
119
122
  }
120
- if (!appPlugin) {
123
+ if (!this.appPlugin) {
121
124
  throw new Error("支付模块需要 app 插件支持");
122
125
  }
123
- this.app = appPlugin.getApp();
126
+ this.app = this.appPlugin.getApp();
124
127
  this.dbManager = this.app.dbManager;
125
128
  this.logger = this.app.logger;
126
129
  this.registerNetworkHandlers();
@@ -136,6 +139,14 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
136
139
  updateOtherParams(params) {
137
140
  this.otherParams = params || {};
138
141
  }
142
+ getPaymentNumberAppData(key) {
143
+ var _a, _b, _c, _d, _e, _f, _g;
144
+ const getData = (_b = (_a = this.appPlugin) == null ? void 0 : _a.getData) == null ? void 0 : _b.call(_a);
145
+ if (typeof getData === "function")
146
+ return getData(key);
147
+ const coreData = (_g = (_e = (_d = (_c = this.app) == null ? void 0 : _c.models) == null ? void 0 : _d.getStore) == null ? void 0 : (_f = _e.call(_d)).getDataByModel) == null ? void 0 : _g.call(_f, "core", "core");
148
+ return coreData == null ? void 0 : coreData[key];
149
+ }
139
150
  /**
140
151
  * 记录信息日志
141
152
  */
@@ -521,15 +532,20 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
521
532
  });
522
533
  throw new Error(warningMessage);
523
534
  }
524
- let paymentUuid;
525
- if ((_a = paymentItem.metadata) == null ? void 0 : _a.unique_payment_number) {
526
- paymentUuid = paymentItem.metadata.unique_payment_number;
527
- } else {
528
- paymentUuid = (0, import_utils.getUniqueId)("payment_");
529
- }
535
+ const paymentUuid = paymentItem.uuid || ((_a = paymentItem.metadata) == null ? void 0 : _a.unique_payment_number) || (0, import_utils.getUniqueId)("payment_");
530
536
  const currentTime = formatDateTime(/* @__PURE__ */ new Date());
537
+ const hasPaymentNumber = String(paymentItem.payment_number || "").trim() !== "";
538
+ const paymentNumberDevicePrefix = hasPaymentNumber ? "LOCAL" : await (0, import_payment_number.resolvePaymentNumberDevicePrefix)(
539
+ (key) => this.getPaymentNumberAppData(key)
540
+ );
541
+ const paymentNumber = (0, import_payment_utils.ensureOrderPaymentNumber)(
542
+ paymentItem,
543
+ paymentNumberDevicePrefix,
544
+ import_utils2.createUuidV4
545
+ ).payment_number;
531
546
  const newPaymentItem = {
532
547
  uuid: paymentUuid,
548
+ payment_number: paymentNumber,
533
549
  custom_payment_id: normalizeCustomPaymentId(paymentItem),
534
550
  name: paymentItem.name,
535
551
  code: paymentItem.code,
@@ -549,10 +565,8 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
549
565
  updated_at: currentTime,
550
566
  // 更新时间
551
567
  metadata: {
552
- ...paymentItem.metadata,
568
+ ...paymentItem.metadata
553
569
  // 保留传入的所有 metadata 字段
554
- unique_payment_number: paymentUuid
555
- // 设置唯一支付号为支付项的 uuid
556
570
  }
557
571
  };
558
572
  order.payment.push(newPaymentItem);
@@ -767,6 +781,12 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
767
781
  if ("amount" in formattedParams && formattedParams.amount !== void 0) {
768
782
  formattedParams.amount = formatAmount(formattedParams.amount);
769
783
  }
784
+ if (formattedParams.metadata && typeof formattedParams.metadata === "object") {
785
+ formattedParams.metadata = {
786
+ ...paymentItem.metadata || {},
787
+ ...formattedParams.metadata
788
+ };
789
+ }
770
790
  Object.assign(paymentItem, formattedParams);
771
791
  this.recalculateOrderAmount(order);
772
792
  await this.dbManager.update("order", order);
@@ -824,6 +844,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
824
844
  const paymentData = {
825
845
  payments: order.payment.map((payment) => ({
826
846
  uuid: payment.uuid,
847
+ payment_number: payment.payment_number,
827
848
  amount: payment.amount,
828
849
  code: payment.code,
829
850
  custom_payment_id: payment.custom_payment_id,