@pisell/pisellos 2.2.309 → 2.2.311
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.
- package/dist/model/strategy/adapter/promotion/index.js +0 -9
- package/dist/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.js +4 -2
- package/dist/modules/BookingContext/index.js +4 -4
- package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +58 -19
- package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +24 -12
- package/dist/modules/Customer/index.js +6 -3
- package/dist/modules/Customer/types.d.ts +2 -0
- package/dist/modules/Discount/availability.d.ts +7 -0
- package/dist/modules/Discount/availability.js +49 -0
- package/dist/modules/Discount/entitlementPass.d.ts +34 -0
- package/dist/modules/Discount/entitlementPass.js +147 -0
- package/dist/modules/Discount/index.d.ts +2 -2
- package/dist/modules/Discount/index.js +37 -151
- package/dist/modules/Discount/types.d.ts +36 -5
- package/dist/modules/OpenData/index.d.ts +1 -1
- package/dist/modules/OpenData/index.js +21 -12
- package/dist/modules/Order/index.d.ts +32 -4
- package/dist/modules/Order/index.js +733 -373
- package/dist/modules/Order/types.d.ts +17 -0
- package/dist/modules/Order/utils/orderCollectionIdentity.js +16 -12
- package/dist/modules/Order/utils.d.ts +19 -5
- package/dist/modules/Order/utils.js +306 -86
- package/dist/modules/Payment/index.d.ts +0 -5
- package/dist/modules/Payment/index.js +35 -85
- package/dist/modules/Payment/types.d.ts +21 -1
- package/dist/modules/Payment/types.js +2 -0
- package/dist/modules/Payment/walletpass.d.ts +1 -1
- package/dist/modules/Payment/walletpass.js +80 -47
- package/dist/modules/ProductList/index.js +18 -5
- package/dist/modules/Rules/index.d.ts +2 -2
- package/dist/modules/Rules/index.js +480 -186
- package/dist/modules/Rules/types.d.ts +4 -0
- package/dist/server/index.js +8 -5
- package/dist/server/modules/floor-plan/index.js +34 -3
- package/dist/server/modules/order/index.js +6 -0
- package/dist/server/modules/order/types.d.ts +12 -0
- package/dist/server/modules/payment/index.d.ts +25 -6
- package/dist/server/modules/payment/index.js +660 -133
- package/dist/server/utils/small-ticket.d.ts +8 -5
- package/dist/server/utils/small-ticket.js +1269 -199
- package/dist/solution/BaseSales/index.d.ts +11 -2
- package/dist/solution/BaseSales/index.js +1463 -1173
- package/dist/solution/BaseSales/types.d.ts +7 -3
- package/dist/solution/BaseSales/utils/cartPromotion.js +141 -126
- package/dist/solution/BookingTicket/index.d.ts +11 -2
- package/dist/solution/BookingTicket/index.js +663 -542
- package/dist/solution/BookingTicket/types.d.ts +5 -1
- package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +2 -0
- package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +338 -147
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +8 -4
- package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +6 -0
- package/dist/solution/BookingTicket/utils/scan/formatGlobalScan.js +19 -6
- package/dist/solution/ShopDiscount/index.d.ts +2 -0
- package/dist/solution/ShopDiscount/index.js +99 -42
- package/dist/solution/ShopDiscount/utils.d.ts +4 -2
- package/dist/solution/ShopDiscount/utils.js +43 -23
- package/dist/solution/UnifiedBookingSales/index.d.ts +2 -2
- package/dist/solution/UnifiedBookingSales/index.js +5 -5
- package/dist/utils/os-private-payload.d.ts +5 -0
- package/dist/utils/os-private-payload.js +17 -0
- package/lib/model/strategy/adapter/walletPass/evaluator.d.ts +2 -0
- package/lib/model/strategy/adapter/walletPass/evaluator.js +2 -0
- package/lib/modules/BookingContext/index.js +3 -3
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +35 -6
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +13 -6
- package/lib/modules/Customer/index.js +5 -1
- package/lib/modules/Customer/types.d.ts +2 -0
- package/lib/modules/Discount/availability.d.ts +7 -0
- package/lib/modules/Discount/availability.js +43 -0
- package/lib/modules/Discount/entitlementPass.d.ts +34 -0
- package/lib/modules/Discount/entitlementPass.js +141 -0
- package/lib/modules/Discount/index.d.ts +2 -2
- package/lib/modules/Discount/index.js +23 -129
- package/lib/modules/Discount/types.d.ts +36 -5
- package/lib/modules/OpenData/index.d.ts +1 -1
- package/lib/modules/OpenData/index.js +11 -2
- package/lib/modules/Order/index.d.ts +32 -4
- package/lib/modules/Order/index.js +341 -71
- package/lib/modules/Order/types.d.ts +17 -0
- package/lib/modules/Order/utils/orderCollectionIdentity.js +14 -11
- package/lib/modules/Order/utils.d.ts +19 -5
- package/lib/modules/Order/utils.js +215 -13
- package/lib/modules/Payment/index.d.ts +0 -5
- package/lib/modules/Payment/index.js +3 -28
- package/lib/modules/Payment/types.d.ts +21 -1
- package/lib/modules/Payment/types.js +1 -0
- package/lib/modules/Payment/walletpass.d.ts +1 -1
- package/lib/modules/Payment/walletpass.js +29 -9
- package/lib/modules/ProductList/index.js +14 -1
- package/lib/modules/Rules/index.d.ts +2 -2
- package/lib/modules/Rules/index.js +357 -110
- package/lib/modules/Rules/types.d.ts +4 -0
- package/lib/server/index.js +8 -5
- package/lib/server/modules/floor-plan/index.js +29 -1
- package/lib/server/modules/order/index.js +6 -0
- package/lib/server/modules/order/types.d.ts +12 -0
- package/lib/server/modules/payment/index.d.ts +25 -6
- package/lib/server/modules/payment/index.js +350 -78
- package/lib/server/utils/small-ticket.d.ts +8 -5
- package/lib/server/utils/small-ticket.js +1009 -121
- package/lib/solution/BaseSales/index.d.ts +11 -2
- package/lib/solution/BaseSales/index.js +164 -30
- package/lib/solution/BaseSales/types.d.ts +7 -3
- package/lib/solution/BaseSales/utils/cartPromotion.js +12 -4
- package/lib/solution/BookingTicket/index.d.ts +11 -2
- package/lib/solution/BookingTicket/index.js +103 -41
- package/lib/solution/BookingTicket/types.d.ts +5 -1
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +2 -0
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +174 -42
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +8 -4
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.d.ts +6 -0
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +11 -3
- package/lib/solution/ShopDiscount/index.d.ts +2 -0
- package/lib/solution/ShopDiscount/index.js +55 -9
- package/lib/solution/ShopDiscount/utils.d.ts +4 -2
- package/lib/solution/ShopDiscount/utils.js +42 -25
- package/lib/solution/UnifiedBookingSales/index.d.ts +2 -2
- package/lib/solution/UnifiedBookingSales/index.js +5 -5
- package/lib/utils/os-private-payload.d.ts +5 -0
- package/lib/utils/os-private-payload.js +22 -0
- package/package.json +1 -1
|
@@ -199,12 +199,27 @@ export interface PointCardSnapshotItem {
|
|
|
199
199
|
id: number | string;
|
|
200
200
|
tag: 'point_card';
|
|
201
201
|
product_id?: number | string;
|
|
202
|
+
code?: string;
|
|
202
203
|
product_name: string;
|
|
203
204
|
par_value: string;
|
|
204
205
|
used_par_value: string;
|
|
205
206
|
}
|
|
207
|
+
export interface PointCardSnapshotMergeContext {
|
|
208
|
+
customerId?: number | string | null;
|
|
209
|
+
orderIdentity?: OrderIdentitySnapshot | null;
|
|
210
|
+
}
|
|
211
|
+
export interface VirtualCurrencySnapshotItem {
|
|
212
|
+
id: number | string;
|
|
213
|
+
tag: 'virtual_currency';
|
|
214
|
+
product_id?: number | string;
|
|
215
|
+
product_name: string;
|
|
216
|
+
par_value: string;
|
|
217
|
+
used_par_value: string;
|
|
218
|
+
name: Record<string, string>;
|
|
219
|
+
}
|
|
206
220
|
export interface OrderMetaList {
|
|
207
221
|
point_cards_snapshot?: PointCardSnapshotItem[];
|
|
222
|
+
virtual_currency_snapshot?: VirtualCurrencySnapshotItem[];
|
|
208
223
|
}
|
|
209
224
|
export interface OrderProduct extends OrderProductIdentity {
|
|
210
225
|
order_detail_id: number | null;
|
|
@@ -964,6 +979,8 @@ export interface OrderModuleAPI {
|
|
|
964
979
|
}) => Promise<Discount[]>;
|
|
965
980
|
getDiscountList: () => Discount[];
|
|
966
981
|
getAvailableWalletIds: () => number[];
|
|
982
|
+
getCustomerWalletPrepareConfigEpoch: () => number;
|
|
983
|
+
mergePointCardSnapshotCodes: (walletPassList: unknown, context?: PointCardSnapshotMergeContext) => PointCardSnapshotItem[];
|
|
967
984
|
applyDiscount: () => void;
|
|
968
985
|
/**
|
|
969
986
|
* 注入促销评估器。
|
|
@@ -17,6 +17,7 @@ exports.normalizeOrderCollections = normalizeOrderCollections;
|
|
|
17
17
|
exports.repairDuplicateProductLineIdentities = repairDuplicateProductLineIdentities;
|
|
18
18
|
exports.setOrderCollectionUid = setOrderCollectionUid;
|
|
19
19
|
var _lodashEs = require("lodash-es");
|
|
20
|
+
var _entitlementPass = require("../../Discount/entitlementPass");
|
|
20
21
|
const IDENTITY_CONFIG = {
|
|
21
22
|
product: {
|
|
22
23
|
persistentIdField: 'order_detail_id',
|
|
@@ -81,20 +82,22 @@ function setOrderCollectionUid(kind, item, uid) {
|
|
|
81
82
|
delete record[uidField];
|
|
82
83
|
return record;
|
|
83
84
|
}
|
|
84
|
-
function
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
function getFullCoveragePassIdentity(product) {
|
|
86
|
+
const pass = (product.discount_list || []).find(item => (0, _entitlementPass.isFullCoveragePass)(item));
|
|
87
|
+
if (!pass) return null;
|
|
88
|
+
const resourceId = pass.discount?.resource_id ?? pass.resource_id ?? pass.discount_id ?? pass.id;
|
|
89
|
+
if (isBlankOrderCollectionIdentity(resourceId)) return null;
|
|
90
|
+
return {
|
|
91
|
+
type: String(pass.type || pass.tag),
|
|
92
|
+
resourceId: String(resourceId)
|
|
93
|
+
};
|
|
92
94
|
}
|
|
93
95
|
function buildSplitProductUid(originalUid, product, duplicateOrdinal) {
|
|
94
96
|
const encodedOriginalUid = encodeURIComponent(originalUid);
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
97
|
-
|
|
97
|
+
const passIdentity = getFullCoveragePassIdentity(product);
|
|
98
|
+
if (passIdentity) {
|
|
99
|
+
const passType = passIdentity.type === 'good_pass' ? 'good-pass' : 'entitlement-pass';
|
|
100
|
+
return `os-split:product:${encodedOriginalUid}:${passType}:${encodeURIComponent(passIdentity.resourceId)}:${duplicateOrdinal}`;
|
|
98
101
|
}
|
|
99
102
|
return `os-split:product:${encodedOriginalUid}:duplicate:${duplicateOrdinal}`;
|
|
100
103
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Decimal from 'decimal.js';
|
|
2
2
|
import type { CartItem } from "../Cart";
|
|
3
|
-
import type { OrderProductDiscountItem, OrderMetaList, OrderProduct, OrderSubmitPayload, OrderSubmitProduct, OrderSummary, OrderTempOrder, PointCardSnapshotItem } from './types';
|
|
3
|
+
import type { OrderProductDiscountItem, OrderMetaList, OrderProduct, OrderSubmitPayload, OrderSubmitProduct, OrderSummary, OrderTempOrder, PointCardSnapshotItem, VirtualCurrencySnapshotItem } from './types';
|
|
4
4
|
import type { RulesParamsHooks } from '../Rules/types';
|
|
5
5
|
import type { MapOrderPaymentsOptions, OrderPaymentData, OrderPaymentSource } from './types';
|
|
6
6
|
import { createUuidV4 } from './utils/orderCollectionIdentity';
|
|
@@ -18,6 +18,18 @@ export interface OrderProductsDepositSummary {
|
|
|
18
18
|
import type { WindowPlugin } from '../../plugins';
|
|
19
19
|
export declare function normalizePointCardSnapshotItem(value: unknown): PointCardSnapshotItem | null;
|
|
20
20
|
export declare function buildPointCardSnapshotFromWalletPassList(value: unknown): PointCardSnapshotItem[];
|
|
21
|
+
export declare function collectPointCardSnapshotCodeCandidates(value: unknown): Array<{
|
|
22
|
+
id: string;
|
|
23
|
+
code: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Payment 的 WalletPass 列表包含实例 code,而 prepare/config 通常只提供
|
|
27
|
+
* 卡名称和余额。按实例 ID 仅补齐 Snapshot 缺失的 code,避免后到的运行态
|
|
28
|
+
* 数据覆盖下单时已经冻结的卡名称和余额。
|
|
29
|
+
*/
|
|
30
|
+
export declare function mergePointCardSnapshotCodes(snapshotsValue: unknown, walletPassesValue: unknown): PointCardSnapshotItem[];
|
|
31
|
+
export declare function normalizeVirtualCurrencySnapshotItem(value: unknown): VirtualCurrencySnapshotItem | null;
|
|
32
|
+
export declare function buildVirtualCurrencySnapshotFromList(value: unknown): VirtualCurrencySnapshotItem[];
|
|
21
33
|
export declare function normalizeOrderMetaList(value: unknown): OrderMetaList | undefined;
|
|
22
34
|
/**
|
|
23
35
|
* 把"含 option 的主商品单价"与 bundle 合成"单行 composite 单价"。
|
|
@@ -109,8 +121,9 @@ export declare function getBundleSellingMagnitude(bundle: Record<string, any> |
|
|
|
109
121
|
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
110
122
|
* - `metadata.source_product_price`:主商品/variant 基础价(已应用报价单),不含 option、
|
|
111
123
|
* 不含折扣。**权威源**。
|
|
112
|
-
* - `
|
|
113
|
-
* - `metadata.
|
|
124
|
+
* - `product_sku.option[].add_price` 保留单规格折前单价;Rules 的 option.price 只用于本次计算。
|
|
125
|
+
* - `metadata.main_product_original_price` = source + Σ(option.add_price × option.num)(含 option、不含折扣)。
|
|
126
|
+
* - `metadata.main_product_selling_price` = main_original − 行内 per-unit amount(含主商品及 option 优惠)。
|
|
114
127
|
* - `payment_price`:出站 payload 中为行 composite 已减整单折扣均摊价(无折扣时与 `selling_price` 同义)。
|
|
115
128
|
*
|
|
116
129
|
* Rules 钩子契约(hook_adapt 方案,Rules 内部保持不变):
|
|
@@ -119,8 +132,9 @@ export declare function getBundleSellingMagnitude(bundle: Record<string, any> |
|
|
|
119
132
|
* `getProductOriginTotalPrice` 会自行叠加 option + bundle,喂 source 可避免 option 双加。
|
|
120
133
|
* - `getProduct.total` = `selling_price × num`(行 composite × num),与 Rules 内部产出的
|
|
121
134
|
* total(source + option + bundle)对齐。
|
|
135
|
+
* - `getProduct.options` 用单规格原价参与重算;主商品折后价从 main_selling 减去 option 折后合计反推。
|
|
122
136
|
* - `setProduct` 反向流程:把 Rules 返回的 source-level `main_product_selling_price` / `price`
|
|
123
|
-
*
|
|
137
|
+
* 加回单规格原价合计,再减去 optionDiscountAmount;保留订单单规格原价供取消折扣及后续重算。
|
|
124
138
|
* 优先级:
|
|
125
139
|
* 1. `values.main_product_selling_price`(券应用分支,per-unit 券后 source-level 主价)
|
|
126
140
|
* 2. `values.price`(还原分支 `restoredPrice`、good_pass 归零)
|
|
@@ -159,7 +173,7 @@ export declare function resolveManualOverrideLineOriginalPrice(params: {
|
|
|
159
173
|
* // => -4
|
|
160
174
|
*/
|
|
161
175
|
export declare function resolveEffectivePerUnitDiscount(product: Record<string, any>): number;
|
|
162
|
-
export declare function createDefaultOrderRulesHooks(): RulesParamsHooks;
|
|
176
|
+
export declare function createDefaultOrderRulesHooks(getBookings?: () => OrderTempOrder['bookings']): RulesParamsHooks;
|
|
163
177
|
/**
|
|
164
178
|
* 通过 session 类商品的开始时间结束时间生成商品的时长
|
|
165
179
|
* @param {CartItem} cartItem
|
|
@@ -11,8 +11,10 @@ Object.defineProperty(exports, "buildManualProductDiscountItem", {
|
|
|
11
11
|
});
|
|
12
12
|
exports.buildPointCardSnapshotFromWalletPassList = buildPointCardSnapshotFromWalletPassList;
|
|
13
13
|
exports.buildSubmitPayload = buildSubmitPayload;
|
|
14
|
+
exports.buildVirtualCurrencySnapshotFromList = buildVirtualCurrencySnapshotFromList;
|
|
14
15
|
exports.calculateOrderProductsDeposit = calculateOrderProductsDeposit;
|
|
15
16
|
exports.clearTempOrderHolderAssignments = clearTempOrderHolderAssignments;
|
|
17
|
+
exports.collectPointCardSnapshotCodeCandidates = collectPointCardSnapshotCodeCandidates;
|
|
16
18
|
exports.composeLinePrice = composeLinePrice;
|
|
17
19
|
exports.createDefaultOrderRulesHooks = createDefaultOrderRulesHooks;
|
|
18
20
|
exports.createDefaultTempOrder = createDefaultTempOrder;
|
|
@@ -65,6 +67,7 @@ Object.defineProperty(exports, "mergeManualProductDiscountIntoList", {
|
|
|
65
67
|
}
|
|
66
68
|
});
|
|
67
69
|
exports.mergeOrderProductDisplayFields = mergeOrderProductDisplayFields;
|
|
70
|
+
exports.mergePointCardSnapshotCodes = mergePointCardSnapshotCodes;
|
|
68
71
|
exports.mergeRelationForms = void 0;
|
|
69
72
|
exports.normalizeBookingIsAll = normalizeBookingIsAll;
|
|
70
73
|
exports.normalizeBookingSubType = normalizeBookingSubType;
|
|
@@ -74,6 +77,7 @@ exports.normalizePointCardSnapshotItem = normalizePointCardSnapshotItem;
|
|
|
74
77
|
exports.normalizeProductSkuOptions = normalizeProductSkuOptions;
|
|
75
78
|
exports.normalizeSubmitBooking = normalizeSubmitBooking;
|
|
76
79
|
exports.normalizeSubmitCollectPaxValue = normalizeSubmitCollectPaxValue;
|
|
80
|
+
exports.normalizeVirtualCurrencySnapshotItem = normalizeVirtualCurrencySnapshotItem;
|
|
77
81
|
exports.productRequiresFormSubject = productRequiresFormSubject;
|
|
78
82
|
exports.resolveEffectivePerUnitDiscount = resolveEffectivePerUnitDiscount;
|
|
79
83
|
exports.resolveIsFormSubject = resolveIsFormSubject;
|
|
@@ -125,6 +129,7 @@ Object.defineProperty(exports, "syncManualProductDiscountProductNum", {
|
|
|
125
129
|
}
|
|
126
130
|
});
|
|
127
131
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
132
|
+
var _customParseFormat = _interopRequireDefault(require("dayjs/plugin/customParseFormat"));
|
|
128
133
|
var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
129
134
|
var _weighedProduct = require("./utils/weighedProduct");
|
|
130
135
|
var _manualProductDiscount = require("./utils/manualProductDiscount");
|
|
@@ -133,7 +138,9 @@ var _utils2 = require("../../solution/ScanOrder/utils");
|
|
|
133
138
|
var _orderCollectionIdentity = require("./utils/orderCollectionIdentity");
|
|
134
139
|
var _salesNotes = require("./salesNotes");
|
|
135
140
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
141
|
+
_dayjs.default.extend(_customParseFormat.default);
|
|
136
142
|
const POINT_CARD_SNAPSHOT_TAG = 'point_card';
|
|
143
|
+
const VIRTUAL_CURRENCY_SNAPSHOT_TAG = 'virtual_currency';
|
|
137
144
|
function isPlainObject(value) {
|
|
138
145
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
139
146
|
}
|
|
@@ -161,6 +168,10 @@ function normalizePointCardSnapshotItem(value) {
|
|
|
161
168
|
if (productId !== undefined) {
|
|
162
169
|
snapshot.product_id = productId;
|
|
163
170
|
}
|
|
171
|
+
const code = normalizeSnapshotScalar(value.code);
|
|
172
|
+
if (code !== undefined) {
|
|
173
|
+
snapshot.code = String(code).trim();
|
|
174
|
+
}
|
|
164
175
|
return snapshot;
|
|
165
176
|
}
|
|
166
177
|
function buildPointCardSnapshotFromWalletPassList(value) {
|
|
@@ -171,6 +182,141 @@ function buildPointCardSnapshotFromWalletPassList(value) {
|
|
|
171
182
|
return result;
|
|
172
183
|
}, []);
|
|
173
184
|
}
|
|
185
|
+
function collectPointCardSnapshotCodeCandidates(value) {
|
|
186
|
+
if (!Array.isArray(value)) return [];
|
|
187
|
+
const codeById = new Map();
|
|
188
|
+
value.forEach(item => {
|
|
189
|
+
if (!isPlainObject(item)) return;
|
|
190
|
+
const id = normalizeSnapshotScalar(item.id ?? item.voucher_id);
|
|
191
|
+
const code = normalizeSnapshotScalar(item.code);
|
|
192
|
+
if (id === undefined || code === undefined) return;
|
|
193
|
+
const identity = String(id).trim();
|
|
194
|
+
const normalizedCode = String(code).trim();
|
|
195
|
+
if (!identity || !normalizedCode || codeById.has(identity)) return;
|
|
196
|
+
codeById.set(identity, normalizedCode);
|
|
197
|
+
});
|
|
198
|
+
return [...codeById].map(([id, code]) => ({
|
|
199
|
+
id,
|
|
200
|
+
code
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Payment 的 WalletPass 列表包含实例 code,而 prepare/config 通常只提供
|
|
206
|
+
* 卡名称和余额。按实例 ID 仅补齐 Snapshot 缺失的 code,避免后到的运行态
|
|
207
|
+
* 数据覆盖下单时已经冻结的卡名称和余额。
|
|
208
|
+
*/
|
|
209
|
+
function mergePointCardSnapshotCodes(snapshotsValue, walletPassesValue) {
|
|
210
|
+
const snapshots = buildPointCardSnapshotFromWalletPassList(snapshotsValue);
|
|
211
|
+
if (!snapshots.length || !Array.isArray(walletPassesValue)) return snapshots;
|
|
212
|
+
const codeById = new Map(collectPointCardSnapshotCodeCandidates(walletPassesValue).map(({
|
|
213
|
+
id,
|
|
214
|
+
code
|
|
215
|
+
}) => [id, code]));
|
|
216
|
+
return snapshots.map(snapshot => {
|
|
217
|
+
if (snapshot.code) return snapshot;
|
|
218
|
+
const code = codeById.get(String(snapshot.id).trim());
|
|
219
|
+
return code ? {
|
|
220
|
+
...snapshot,
|
|
221
|
+
code
|
|
222
|
+
} : snapshot;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function normalizeSnapshotNameMap(value) {
|
|
226
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
227
|
+
const normalizedText = String(value).trim();
|
|
228
|
+
return normalizedText ? {
|
|
229
|
+
original: normalizedText
|
|
230
|
+
} : {};
|
|
231
|
+
}
|
|
232
|
+
if (!isPlainObject(value)) return {};
|
|
233
|
+
return Object.entries(value).reduce((result, [locale, text]) => {
|
|
234
|
+
if (!locale.trim()) return result;
|
|
235
|
+
if (typeof text !== 'string' && typeof text !== 'number') return result;
|
|
236
|
+
const normalizedText = String(text).trim();
|
|
237
|
+
if (normalizedText) result[locale] = normalizedText;
|
|
238
|
+
return result;
|
|
239
|
+
}, {});
|
|
240
|
+
}
|
|
241
|
+
function buildVirtualCurrencySnapshotName(value) {
|
|
242
|
+
if (!isPlainObject(value)) return {};
|
|
243
|
+
const amountFormat = String(value.amount_format ?? '').trim();
|
|
244
|
+
let configuredName;
|
|
245
|
+
if (amountFormat === '{{amount}} {{unit}}') {
|
|
246
|
+
configuredName = value.unit_label;
|
|
247
|
+
} else if (amountFormat === '{{amount}} {{sym}}') {
|
|
248
|
+
configuredName = value.symbol;
|
|
249
|
+
} else {
|
|
250
|
+
return {};
|
|
251
|
+
}
|
|
252
|
+
const configuredNameMap = normalizeSnapshotNameMap(configuredName);
|
|
253
|
+
const shortNameMap = normalizeSnapshotNameMap(value.short_name);
|
|
254
|
+
|
|
255
|
+
// The configured unit/symbol is resolved before short_name. If it already
|
|
256
|
+
// carries a global fallback, keep it authoritative so (for example)
|
|
257
|
+
// short_name.en cannot mask unit_label.original. When it only has explicit
|
|
258
|
+
// locale entries, merge short_name so other receipt locales can still fall
|
|
259
|
+
// back after the configured value has no match.
|
|
260
|
+
const hasConfiguredGlobalFallback = ['original', 'auto', 'default', 'en'].some(locale => Boolean(configuredNameMap[locale]));
|
|
261
|
+
if (hasConfiguredGlobalFallback) return configuredNameMap;
|
|
262
|
+
return {
|
|
263
|
+
...shortNameMap,
|
|
264
|
+
...configuredNameMap
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function normalizeVirtualCurrencySnapshotItem(value) {
|
|
268
|
+
if (!isPlainObject(value)) return null;
|
|
269
|
+
const id = normalizeSnapshotScalar(value.id);
|
|
270
|
+
if (id === undefined) return null;
|
|
271
|
+
if (String(value.tag || '').trim().toLowerCase() !== VIRTUAL_CURRENCY_SNAPSHOT_TAG) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
const snapshot = {
|
|
275
|
+
id,
|
|
276
|
+
tag: 'virtual_currency',
|
|
277
|
+
product_name: String(value.product_name ?? ''),
|
|
278
|
+
par_value: String(value.par_value ?? ''),
|
|
279
|
+
used_par_value: String(value.used_par_value ?? ''),
|
|
280
|
+
name: normalizeSnapshotNameMap(value.name)
|
|
281
|
+
};
|
|
282
|
+
const productId = normalizeSnapshotScalar(value.product_id);
|
|
283
|
+
if (productId !== undefined) {
|
|
284
|
+
snapshot.product_id = productId;
|
|
285
|
+
}
|
|
286
|
+
return snapshot;
|
|
287
|
+
}
|
|
288
|
+
function normalizeVirtualCurrencySnapshotList(value) {
|
|
289
|
+
if (!Array.isArray(value)) return [];
|
|
290
|
+
return value.reduce((result, item) => {
|
|
291
|
+
const normalized = normalizeVirtualCurrencySnapshotItem(item);
|
|
292
|
+
if (normalized) result.push(normalized);
|
|
293
|
+
return result;
|
|
294
|
+
}, []);
|
|
295
|
+
}
|
|
296
|
+
function buildVirtualCurrencySnapshotFromList(value) {
|
|
297
|
+
if (!Array.isArray(value)) return [];
|
|
298
|
+
return value.reduce((result, item) => {
|
|
299
|
+
if (!isPlainObject(item)) return result;
|
|
300
|
+
const id = normalizeSnapshotScalar(item.id);
|
|
301
|
+
if (id === undefined) return result;
|
|
302
|
+
const sourceTag = String(item.tag ?? '').trim().toLowerCase();
|
|
303
|
+
if (sourceTag !== VIRTUAL_CURRENCY_SNAPSHOT_TAG) return result;
|
|
304
|
+
const snapshot = {
|
|
305
|
+
id,
|
|
306
|
+
tag: 'virtual_currency',
|
|
307
|
+
product_name: String(item.product_name ?? ''),
|
|
308
|
+
par_value: String(item.par_value ?? ''),
|
|
309
|
+
used_par_value: String(item.used_par_value ?? ''),
|
|
310
|
+
name: buildVirtualCurrencySnapshotName(item.virtual_currency_display)
|
|
311
|
+
};
|
|
312
|
+
const productId = normalizeSnapshotScalar(item.product_id);
|
|
313
|
+
if (productId !== undefined) {
|
|
314
|
+
snapshot.product_id = productId;
|
|
315
|
+
}
|
|
316
|
+
result.push(snapshot);
|
|
317
|
+
return result;
|
|
318
|
+
}, []);
|
|
319
|
+
}
|
|
174
320
|
function normalizeOrderMetaList(value) {
|
|
175
321
|
if (value === undefined) return undefined;
|
|
176
322
|
if (!isPlainObject(value)) return undefined;
|
|
@@ -178,6 +324,9 @@ function normalizeOrderMetaList(value) {
|
|
|
178
324
|
if (Object.prototype.hasOwnProperty.call(value, 'point_cards_snapshot')) {
|
|
179
325
|
normalized.point_cards_snapshot = buildPointCardSnapshotFromWalletPassList(value.point_cards_snapshot);
|
|
180
326
|
}
|
|
327
|
+
if (Object.prototype.hasOwnProperty.call(value, 'virtual_currency_snapshot')) {
|
|
328
|
+
normalized.virtual_currency_snapshot = normalizeVirtualCurrencySnapshotList(value.virtual_currency_snapshot);
|
|
329
|
+
}
|
|
181
330
|
if (Object.keys(normalized).length > 0) return normalized;
|
|
182
331
|
return {};
|
|
183
332
|
}
|
|
@@ -483,8 +632,9 @@ function getBundleSellingMagnitude(bundle) {
|
|
|
483
632
|
* = `metadata.main_product_original_price` + Σ(bundle 原价 × num)。
|
|
484
633
|
* - `metadata.source_product_price`:主商品/variant 基础价(已应用报价单),不含 option、
|
|
485
634
|
* 不含折扣。**权威源**。
|
|
486
|
-
* - `
|
|
487
|
-
* - `metadata.
|
|
635
|
+
* - `product_sku.option[].add_price` 保留单规格折前单价;Rules 的 option.price 只用于本次计算。
|
|
636
|
+
* - `metadata.main_product_original_price` = source + Σ(option.add_price × option.num)(含 option、不含折扣)。
|
|
637
|
+
* - `metadata.main_product_selling_price` = main_original − 行内 per-unit amount(含主商品及 option 优惠)。
|
|
488
638
|
* - `payment_price`:出站 payload 中为行 composite 已减整单折扣均摊价(无折扣时与 `selling_price` 同义)。
|
|
489
639
|
*
|
|
490
640
|
* Rules 钩子契约(hook_adapt 方案,Rules 内部保持不变):
|
|
@@ -493,8 +643,9 @@ function getBundleSellingMagnitude(bundle) {
|
|
|
493
643
|
* `getProductOriginTotalPrice` 会自行叠加 option + bundle,喂 source 可避免 option 双加。
|
|
494
644
|
* - `getProduct.total` = `selling_price × num`(行 composite × num),与 Rules 内部产出的
|
|
495
645
|
* total(source + option + bundle)对齐。
|
|
646
|
+
* - `getProduct.options` 用单规格原价参与重算;主商品折后价从 main_selling 减去 option 折后合计反推。
|
|
496
647
|
* - `setProduct` 反向流程:把 Rules 返回的 source-level `main_product_selling_price` / `price`
|
|
497
|
-
*
|
|
648
|
+
* 加回单规格原价合计,再减去 optionDiscountAmount;保留订单单规格原价供取消折扣及后续重算。
|
|
498
649
|
* 优先级:
|
|
499
650
|
* 1. `values.main_product_selling_price`(券应用分支,per-unit 券后 source-level 主价)
|
|
500
651
|
* 2. `values.price`(还原分支 `restoredPrice`、good_pass 归零)
|
|
@@ -566,6 +717,24 @@ function resolveSubmitBundleMapId(bundle) {
|
|
|
566
717
|
}
|
|
567
718
|
return undefined;
|
|
568
719
|
}
|
|
720
|
+
function ensureSubmitDiscountIdentity(discount) {
|
|
721
|
+
if (!discount || typeof discount !== 'object' || Array.isArray(discount)) {
|
|
722
|
+
return discount;
|
|
723
|
+
}
|
|
724
|
+
const discountRecord = discount;
|
|
725
|
+
const metadata = discountRecord.metadata && typeof discountRecord.metadata === 'object' && !Array.isArray(discountRecord.metadata) ? discountRecord.metadata : {};
|
|
726
|
+
const uniqueIdentificationNumber = metadata.unique_identification_number;
|
|
727
|
+
if (uniqueIdentificationNumber !== undefined && uniqueIdentificationNumber !== null && String(uniqueIdentificationNumber).trim() !== '') {
|
|
728
|
+
return discount;
|
|
729
|
+
}
|
|
730
|
+
return {
|
|
731
|
+
...discountRecord,
|
|
732
|
+
metadata: {
|
|
733
|
+
...metadata,
|
|
734
|
+
unique_identification_number: (0, _orderCollectionIdentity.createUuidV4)()
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
}
|
|
569
738
|
function collectSubmitProductDiscountList(product) {
|
|
570
739
|
const submitDiscountList = Array.isArray(product?.discount_list) ? [...product.discount_list] : [];
|
|
571
740
|
for (const bundle of product?.product_bundle || []) {
|
|
@@ -587,7 +756,7 @@ function collectSubmitProductDiscountList(product) {
|
|
|
587
756
|
});
|
|
588
757
|
}
|
|
589
758
|
}
|
|
590
|
-
return normalizeOrderProductDiscountList(submitDiscountList);
|
|
759
|
+
return normalizeOrderProductDiscountList(submitDiscountList.map(ensureSubmitDiscountIdentity));
|
|
591
760
|
}
|
|
592
761
|
|
|
593
762
|
/**
|
|
@@ -654,11 +823,35 @@ function resolveEffectivePerUnitDiscount(product) {
|
|
|
654
823
|
if (!Number.isFinite(originalPrice) || !Number.isFinite(finalPrice)) return fromList;
|
|
655
824
|
return fromList + (originalPrice - finalPrice);
|
|
656
825
|
}
|
|
657
|
-
function createDefaultOrderRulesHooks() {
|
|
826
|
+
function createDefaultOrderRulesHooks(getBookings) {
|
|
827
|
+
const getProductStartDate = product => {
|
|
828
|
+
const productUid = String(product.metadata?.unique_identification_number ?? product.unique_identification_number ?? '');
|
|
829
|
+
const bookingUid = String(product.booking_uid ?? product.metadata?.booking_uid ?? '');
|
|
830
|
+
// 每次读取当前 bookings,覆盖改期、订单回显以及直接调用 Rules 的选券入口。
|
|
831
|
+
const bookings = getBookings?.() || [];
|
|
832
|
+
const booking = bookings.find(item => productUid && String(item?.product_uid ?? item?.metadata?.product_uid ?? '') === productUid) || bookings.find(item => bookingUid && String(item?.metadata?.unique_identification_number ?? item?.booking_uid ?? '') === bookingUid);
|
|
833
|
+
if (booking) {
|
|
834
|
+
// 严格解析并保留 Invalid Date,让公共时间校验拒绝缺失/非法时间,避免回退到当前时间。
|
|
835
|
+
return (0, _dayjs.default)(`${booking.start_date} ${booking.start_time}`, ['YYYY-MM-DD HH:mm', 'YYYY-MM-DD HH:mm:ss', 'YYYY-MM-DD H:mm', 'YYYY-MM-DD H:mm:ss'], true);
|
|
836
|
+
}
|
|
837
|
+
if (getBookings && (bookingUid || product.booking_id || product.metadata?.booking_id)) {
|
|
838
|
+
return (0, _dayjs.default)('');
|
|
839
|
+
}
|
|
840
|
+
const legacyStartDate = product.metadata?.start_date || product.metadata?.startDate;
|
|
841
|
+
return legacyStartDate ? (0, _dayjs.default)(legacyStartDate) : undefined;
|
|
842
|
+
};
|
|
658
843
|
const toUnitPriceString = (totalLike, num) => {
|
|
659
844
|
const effectiveNum = Number(num) > 0 ? Number(num) : 1;
|
|
660
845
|
return new _decimal.default(Number(totalLike) || 0).dividedBy(effectiveNum).toDecimalPlaces(2).toString();
|
|
661
846
|
};
|
|
847
|
+
|
|
848
|
+
// optionDiscountAmount 已是每件主商品内的单规格优惠合计,不再乘商品数量。
|
|
849
|
+
const getOptionDiscountAmount = discountList => {
|
|
850
|
+
return (discountList || []).reduce((total, discount) => {
|
|
851
|
+
if (discount?.metadata?.custom_product_bundle_map_id) return total;
|
|
852
|
+
return total.plus(Number(discount?.metadata?.optionDiscountAmount) || 0);
|
|
853
|
+
}, new _decimal.default(0));
|
|
854
|
+
};
|
|
662
855
|
const getBundleIdentity = bundle => {
|
|
663
856
|
return [bundle.bundle_id ?? bundle.id ?? '', bundle.bundle_product_id ?? bundle._bundle_product_id ?? bundle.product_id ?? '', bundle.bundle_variant_id ?? bundle.variant_id ?? bundle.product_variant_id ?? 0, bundle.bundle_group_id ?? bundle.group_id ?? ''].join('|');
|
|
664
857
|
};
|
|
@@ -701,12 +894,14 @@ function createDefaultOrderRulesHooks() {
|
|
|
701
894
|
getProduct: product => {
|
|
702
895
|
// source_product_price 是权威源;兜底链:source → mainSelling − options(反推)→ 行 selling_price
|
|
703
896
|
const metadataAny = product.metadata || {};
|
|
704
|
-
const
|
|
897
|
+
const productOptions = getProductSkuOptions(product);
|
|
898
|
+
const optionSum = sumOptionUnitPrice(productOptions);
|
|
899
|
+
const optionSellingSum = optionSum.minus(getOptionDiscountAmount(product.discount_list));
|
|
705
900
|
let sourcePrice;
|
|
706
901
|
if (metadataAny.source_product_price !== undefined) {
|
|
707
902
|
sourcePrice = String(metadataAny.source_product_price);
|
|
708
903
|
} else if (metadataAny.main_product_selling_price !== undefined) {
|
|
709
|
-
sourcePrice = new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(
|
|
904
|
+
sourcePrice = new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(optionSellingSum).toDecimalPlaces(2).toString();
|
|
710
905
|
} else {
|
|
711
906
|
sourcePrice = String(product.selling_price ?? 0);
|
|
712
907
|
}
|
|
@@ -736,14 +931,19 @@ function createDefaultOrderRulesHooks() {
|
|
|
736
931
|
num: product.num || 1,
|
|
737
932
|
discount_list: product.discount_list || [],
|
|
738
933
|
bundle: product.product_bundle || [],
|
|
934
|
+
// 仅在 Rules 入参中映射 price,避免折后价污染订单的 add_price。
|
|
935
|
+
options: productOptions.map(option => ({
|
|
936
|
+
...option,
|
|
937
|
+
price: option.add_price
|
|
938
|
+
})),
|
|
739
939
|
booking_id: product.metadata?.booking_id || null,
|
|
740
940
|
isClient: false,
|
|
741
941
|
// 勿写死 false:否则 Rules 不会走 total≠origin_total 的手动价推断,
|
|
742
942
|
// 无券时会把 bundle 价还原成 original_price(手动改价套餐会从 20 回到 30)。
|
|
743
943
|
isManualDiscount: resolveRulesManualDiscountFlag(metadataAny),
|
|
744
944
|
holder_id: product.metadata?.holder_id,
|
|
745
|
-
startDate: product
|
|
746
|
-
main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(
|
|
945
|
+
startDate: getProductStartDate(product),
|
|
946
|
+
main_product_selling_price: metadataAny.main_product_selling_price !== undefined ? new _decimal.default(Number(metadataAny.main_product_selling_price) || 0).minus(optionSellingSum).toDecimalPlaces(2).toString() : undefined,
|
|
747
947
|
inPromotion: metadataAny._promotion?.inPromotion === true,
|
|
748
948
|
_promotion: metadataAny._promotion
|
|
749
949
|
};
|
|
@@ -754,8 +954,10 @@ function createDefaultOrderRulesHooks() {
|
|
|
754
954
|
const existedSource = metadataAny.source_product_price ?? product.selling_price ?? '0';
|
|
755
955
|
const nextOptions = getProductSkuOptions(product);
|
|
756
956
|
const optionSum = sumOptionUnitPrice(nextOptions);
|
|
957
|
+
const nextDiscountList = values.discount_list ?? product.discount_list;
|
|
958
|
+
const optionSellingSum = optionSum.minus(getOptionDiscountAmount(nextDiscountList));
|
|
757
959
|
|
|
758
|
-
// Rules 返回的 main_product_selling_price / price
|
|
960
|
+
// Rules 返回的 main_product_selling_price / price 为不含 option 的主商品价。
|
|
759
961
|
// 优先级:main_product_selling_price(per-unit 券后 source)> price(还原/good_pass 分支)>
|
|
760
962
|
// total/num(仅当 Rules 只给 total 时的兜底)> 保留当前 source。
|
|
761
963
|
const nextSourceSellingPrice = values.main_product_selling_price !== undefined ? String(values.main_product_selling_price) : values.price !== undefined ? String(values.price) : values.total !== undefined ? toUnitPriceString(values.total, nextNum) : String(existedSource);
|
|
@@ -764,8 +966,8 @@ function createDefaultOrderRulesHooks() {
|
|
|
764
966
|
// 缺省时保留现有 source(券前 = 当前 source)。
|
|
765
967
|
const nextSourceOriginalPrice = values.original_price !== undefined ? String(values.original_price) : String(existedSource);
|
|
766
968
|
|
|
767
|
-
//
|
|
768
|
-
const nextMainSellingPrice = new _decimal.default(Number(nextSourceSellingPrice) || 0).plus(
|
|
969
|
+
// 成交价只加回 option 折后合计;原价仍使用订单中保存的 option 原价。
|
|
970
|
+
const nextMainSellingPrice = new _decimal.default(Number(nextSourceSellingPrice) || 0).plus(optionSellingSum).toDecimalPlaces(2).toFixed(2);
|
|
769
971
|
const nextMainOriginalPrice = new _decimal.default(Number(nextSourceOriginalPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
770
972
|
const nextBundle = values.bundle !== undefined ? mergeRulesBundlePrices(product.product_bundle, values.bundle) : product.product_bundle;
|
|
771
973
|
const composedSellingPrice = composeLinePrice({
|
|
@@ -786,7 +988,7 @@ function createDefaultOrderRulesHooks() {
|
|
|
786
988
|
...product,
|
|
787
989
|
selling_price: composedSellingPrice,
|
|
788
990
|
original_price: finalOriginalPrice,
|
|
789
|
-
discount_list:
|
|
991
|
+
discount_list: nextDiscountList,
|
|
790
992
|
num: values.quantity ?? product.num,
|
|
791
993
|
product_bundle: nextBundle,
|
|
792
994
|
metadata: {
|
|
@@ -171,11 +171,6 @@ export declare class PaymentModule extends BaseModule implements Module, Payment
|
|
|
171
171
|
* 获取钱包支付方式
|
|
172
172
|
*/
|
|
173
173
|
getWalletPaymentMethod(): Promise<PaymentMethod | null>;
|
|
174
|
-
/**
|
|
175
|
-
* 确保支付模块所需的数据库表已创建
|
|
176
|
-
*/
|
|
177
|
-
/** @deprecated */
|
|
178
|
-
private ensurePaymentTables;
|
|
179
174
|
/**
|
|
180
175
|
* 获取部分支付的订单
|
|
181
176
|
*/
|
|
@@ -159,10 +159,6 @@ class PaymentModule extends _BaseModule.BaseModule {
|
|
|
159
159
|
this.app = this.appPlugin.getApp();
|
|
160
160
|
this.dbManager = this.app.dbManager;
|
|
161
161
|
this.logger = this.app.logger;
|
|
162
|
-
|
|
163
|
-
// 确保支付模块所需的对象存储已创建
|
|
164
|
-
// await this.ensurePaymentTables();
|
|
165
|
-
|
|
166
162
|
this.registerNetworkHandlers();
|
|
167
163
|
|
|
168
164
|
// // 预连接数据库
|
|
@@ -1111,7 +1107,7 @@ class PaymentModule extends _BaseModule.BaseModule {
|
|
|
1111
1107
|
*/
|
|
1112
1108
|
async getCashPaymentMethod() {
|
|
1113
1109
|
try {
|
|
1114
|
-
const payMethods = await this.
|
|
1110
|
+
const payMethods = await this.getPayMethodListAsync();
|
|
1115
1111
|
return payMethods.find(method => method.code === _types.PaymentMethodType.Cash) || null;
|
|
1116
1112
|
} catch (error) {
|
|
1117
1113
|
console.error('[PaymentModule] 获取现金支付方式失败', error);
|
|
@@ -1124,7 +1120,7 @@ class PaymentModule extends _BaseModule.BaseModule {
|
|
|
1124
1120
|
*/
|
|
1125
1121
|
async getEftposPaymentMethod() {
|
|
1126
1122
|
try {
|
|
1127
|
-
const payMethods = await this.
|
|
1123
|
+
const payMethods = await this.getPayMethodListAsync();
|
|
1128
1124
|
return payMethods.find(method => method.code === _types.PaymentMethodType.Eftpos) || null;
|
|
1129
1125
|
} catch (error) {
|
|
1130
1126
|
console.error('[PaymentModule] 获取Eftpos支付方式失败', error);
|
|
@@ -1137,7 +1133,7 @@ class PaymentModule extends _BaseModule.BaseModule {
|
|
|
1137
1133
|
*/
|
|
1138
1134
|
async getWalletPaymentMethod() {
|
|
1139
1135
|
try {
|
|
1140
|
-
const payMethods = await this.
|
|
1136
|
+
const payMethods = await this.getPayMethodListAsync();
|
|
1141
1137
|
return payMethods.find(method => method.code === _types.PaymentMethodType.Wallet) || null;
|
|
1142
1138
|
} catch (error) {
|
|
1143
1139
|
console.error('[PaymentModule] 获取钱包支付方式失败', error);
|
|
@@ -1145,27 +1141,6 @@ class PaymentModule extends _BaseModule.BaseModule {
|
|
|
1145
1141
|
}
|
|
1146
1142
|
}
|
|
1147
1143
|
|
|
1148
|
-
/**
|
|
1149
|
-
* 确保支付模块所需的数据库表已创建
|
|
1150
|
-
*/
|
|
1151
|
-
/** @deprecated */
|
|
1152
|
-
async ensurePaymentTables() {
|
|
1153
|
-
try {
|
|
1154
|
-
// 尝试访问 pay_method 表,如果不存在会抛出错误
|
|
1155
|
-
await this.dbManager.getAll('pay_method');
|
|
1156
|
-
} catch (error) {
|
|
1157
|
-
console.warn('[PaymentModule] pay_method 表不存在,请在数据库配置中添加以下配置:');
|
|
1158
|
-
console.warn('{ name: "pay_method", keyPath: "id" }');
|
|
1159
|
-
}
|
|
1160
|
-
try {
|
|
1161
|
-
// 尝试访问 order 表,如果不存在会抛出错误
|
|
1162
|
-
await this.dbManager.getAll('order');
|
|
1163
|
-
} catch (error) {
|
|
1164
|
-
console.warn('[PaymentModule] order 表不存在,请在数据库配置中添加以下配置:');
|
|
1165
|
-
console.warn('{ name: "order", keyPath: "uuid" }');
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
1144
|
/**
|
|
1170
1145
|
* 获取部分支付的订单
|
|
1171
1146
|
*/
|
|
@@ -412,6 +412,8 @@ export interface WalletAssetsBehaviorOptions {
|
|
|
412
412
|
export interface RefreshWalletAssetsOptions {
|
|
413
413
|
/** 商品/金额变化默认保留并重验选择;客户变化由实现层强制清空。 */
|
|
414
414
|
preserveSelection?: boolean;
|
|
415
|
+
/** 客户变化时,仅保留与本次扫码匹配的搜索结果;其他搜索缓存仍会清空。 */
|
|
416
|
+
retainSearchResultCodes?: string[];
|
|
415
417
|
}
|
|
416
418
|
export interface SelectWalletAssetOptions {
|
|
417
419
|
selected: boolean;
|
|
@@ -419,6 +421,8 @@ export interface SelectWalletAssetOptions {
|
|
|
419
421
|
}
|
|
420
422
|
export interface ScanWalletAssetResult {
|
|
421
423
|
type: SearchIdentificationCodeResult['type'];
|
|
424
|
+
/** walletCode 时保留完整 Wallet Detail,供客户解析与客户选择器使用。 */
|
|
425
|
+
data?: WalletDetailSearchData;
|
|
422
426
|
asset?: any;
|
|
423
427
|
selected: boolean;
|
|
424
428
|
state: WalletAssetsState;
|
|
@@ -864,6 +868,8 @@ export interface SearchIdentificationCodeParams extends WalletDeductionRecommend
|
|
|
864
868
|
* 搜索识别码响应数据
|
|
865
869
|
*/
|
|
866
870
|
export interface SearchIdentificationCodeResponse {
|
|
871
|
+
/** 业务是否成功 */
|
|
872
|
+
status?: boolean;
|
|
867
873
|
/** 响应状态码 */
|
|
868
874
|
code?: number;
|
|
869
875
|
/** 响应消息 */
|
|
@@ -871,12 +877,26 @@ export interface SearchIdentificationCodeResponse {
|
|
|
871
877
|
/** 响应数据 */
|
|
872
878
|
data?: SearchIdentificationCodeItem[];
|
|
873
879
|
}
|
|
880
|
+
/** Wallet code 精确搜索返回的 Wallet Detail。 */
|
|
881
|
+
export interface WalletDetailSearchData {
|
|
882
|
+
id?: string | number;
|
|
883
|
+
customer_id?: string | number;
|
|
884
|
+
customer?: Record<string, any> | null;
|
|
885
|
+
is_cross_shop_wallet?: boolean | 0 | 1;
|
|
886
|
+
[key: string]: any;
|
|
887
|
+
}
|
|
888
|
+
export interface WalletDetailSearchResponse {
|
|
889
|
+
status?: boolean;
|
|
890
|
+
code?: number;
|
|
891
|
+
message?: string;
|
|
892
|
+
data?: WalletDetailSearchData | null;
|
|
893
|
+
}
|
|
874
894
|
/**
|
|
875
895
|
* 搜索识别码结果类型
|
|
876
896
|
*/
|
|
877
897
|
export type SearchIdentificationCodeResult = {
|
|
878
898
|
type: 'walletCode';
|
|
879
|
-
data:
|
|
899
|
+
data: WalletDetailSearchData;
|
|
880
900
|
} | {
|
|
881
901
|
type: 'normalCode';
|
|
882
902
|
data: SearchIdentificationCodeItem[];
|
|
@@ -96,7 +96,7 @@ export declare class WalletPassPaymentImpl implements WalletPassPayment {
|
|
|
96
96
|
* 搜索识别码信息
|
|
97
97
|
* 通过识别码搜索相关的钱包通行证信息
|
|
98
98
|
* 基于 WalletDeductionRecommendParams 参数结构
|
|
99
|
-
*
|
|
99
|
+
* 特殊逻辑:WL 或指定 200 格式的 Wallet Code 调用 /wallet/detail/search 接口。
|
|
100
100
|
*/
|
|
101
101
|
searchIdentificationCodeAsync(params: SearchIdentificationCodeParams, config?: {
|
|
102
102
|
noCache?: boolean;
|