@pisell/pisellos 0.10.2 → 0.10.4

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 (139) 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 +0 -9
  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/BaseModule.d.ts +1 -0
  14. package/dist/modules/BaseModule.js +24 -28
  15. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -3
  16. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +6 -3
  17. package/dist/modules/OpenData/index.d.ts +2 -0
  18. package/dist/modules/OpenData/index.js +8 -0
  19. package/dist/modules/Order/index.d.ts +41 -10
  20. package/dist/modules/Order/index.js +943 -546
  21. package/dist/modules/Order/payment-utils.d.ts +26 -0
  22. package/dist/modules/Order/payment-utils.js +225 -0
  23. package/dist/modules/Order/types.d.ts +43 -2
  24. package/dist/modules/Order/utils/orderCollectionIdentity.js +7 -2
  25. package/dist/modules/Order/utils.js +10 -6
  26. package/dist/modules/Payment/index.d.ts +2 -0
  27. package/dist/modules/Payment/index.js +79 -50
  28. package/dist/modules/Payment/types.d.ts +107 -28
  29. package/dist/modules/Payment/types.js +20 -3
  30. package/dist/modules/Payment/walletpass.d.ts +38 -1
  31. package/dist/modules/Payment/walletpass.js +917 -114
  32. package/dist/modules/ProductList/index.js +1 -1
  33. package/dist/modules/Rules/index.d.ts +3 -0
  34. package/dist/modules/Rules/index.js +130 -99
  35. package/dist/server/index.d.ts +16 -0
  36. package/dist/server/index.js +2084 -1188
  37. package/dist/server/modules/index.d.ts +1 -1
  38. package/dist/server/modules/order/index.d.ts +70 -4
  39. package/dist/server/modules/order/index.js +1816 -728
  40. package/dist/server/modules/order/types.d.ts +25 -3
  41. package/dist/server/modules/order/types.js +7 -1
  42. package/dist/solution/BaseSales/index.d.ts +114 -14
  43. package/dist/solution/BaseSales/index.js +1848 -478
  44. package/dist/solution/BaseSales/types.d.ts +55 -1
  45. package/dist/solution/BaseSales/types.js +2 -1
  46. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  47. package/dist/solution/BaseSales/utils/cartPromotion.js +90 -31
  48. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  49. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  50. package/dist/solution/BookingByStep/index.d.ts +1 -1
  51. package/dist/solution/BookingTicket/index.d.ts +8 -16
  52. package/dist/solution/BookingTicket/index.js +138 -52
  53. package/dist/solution/BookingTicket/types.d.ts +1 -0
  54. package/dist/solution/BookingTicket/utils/addProductDecision.js +6 -0
  55. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  56. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +173 -83
  57. package/dist/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  58. package/dist/solution/BookingTicket/utils/weighingProductSku.js +45 -0
  59. package/dist/solution/Sales/index.d.ts +1 -0
  60. package/dist/solution/Sales/index.js +10 -2
  61. package/dist/solution/ScanOrder/index.js +31 -20
  62. package/dist/solution/UnifiedBookingSales/index.d.ts +3 -0
  63. package/dist/solution/UnifiedBookingSales/index.js +392 -304
  64. package/dist/solution/UnifiedBookingSales/types.d.ts +7 -0
  65. package/dist/solution/VenueBooking/index.d.ts +1 -0
  66. package/dist/solution/VenueBooking/index.js +34 -24
  67. package/dist/types/index.d.ts +1 -0
  68. package/dist/utils/payment-number.d.ts +9 -0
  69. package/dist/utils/payment-number.js +69 -0
  70. package/lib/core/index.d.ts +2 -0
  71. package/lib/core/index.js +4 -0
  72. package/lib/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  73. package/lib/model/strategy/adapter/promotion/adapter.js +20 -0
  74. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  75. package/lib/model/strategy/adapter/promotion/evaluator.js +235 -0
  76. package/lib/model/strategy/adapter/promotion/examples.d.ts +86 -0
  77. package/lib/model/strategy/adapter/promotion/examples.js +91 -0
  78. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  79. package/lib/model/strategy/adapter/promotion/index.js +2 -0
  80. package/lib/model/strategy/adapter/promotion/type.d.ts +90 -2
  81. package/lib/model/strategy/adapter/promotion/type.js +2 -0
  82. package/lib/modules/BaseModule.d.ts +1 -0
  83. package/lib/modules/BaseModule.js +24 -37
  84. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +2 -1
  85. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  86. package/lib/modules/OpenData/index.d.ts +2 -0
  87. package/lib/modules/OpenData/index.js +5 -0
  88. package/lib/modules/Order/index.d.ts +41 -10
  89. package/lib/modules/Order/index.js +322 -86
  90. package/lib/modules/Order/payment-utils.d.ts +26 -0
  91. package/lib/modules/Order/payment-utils.js +224 -0
  92. package/lib/modules/Order/types.d.ts +43 -2
  93. package/lib/modules/Order/utils/orderCollectionIdentity.js +3 -0
  94. package/lib/modules/Order/utils.js +11 -4
  95. package/lib/modules/Payment/index.d.ts +2 -0
  96. package/lib/modules/Payment/index.js +34 -13
  97. package/lib/modules/Payment/types.d.ts +107 -28
  98. package/lib/modules/Payment/types.js +4 -3
  99. package/lib/modules/Payment/walletpass.d.ts +38 -1
  100. package/lib/modules/Payment/walletpass.js +730 -21
  101. package/lib/modules/ProductList/index.js +9 -1
  102. package/lib/modules/Rules/index.d.ts +3 -0
  103. package/lib/modules/Rules/index.js +39 -10
  104. package/lib/server/index.d.ts +16 -0
  105. package/lib/server/index.js +677 -28
  106. package/lib/server/modules/index.d.ts +1 -1
  107. package/lib/server/modules/order/index.d.ts +70 -4
  108. package/lib/server/modules/order/index.js +818 -69
  109. package/lib/server/modules/order/types.d.ts +25 -3
  110. package/lib/server/modules/order/types.js +1 -0
  111. package/lib/solution/BaseSales/index.d.ts +114 -14
  112. package/lib/solution/BaseSales/index.js +907 -58
  113. package/lib/solution/BaseSales/types.d.ts +55 -1
  114. package/lib/solution/BaseSales/types.js +2 -1
  115. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  116. package/lib/solution/BaseSales/utils/cartPromotion.js +63 -12
  117. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  118. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  119. package/lib/solution/BookingByStep/index.d.ts +1 -1
  120. package/lib/solution/BookingTicket/index.d.ts +8 -16
  121. package/lib/solution/BookingTicket/index.js +63 -9
  122. package/lib/solution/BookingTicket/types.d.ts +1 -0
  123. package/lib/solution/BookingTicket/utils/addProductDecision.js +4 -0
  124. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  125. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +37 -5
  126. package/lib/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  127. package/lib/solution/BookingTicket/utils/weighingProductSku.js +63 -0
  128. package/lib/solution/Sales/index.d.ts +1 -0
  129. package/lib/solution/Sales/index.js +5 -3
  130. package/lib/solution/ScanOrder/index.js +8 -0
  131. package/lib/solution/UnifiedBookingSales/index.d.ts +3 -0
  132. package/lib/solution/UnifiedBookingSales/index.js +48 -2
  133. package/lib/solution/UnifiedBookingSales/types.d.ts +7 -0
  134. package/lib/solution/VenueBooking/index.d.ts +1 -0
  135. package/lib/solution/VenueBooking/index.js +13 -6
  136. package/lib/types/index.d.ts +1 -0
  137. package/lib/utils/payment-number.d.ts +9 -0
  138. package/lib/utils/payment-number.js +64 -0
  139. 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';
@@ -469,6 +471,8 @@ export interface SubmitSalesOrderParams {
469
471
  export interface PaymentItemData {
470
472
  /** 当前支付项的唯一 ID */
471
473
  uuid: string;
474
+ /** 支付项稳定唯一号 */
475
+ payment_number?: string;
472
476
  /** 当前支付方式付出去多少钱 */
473
477
  amount: string;
474
478
  /** 支付类型代码 */
@@ -491,13 +495,22 @@ export interface PaymentItemData {
491
495
  export interface OrderPaymentMetadata {
492
496
  rounding_rule?: Record<string, any>;
493
497
  unique_payment_number?: string;
498
+ /** 刷卡机设备快照;OS 不解析内部字段,仅透传并持久化 */
499
+ card_reader_snapshot?: Record<string, unknown>;
494
500
  shop_wallet_pass_id?: number | string;
495
501
  actual_paid_amount?: number | string;
496
502
  change_given_amount?: number | string;
503
+ transactions?: OrderPaymentTransaction[];
497
504
  [key: string]: any;
498
505
  }
506
+ export interface OrderPaymentTransaction {
507
+ number: string;
508
+ status: 'success' | 'fail';
509
+ }
499
510
  export interface OrderPaymentData {
500
511
  order_payment_id?: number | string;
512
+ /** 支付项稳定唯一号;历史支付项允许缺失 */
513
+ payment_number?: string;
501
514
  amount: string;
502
515
  code: string;
503
516
  custom_payment_id: number;
@@ -524,6 +537,15 @@ export interface OrderPaymentData {
524
537
  created_at?: string;
525
538
  updated_at?: string;
526
539
  }
540
+ export interface OrderPaymentUpdateOptions {
541
+ matchBy?: 'payment_number' | 'compat' | 'legacy';
542
+ }
543
+ export interface OrderPaymentUpdateResult {
544
+ updated: boolean;
545
+ payment: OrderPaymentData | null;
546
+ payments: OrderPaymentData[];
547
+ summary: OrderSummary | null;
548
+ }
527
549
  export type OrderPaymentSource = PaymentItem | OrderPaymentData | Record<string, any>;
528
550
  export interface MapOrderPaymentsOptions {
529
551
  includeVoided?: boolean;
@@ -539,6 +561,10 @@ export interface LoadSalesDetailParams {
539
561
  * 存在时 loadSalesDetail 会跳过远端 lookup,直接复用 hydrate 后半段逻辑。
540
562
  */
541
563
  preloadedSalesDetail?: Record<string, any>;
564
+ /**
565
+ * sessionStorage 快照复用详情 hydrate 时使用;不带该值时保持既有编辑订单语义。
566
+ */
567
+ hydrateSource?: 'sessionStorage';
542
568
  forceRemote?: boolean;
543
569
  merge?: boolean;
544
570
  }
@@ -680,6 +706,14 @@ export interface OrderModuleAPI {
680
706
  channel?: string;
681
707
  type?: string;
682
708
  }) => OrderSubmitPayload;
709
+ saveTempOrderAsDraft: <T = any>(params?: {
710
+ cacheId?: string;
711
+ platform?: string;
712
+ businessCode?: string;
713
+ channel?: string;
714
+ type?: string;
715
+ enhancePayload?: SubmitPayloadEnhancer;
716
+ }) => Promise<T>;
683
717
  applyLocalPrintOrderNumbers: (order?: Record<string, any> | null) => Promise<OrderTempOrder>;
684
718
  getTempOrderNote: () => string;
685
719
  updateTempOrderNote: {
@@ -701,8 +735,10 @@ export interface OrderModuleAPI {
701
735
  removeProductFromOrder: (identity: OrderProductIdentity) => Promise<OrderProduct[]>;
702
736
  /** 批量删除购物车行,末尾仅触发一次促销重算与 summary 刷新 */
703
737
  removeProductsFromOrder: (identities: OrderProductIdentity[]) => Promise<OrderProduct[]>;
704
- /** @deprecated no-op;OrderModule 不再负责 tempOrder localStorage 持久化。 */
738
+ /** 在显式开启时保存当前 tempOrder sessionStorage 会话快照。 */
705
739
  persistTempOrder: () => void;
740
+ /** 取出一次待恢复的 sessionStorage tempOrder 快照。 */
741
+ consumeSessionStorageRestore: () => Record<string, any> | null;
706
742
  /**
707
743
  * 控制 IndexedDB 草稿(saveDraft)开关;localStorage tempOrder 持久化已废弃。
708
744
  * BigSale 弹窗等场景传 false 可跳过 saveDraft。
@@ -739,11 +775,15 @@ export interface OrderModuleAPI {
739
775
  getOrderPayments: () => OrderPaymentData[];
740
776
  setOrderPayments: (payments: OrderPaymentSource[]) => OrderPaymentData[];
741
777
  addOrderPayment: (payment: OrderPaymentSource) => OrderPaymentData[];
742
- updateOrderPayment: (paymentIdentity: string | number, updates: Partial<OrderPaymentData> & Record<string, any>) => OrderPaymentData[];
778
+ addOrderPaymentAsync: (payment: OrderPaymentSource) => Promise<OrderPaymentData[]>;
779
+ updateOrderPayment: (paymentIdentity: string | number, updates: Partial<OrderPaymentData> & Record<string, any>, options?: OrderPaymentUpdateOptions) => Promise<OrderPaymentUpdateResult>;
743
780
  deleteOrderPayment: (paymentIdentity: string | number) => OrderPaymentData[];
744
781
  updateVoucherOrderPayments: (payments: OrderPaymentSource[], options?: {
745
782
  status?: 'paid' | 'payment_pending';
746
783
  }) => OrderPaymentData[];
784
+ updateVoucherOrderPaymentsAsync: (payments: OrderPaymentSource[], options?: {
785
+ status?: 'paid' | 'payment_pending';
786
+ }) => Promise<OrderPaymentData[]>;
747
787
  confirmPendingVoucherPayments: (options?: {
748
788
  persist?: boolean;
749
789
  recalculateSummary?: boolean;
@@ -756,6 +796,7 @@ export interface OrderModuleAPI {
756
796
  saveDraft: () => Promise<void>;
757
797
  hydrateTempOrderFromRecord: (record: Record<string, any>, options?: {
758
798
  recalcOnHydrate?: boolean;
799
+ source?: 'salesDetail' | 'sessionStorage';
759
800
  }) => Promise<OrderTempOrder>;
760
801
  syncPaymentsToOrder: <T = any>(params: SyncPaymentsToOrderParams) => Promise<SyncPaymentsToOrderResult<T>>;
761
802
  getSalesOrderByLookup: (params: SalesOrderLookupParams) => Promise<any>;
@@ -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;
@@ -446,7 +446,12 @@ function resolveEffectivePerUnitDiscount(product) {
446
446
  (sum, discount) => sum + Number((discount == null ? void 0 : discount.amount) || 0),
447
447
  0
448
448
  );
449
- const hasPromoDiscountItem = discountList.some((item) => (item == null ? void 0 : item.type) === "promotion");
449
+ const hasPromoDiscountItem = discountList.some(
450
+ (item) => {
451
+ var _a, _b;
452
+ 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";
453
+ }
454
+ );
450
455
  if (hasPromoDiscountItem)
451
456
  return fromList;
452
457
  const metadata = (product == null ? void 0 : product.metadata) || {};
@@ -995,6 +1000,9 @@ function buildSubmitPayload(params) {
995
1000
  ...tempOrderRest,
996
1001
  customer_id: tempOrder.customer_id ?? 1,
997
1002
  customer_name: tempOrder.customer_name || "Walk-In",
1003
+ country_calling_code: String(tempOrder.country_calling_code ?? ""),
1004
+ phone: String(tempOrder.phone ?? ""),
1005
+ email: String(tempOrder.email ?? ""),
998
1006
  order_number: tempOrder.order_number ?? null,
999
1007
  shop_order_number: tempOrder.shop_order_number ?? null,
1000
1008
  shop_full_order_number: tempOrder.shop_full_order_number ?? null,
@@ -1050,9 +1058,7 @@ function mapPaymentItemToOrderPayment(paymentItem) {
1050
1058
  const item = paymentItem;
1051
1059
  const customPaymentId = item.custom_payment_id ?? item.id;
1052
1060
  const metadata = item.metadata && typeof item.metadata === "object" ? { ...item.metadata } : {};
1053
- if (item.uuid && !metadata.unique_payment_number) {
1054
- metadata.unique_payment_number = String(item.uuid);
1055
- }
1061
+ const paymentNumber = item.payment_number;
1056
1062
  const paymentMetadataKeys = [
1057
1063
  "rounding_rule",
1058
1064
  "shop_wallet_pass_id",
@@ -1069,6 +1075,7 @@ function mapPaymentItemToOrderPayment(paymentItem) {
1069
1075
  const createdAt = item.created_at ?? timestamp;
1070
1076
  return {
1071
1077
  ...item.order_payment_id !== void 0 ? { order_payment_id: item.order_payment_id } : {},
1078
+ ...paymentNumber !== void 0 && paymentNumber !== null && paymentNumber !== "" ? { payment_number: String(paymentNumber) } : {},
1072
1079
  amount: String(item.amount ?? "0.00"),
1073
1080
  code: String(item.code || ""),
1074
1081
  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,
@@ -1067,7 +1088,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
1067
1088
  roundedValue = this.standardRound(baseValue, true);
1068
1089
  break;
1069
1090
  case import_types.RoundingRule.StandardDown:
1070
- case "standard_down":
1091
+ case "standard_rounding_midpoint_down":
1071
1092
  roundedValue = this.standardRound(baseValue, false);
1072
1093
  break;
1073
1094
  case import_types.RoundingRule.AlwaysUp: