@pisell/pisellos 0.0.567 → 0.0.568
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/core/index.js +6 -9
- package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -2
- package/dist/model/strategy/adapter/walletPass/example.js +3 -26
- package/dist/model/strategy/adapter/walletPass/utils.js +0 -3
- package/dist/model/strategy/strategy-example.js +5 -19
- package/dist/modules/Cart/index.js +0 -3
- package/dist/modules/Cart/utils/cartProduct.js +0 -1
- package/dist/modules/Date/index.js +1 -5
- package/dist/modules/Discount/index.js +1 -4
- package/dist/modules/OpenData/index.js +0 -2
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Order/index.js +14 -41
- package/dist/modules/Payment/index.js +142 -270
- package/dist/modules/Payment/walletpass.js +4 -5
- package/dist/modules/Rules/index.js +0 -7
- package/dist/modules/Schedule/utils.js +0 -1
- package/dist/modules/Step/index.js +0 -1
- package/dist/plugins/request.js +1 -4
- package/dist/plugins/window.js +2 -6
- package/dist/server/index.js +88 -121
- package/dist/server/modules/menu/index.js +32 -41
- package/dist/server/modules/products/index.js +29 -49
- package/dist/server/modules/quotation/index.js +29 -38
- package/dist/server/modules/resource/index.js +3 -4
- package/dist/server/modules/schedule/index.js +32 -40
- package/dist/server/utils/product.js +0 -1
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingByStep/index.js +7 -59
- package/dist/solution/BookingByStep/utils/capacity.js +1 -11
- package/dist/solution/BookingByStep/utils/resources.js +1 -3
- package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +5 -7
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
- package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
- package/dist/solution/BuyTickets/index.js +9 -12
- package/dist/solution/Checkout/index.js +177 -246
- package/dist/solution/Checkout/utils/index.js +4 -16
- package/dist/solution/RegisterAndLogin/index.js +30 -76
- package/dist/solution/ScanOrder/index.js +50 -60
- package/dist/solution/ShopDiscount/index.js +2 -7
- package/dist/solution/VenueBooking/index.d.ts +5 -0
- package/dist/solution/VenueBooking/index.js +364 -327
- package/dist/utils/task.js +15 -18
- package/dist/utils/watch.js +0 -1
- package/lib/apis/picoding.js +2 -0
- package/lib/core/index.js +130 -131
- package/lib/effects/index.js +46 -57
- package/lib/index.js +92 -53
- package/lib/model/index.js +14 -21
- package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
- package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
- package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
- package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
- package/lib/model/strategy/adapter/index.js +100 -64
- package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
- package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
- package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
- package/lib/model/strategy/adapter/itemRule/index.js +83 -57
- package/lib/model/strategy/adapter/itemRule/type.js +97 -36
- package/lib/model/strategy/adapter/promotion/adapter.js +84 -63
- package/lib/model/strategy/adapter/promotion/evaluator.js +381 -231
- package/lib/model/strategy/adapter/promotion/examples.js +139 -159
- package/lib/model/strategy/adapter/promotion/index.js +1 -49
- package/lib/model/strategy/adapter/promotion/type.js +199 -35
- package/lib/model/strategy/adapter/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -152
- package/lib/model/strategy/adapter/walletPass/example.js +217 -190
- package/lib/model/strategy/adapter/walletPass/index.js +75 -51
- package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
- package/lib/model/strategy/adapter/walletPass/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/utils.js +652 -402
- package/lib/model/strategy/engine.js +270 -168
- package/lib/model/strategy/index.js +49 -34
- package/lib/model/strategy/strategy-example.js +243 -239
- package/lib/model/strategy/type.js +100 -40
- package/lib/modules/Account/index.js +39 -53
- package/lib/modules/Account/types.js +20 -33
- package/lib/modules/AccountList/index.js +116 -154
- package/lib/modules/AccountList/types.js +30 -31
- package/lib/modules/AccountList/utils.js +18 -30
- package/lib/modules/BaseModule.js +22 -45
- package/lib/modules/Cart/index.js +170 -124
- package/lib/modules/Cart/types.js +46 -51
- package/lib/modules/Cart/utils/cartAccount.js +40 -39
- package/lib/modules/Cart/utils/cartDate.js +56 -61
- package/lib/modules/Cart/utils/cartDiscount.js +28 -33
- package/lib/modules/Cart/utils/cartNote.js +27 -32
- package/lib/modules/Cart/utils/cartProduct.js +306 -241
- package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
- package/lib/modules/Cart/utils/cartResource.js +72 -78
- package/lib/modules/Cart/utils/changePrice.js +26 -62
- package/lib/modules/Cart/utils/index.js +106 -48
- package/lib/modules/Customer/constants.js +13 -34
- package/lib/modules/Customer/index.js +216 -153
- package/lib/modules/Customer/types.js +38 -35
- package/lib/modules/Date/index.js +116 -115
- package/lib/modules/Date/types.js +16 -28
- package/lib/modules/Date/utils.js +174 -123
- package/lib/modules/Discount/index.js +117 -113
- package/lib/modules/Discount/types.js +9 -31
- package/lib/modules/Guests/index.js +30 -56
- package/lib/modules/Guests/types.js +23 -33
- package/lib/modules/Holder/index.js +209 -189
- package/lib/modules/Holder/types.js +4 -16
- package/lib/modules/Holder/utils.js +20 -49
- package/lib/modules/OpenData/index.js +63 -74
- package/lib/modules/OpenData/types.js +4 -16
- package/lib/modules/OpenData/utils.js +44 -78
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Order/index.js +332 -320
- package/lib/modules/Order/types.js +24 -33
- package/lib/modules/Order/utils.js +350 -284
- package/lib/modules/Payment/cash.js +20 -33
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
- package/lib/modules/Payment/eftpos.js +16 -30
- package/lib/modules/Payment/index.js +566 -432
- package/lib/modules/Payment/mx51.js +1 -0
- package/lib/modules/Payment/types.js +216 -107
- package/lib/modules/Payment/utils.js +50 -47
- package/lib/modules/Payment/walletpass.js +221 -203
- package/lib/modules/Product/index.js +51 -46
- package/lib/modules/Product/types.js +4 -16
- package/lib/modules/Product/utils.js +32 -33
- package/lib/modules/ProductList/index.js +111 -110
- package/lib/modules/ProductList/types.js +9 -31
- package/lib/modules/Quotation/index.js +60 -82
- package/lib/modules/Quotation/types.js +4 -16
- package/lib/modules/Resource/index.js +27 -59
- package/lib/modules/Resource/types.js +22 -32
- package/lib/modules/Resource/utils.js +30 -38
- package/lib/modules/Rules/index.js +1172 -872
- package/lib/modules/Rules/types.js +17 -40
- package/lib/modules/SalesSummary/index.js +59 -68
- package/lib/modules/SalesSummary/types.js +4 -16
- package/lib/modules/SalesSummary/utils.js +176 -193
- package/lib/modules/ScanOrderLogger/index.js +59 -79
- package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
- package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
- package/lib/modules/ScanOrderLogger/types.js +4 -16
- package/lib/modules/Schedule/getDateIsInSchedule.js +334 -167
- package/lib/modules/Schedule/index.js +97 -107
- package/lib/modules/Schedule/type.js +4 -16
- package/lib/modules/Schedule/types.js +4 -16
- package/lib/modules/Schedule/utils.js +433 -291
- package/lib/modules/Step/index.js +40 -52
- package/lib/modules/Step/tyeps.js +4 -16
- package/lib/modules/Summary/index.js +66 -70
- package/lib/modules/Summary/types.js +4 -16
- package/lib/modules/Summary/utils.js +782 -429
- package/lib/modules/index.js +212 -57
- package/lib/plugins/app.js +4 -16
- package/lib/plugins/index.js +36 -25
- package/lib/plugins/request.js +137 -126
- package/lib/plugins/shopStore.js +4 -16
- package/lib/plugins/user.js +4 -16
- package/lib/plugins/window.js +171 -179
- package/lib/server/index.js +882 -623
- package/lib/server/modules/index.js +85 -59
- package/lib/server/modules/menu/index.js +146 -122
- package/lib/server/modules/menu/types.js +18 -31
- package/lib/server/modules/order/index.js +195 -231
- package/lib/server/modules/order/types.js +107 -32
- package/lib/server/modules/order/utils/filterBookings.js +174 -140
- package/lib/server/modules/order/utils/filterOrders.js +89 -60
- package/lib/server/modules/products/index.js +430 -335
- package/lib/server/modules/products/types.js +41 -34
- package/lib/server/modules/quotation/index.js +76 -77
- package/lib/server/modules/quotation/types.js +21 -31
- package/lib/server/modules/resource/index.js +216 -187
- package/lib/server/modules/resource/types.js +42 -33
- package/lib/server/modules/schedule/index.js +134 -119
- package/lib/server/modules/schedule/types.js +14 -21
- package/lib/server/modules/schedule/utils.js +334 -163
- package/lib/server/types.js +4 -16
- package/lib/server/utils/index.js +25 -23
- package/lib/server/utils/product.js +196 -139
- package/lib/server/utils/schedule.js +34 -41
- package/lib/server/utils/time.js +40 -49
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingByStep/index.js +1530 -1343
- package/lib/solution/BookingByStep/types.js +40 -99
- package/lib/solution/BookingByStep/utils/capacity.js +192 -160
- package/lib/solution/BookingByStep/utils/products.js +42 -52
- package/lib/solution/BookingByStep/utils/resources.js +527 -330
- package/lib/solution/BookingByStep/utils/stock.js +65 -44
- package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +147 -122
- package/lib/solution/BookingTicket/types.js +38 -64
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +64 -80
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +82 -80
- package/lib/solution/BookingTicket/utils/scan/index.js +90 -94
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
- package/lib/solution/BuyTickets/index.js +67 -70
- package/lib/solution/BuyTickets/types.js +22 -38
- package/lib/solution/Checkout/index.js +1451 -1158
- package/lib/solution/Checkout/types.js +91 -61
- package/lib/solution/Checkout/utils/index.js +227 -158
- package/lib/solution/PlaceOrder/index.js +55 -0
- package/lib/solution/RegisterAndLogin/config.js +493 -460
- package/lib/solution/RegisterAndLogin/index.js +633 -630
- package/lib/solution/RegisterAndLogin/types.js +189 -76
- package/lib/solution/RegisterAndLogin/utils.js +183 -125
- package/lib/solution/Sales/index.js +218 -200
- package/lib/solution/Sales/types.js +27 -33
- package/lib/solution/ScanOrder/index.js +803 -840
- package/lib/solution/ScanOrder/types.js +34 -34
- package/lib/solution/ScanOrder/utils.js +372 -331
- package/lib/solution/ShopDiscount/index.js +230 -236
- package/lib/solution/ShopDiscount/types.js +15 -37
- package/lib/solution/ShopDiscount/utils.js +309 -172
- package/lib/solution/VenueBooking/index.d.ts +5 -0
- package/lib/solution/VenueBooking/index.js +886 -929
- package/lib/solution/VenueBooking/types.js +20 -40
- package/lib/solution/VenueBooking/utils/dateSummary.js +22 -54
- package/lib/solution/VenueBooking/utils/resource.js +31 -54
- package/lib/solution/VenueBooking/utils/slotMerge.js +88 -106
- package/lib/solution/VenueBooking/utils/smartPricing.js +112 -100
- package/lib/solution/VenueBooking/utils/timeSlot.js +133 -132
- package/lib/solution/VenueBooking/utils.js +130 -67
- package/lib/solution/index.js +102 -37
- package/lib/store/createStore.js +32 -29
- package/lib/types/index.js +4 -16
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +81 -47
- package/package.json +2 -1
|
@@ -1,82 +1,110 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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;
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
generateRequestUniqueId: true,
|
|
8
|
+
PaymentModule: true
|
|
16
9
|
};
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
exports.PaymentModule = void 0;
|
|
11
|
+
exports.generateRequestUniqueId = generateRequestUniqueId;
|
|
12
|
+
var _BaseModule = require("../BaseModule");
|
|
13
|
+
var _types = require("./types");
|
|
14
|
+
Object.keys(_types).forEach(function (key) {
|
|
15
|
+
if (key === "default" || key === "__esModule") return;
|
|
16
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
17
|
+
if (key in exports && exports[key] === _types[key]) return;
|
|
18
|
+
Object.defineProperty(exports, key, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _types[key];
|
|
22
|
+
}
|
|
23
|
+
});
|
|
25
24
|
});
|
|
26
|
-
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
__reExport(Payment_exports, require("./types"), module.exports);
|
|
25
|
+
var _utils = require("../Cart/utils");
|
|
26
|
+
var _cash = require("./cash");
|
|
27
|
+
var _eftpos = require("./eftpos");
|
|
28
|
+
var _walletpass = require("./walletpass");
|
|
29
|
+
var _decimal = require("decimal.js");
|
|
30
|
+
/**
|
|
31
|
+
* 格式化金额为保留两位小数的字符串
|
|
32
|
+
*/
|
|
35
33
|
function formatAmount(amount) {
|
|
36
34
|
try {
|
|
37
|
-
const decimal = new
|
|
35
|
+
const decimal = new _decimal.Decimal(amount);
|
|
38
36
|
return decimal.toFixed(2);
|
|
39
37
|
} catch (error) {
|
|
40
38
|
console.warn(`[PaymentModule] 金额格式化失败: ${amount},使用默认值 0.00`);
|
|
41
|
-
return
|
|
39
|
+
return '0.00';
|
|
42
40
|
}
|
|
43
41
|
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 格式化日期时间为字符串
|
|
45
|
+
* 格式: YYYY-MM-DD HH:mm:ss
|
|
46
|
+
* 示例: 2025-12-10 16:14:50
|
|
47
|
+
*/
|
|
44
48
|
function formatDateTime(date) {
|
|
45
49
|
const year = date.getFullYear();
|
|
46
|
-
const month = String(date.getMonth() + 1).padStart(2,
|
|
47
|
-
const day = String(date.getDate()).padStart(2,
|
|
48
|
-
const hours = String(date.getHours()).padStart(2,
|
|
49
|
-
const minutes = String(date.getMinutes()).padStart(2,
|
|
50
|
-
const seconds = String(date.getSeconds()).padStart(2,
|
|
50
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
51
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
52
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
53
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
54
|
+
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
51
55
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
52
56
|
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 生成请求唯一ID
|
|
60
|
+
* 格式: 年月日时分秒毫秒+4位随机数
|
|
61
|
+
* 示例: 20241201143025123456
|
|
62
|
+
*/
|
|
53
63
|
function generateRequestUniqueId() {
|
|
54
|
-
const now =
|
|
64
|
+
const now = new Date();
|
|
55
65
|
const year = now.getFullYear();
|
|
56
|
-
const month = String(now.getMonth() + 1).padStart(2,
|
|
57
|
-
const day = String(now.getDate()).padStart(2,
|
|
58
|
-
const hour = String(now.getHours()).padStart(2,
|
|
59
|
-
const minute = String(now.getMinutes()).padStart(2,
|
|
60
|
-
const second = String(now.getSeconds()).padStart(2,
|
|
61
|
-
const millisecond = String(now.getMilliseconds()).padStart(3,
|
|
62
|
-
const randomDigits = Math.floor(Math.random() *
|
|
66
|
+
const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
67
|
+
const day = String(now.getDate()).padStart(2, '0');
|
|
68
|
+
const hour = String(now.getHours()).padStart(2, '0');
|
|
69
|
+
const minute = String(now.getMinutes()).padStart(2, '0');
|
|
70
|
+
const second = String(now.getSeconds()).padStart(2, '0');
|
|
71
|
+
const millisecond = String(now.getMilliseconds()).padStart(3, '0');
|
|
72
|
+
const randomDigits = Math.floor(Math.random() * 9000) + 1000; // 1000-9999的4位随机数
|
|
73
|
+
|
|
63
74
|
return `${year}${month}${day}${hour}${minute}${second}${millisecond}${randomDigits}`;
|
|
64
75
|
}
|
|
65
|
-
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 支付模块实现
|
|
79
|
+
*
|
|
80
|
+
* 负责处理支付相关的数据管理和本地存储
|
|
81
|
+
*/
|
|
82
|
+
class PaymentModule extends _BaseModule.BaseModule {
|
|
83
|
+
defaultName = 'pay';
|
|
84
|
+
defaultVersion = '1.0.0';
|
|
85
|
+
request;
|
|
86
|
+
app; // App instance
|
|
87
|
+
store;
|
|
88
|
+
window; // WindowPlugin 实例
|
|
89
|
+
dbManager; // IndexDBManager 实例
|
|
90
|
+
logger; // LoggerManager 实例
|
|
91
|
+
voucherUpdateLockByOrderUuid = new Map();
|
|
92
|
+
otherParams = {};
|
|
93
|
+
|
|
94
|
+
// 支付方式实例
|
|
95
|
+
cash;
|
|
96
|
+
eftpos;
|
|
97
|
+
wallet;
|
|
66
98
|
constructor(name, version) {
|
|
67
99
|
super(name || "payment", version);
|
|
68
|
-
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
this.
|
|
72
|
-
this.otherParams = {};
|
|
73
|
-
this.cash = new import_cash.CashPaymentImpl(this);
|
|
74
|
-
this.eftpos = new import_eftpos.EftposPaymentImpl(this);
|
|
75
|
-
this.wallet = new import_walletpass.WalletPassPaymentImpl(this);
|
|
100
|
+
// 初始化支付方式实例
|
|
101
|
+
this.cash = new _cash.CashPaymentImpl(this);
|
|
102
|
+
this.eftpos = new _eftpos.EftposPaymentImpl(this);
|
|
103
|
+
this.wallet = new _walletpass.WalletPassPaymentImpl(this);
|
|
76
104
|
}
|
|
77
105
|
runVoucherUpdateLocked(orderUuid, task) {
|
|
78
106
|
const previous = this.voucherUpdateLockByOrderUuid.get(orderUuid) || Promise.resolve();
|
|
79
|
-
const next = previous.catch(() =>
|
|
107
|
+
const next = previous.catch(() => undefined).then(task).finally(() => {
|
|
80
108
|
if (this.voucherUpdateLockByOrderUuid.get(orderUuid) === next) {
|
|
81
109
|
this.voucherUpdateLockByOrderUuid.delete(orderUuid);
|
|
82
110
|
}
|
|
@@ -85,18 +113,21 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
85
113
|
return next;
|
|
86
114
|
}
|
|
87
115
|
normalizeVoucherPaymentItems(voucherPaymentItems) {
|
|
88
|
-
const normalized =
|
|
116
|
+
const normalized = new Map();
|
|
89
117
|
for (const item of voucherPaymentItems || []) {
|
|
90
|
-
if (!
|
|
118
|
+
if (!item?.voucher_id) {
|
|
91
119
|
throw new Error(`代金券支付项缺少 voucher_id: ${JSON.stringify(item)}`);
|
|
92
120
|
}
|
|
93
|
-
const orderPaymentType = item.order_payment_type ||
|
|
121
|
+
const orderPaymentType = item.order_payment_type || 'normal';
|
|
94
122
|
const key = `${item.voucher_id}|${orderPaymentType}`;
|
|
95
|
-
normalized.set(key, {
|
|
123
|
+
normalized.set(key, {
|
|
124
|
+
...item,
|
|
125
|
+
order_payment_type: orderPaymentType
|
|
126
|
+
});
|
|
96
127
|
}
|
|
97
128
|
return {
|
|
98
129
|
items: Array.from(normalized.values()),
|
|
99
|
-
originalCount:
|
|
130
|
+
originalCount: voucherPaymentItems?.length || 0,
|
|
100
131
|
normalizedCount: normalized.size
|
|
101
132
|
};
|
|
102
133
|
}
|
|
@@ -104,30 +135,37 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
104
135
|
this.core = core;
|
|
105
136
|
this.store = options.store;
|
|
106
137
|
this.otherParams = options.otherParams || {};
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
this.
|
|
138
|
+
|
|
139
|
+
// 获取依赖的插件
|
|
140
|
+
this.request = core.getPlugin('request');
|
|
141
|
+
const appPlugin = core.getPlugin('app');
|
|
142
|
+
this.window = core.getPlugin('window');
|
|
110
143
|
if (!this.request) {
|
|
111
|
-
throw new Error(
|
|
144
|
+
throw new Error('支付模块需要 request 插件支持');
|
|
112
145
|
}
|
|
113
146
|
if (!appPlugin) {
|
|
114
|
-
throw new Error(
|
|
147
|
+
throw new Error('支付模块需要 app 插件支持');
|
|
115
148
|
}
|
|
116
149
|
this.app = appPlugin.getApp();
|
|
117
150
|
this.dbManager = this.app.dbManager;
|
|
118
151
|
this.logger = this.app.logger;
|
|
152
|
+
|
|
153
|
+
// 确保支付模块所需的对象存储已创建
|
|
119
154
|
await this.ensurePaymentTables();
|
|
120
155
|
this.registerNetworkHandlers();
|
|
121
|
-
|
|
122
|
-
|
|
156
|
+
|
|
157
|
+
// // 预连接数据库
|
|
158
|
+
// this.dbManager.connect()
|
|
159
|
+
|
|
160
|
+
this.logInfo('PaymentModule initialized successfully');
|
|
123
161
|
}
|
|
162
|
+
|
|
124
163
|
/**
|
|
125
164
|
* 记录信息日志
|
|
126
165
|
*/
|
|
127
166
|
logInfo(title, metadata) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const fatherModule = this.core.getModule((_b = this.otherParams) == null ? void 0 : _b.fatherModule);
|
|
167
|
+
if (this.otherParams?.fatherModule) {
|
|
168
|
+
const fatherModule = this.core.getModule(this.otherParams?.fatherModule);
|
|
131
169
|
if (fatherModule) {
|
|
132
170
|
fatherModule.logInfo(`${title}`, metadata);
|
|
133
171
|
return;
|
|
@@ -135,31 +173,33 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
135
173
|
}
|
|
136
174
|
if (this.logger) {
|
|
137
175
|
this.logger.addLog({
|
|
138
|
-
type:
|
|
176
|
+
type: 'info',
|
|
139
177
|
title: `[PaymentModule] ${title}`,
|
|
140
178
|
metadata: metadata || {}
|
|
141
179
|
});
|
|
142
180
|
}
|
|
143
181
|
}
|
|
182
|
+
|
|
144
183
|
/**
|
|
145
184
|
* 记录警告日志
|
|
146
185
|
*/
|
|
147
186
|
logWarning(title, metadata) {
|
|
148
187
|
if (this.logger) {
|
|
149
188
|
this.logger.addLog({
|
|
150
|
-
type:
|
|
189
|
+
type: 'warning',
|
|
151
190
|
title: `[PaymentModule] ${title}`,
|
|
152
191
|
metadata: metadata || {}
|
|
153
192
|
});
|
|
154
193
|
}
|
|
155
194
|
}
|
|
195
|
+
|
|
156
196
|
/**
|
|
157
197
|
* 记录错误日志
|
|
158
198
|
*/
|
|
159
199
|
logError(title, error, metadata) {
|
|
160
200
|
if (this.logger) {
|
|
161
201
|
this.logger.addLog({
|
|
162
|
-
type:
|
|
202
|
+
type: 'error',
|
|
163
203
|
title: `[PaymentModule] ${title}`,
|
|
164
204
|
metadata: {
|
|
165
205
|
error: error ? {
|
|
@@ -167,144 +207,157 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
167
207
|
stack: error.stack,
|
|
168
208
|
code: error.code,
|
|
169
209
|
...error
|
|
170
|
-
} :
|
|
171
|
-
...metadata || {}
|
|
210
|
+
} : undefined,
|
|
211
|
+
...(metadata || {})
|
|
172
212
|
}
|
|
173
213
|
});
|
|
174
214
|
}
|
|
175
215
|
}
|
|
216
|
+
|
|
176
217
|
/**
|
|
177
218
|
* 记录调试日志
|
|
178
219
|
*/
|
|
179
220
|
logDebug(title, metadata) {
|
|
180
221
|
if (this.logger) {
|
|
181
222
|
this.logger.addLog({
|
|
182
|
-
type:
|
|
223
|
+
type: 'debug',
|
|
183
224
|
title: `[PaymentModule] ${title}`,
|
|
184
225
|
metadata: metadata || {}
|
|
185
226
|
});
|
|
186
227
|
}
|
|
187
228
|
}
|
|
229
|
+
|
|
188
230
|
/**
|
|
189
231
|
* 网络恢复以后,尝试执行队列
|
|
190
232
|
*
|
|
191
233
|
*/
|
|
192
234
|
registerNetworkHandlers() {
|
|
193
|
-
const network = this.app.plugins.get(
|
|
194
|
-
this.logInfo(
|
|
195
|
-
network
|
|
196
|
-
|
|
197
|
-
this.logInfo("Network status changed", {
|
|
235
|
+
const network = this.app.plugins.get('network');
|
|
236
|
+
this.logInfo('Registering network status listener');
|
|
237
|
+
network?.addListener('networkStatusChange', async status => {
|
|
238
|
+
this.logInfo('Network status changed', {
|
|
198
239
|
connected: status.connected,
|
|
199
240
|
previousStatus: status.previousStatus
|
|
200
241
|
});
|
|
201
242
|
if (status.connected) {
|
|
202
|
-
this.logInfo(
|
|
243
|
+
this.logInfo('Network reconnected');
|
|
244
|
+
// 网络恢复时的处理逻辑可以在这里添加
|
|
203
245
|
}
|
|
204
246
|
});
|
|
205
247
|
}
|
|
206
248
|
async filterPayMethods(payMethods) {
|
|
207
|
-
|
|
208
|
-
|
|
249
|
+
// 1. 筛选 status === 1 && disable === 0的数据
|
|
250
|
+
// 2. 检查列表里是否有 code=WALLET_PASS的数据,如果没有,则列表里如果有 PRODUCTVOUCHER 、 GIFTCARD 、 POINTCARD 则删除他们
|
|
251
|
+
// 如果有 code = WALLET_PASS的数据,则列表里PRODUCTVOUCHER 、 GIFTCARD 、 POINTCARD 的channel_application 指向 WALLET_PASS 的 channel_application
|
|
252
|
+
payMethods = payMethods.filter(method => method.status === 1 && method.disable === 0);
|
|
253
|
+
const walletPassMethod = payMethods.find(method => method.code === 'WALLET_PASS');
|
|
209
254
|
if (walletPassMethod) {
|
|
210
|
-
payMethods.forEach(
|
|
211
|
-
if (method.code ===
|
|
255
|
+
payMethods.forEach(method => {
|
|
256
|
+
if (method.code === 'PRODUCTVOUCHER' || method.code === 'GIFTCARD' || method.code === 'POINTCARD') {
|
|
212
257
|
method.channel_application = walletPassMethod.channel_application;
|
|
213
258
|
}
|
|
214
259
|
});
|
|
215
260
|
} else {
|
|
216
|
-
payMethods = payMethods.filter(
|
|
261
|
+
payMethods = payMethods.filter(method => method.code !== 'PRODUCTVOUCHER' && method.code !== 'GIFTCARD' && method.code !== 'POINTCARD');
|
|
217
262
|
}
|
|
218
263
|
return payMethods;
|
|
219
264
|
}
|
|
265
|
+
|
|
220
266
|
/**
|
|
221
267
|
* 获取支付方式列表
|
|
222
268
|
*/
|
|
223
269
|
async getPayMethodListAsync() {
|
|
224
|
-
this.logInfo(
|
|
270
|
+
this.logInfo('Starting getPayMethodListAsync');
|
|
225
271
|
try {
|
|
272
|
+
// 先尝试从 IndexDB 获取缓存
|
|
226
273
|
let cachedMethods = [];
|
|
227
274
|
try {
|
|
228
|
-
cachedMethods = await this.dbManager.getAll(
|
|
275
|
+
cachedMethods = await this.dbManager.getAll('pay_method');
|
|
229
276
|
} catch (dbError) {
|
|
230
|
-
console.warn(
|
|
277
|
+
console.warn('[PaymentModule] pay_method 表不存在,将从服务器获取数据');
|
|
231
278
|
}
|
|
279
|
+
|
|
280
|
+
// 如果有缓存,先返回缓存数据
|
|
232
281
|
const hasCache = cachedMethods.length > 0;
|
|
233
282
|
if (hasCache) {
|
|
283
|
+
// 后台异步获取最新数据
|
|
234
284
|
this.refreshPaymentMethodsInBackground(cachedMethods);
|
|
235
285
|
return cachedMethods;
|
|
236
286
|
}
|
|
237
|
-
|
|
287
|
+
|
|
288
|
+
// 没有缓存时,直接从服务器获取
|
|
289
|
+
const response = await this.request.get('/pay/custom-payment/all');
|
|
238
290
|
response.data = this.filterPayMethods(response.data);
|
|
239
291
|
const payMethods = response.data || [];
|
|
292
|
+
|
|
293
|
+
// 尝试缓存到 IndexDB
|
|
240
294
|
try {
|
|
241
295
|
for (const method of payMethods) {
|
|
242
|
-
await this.dbManager.update(
|
|
296
|
+
await this.dbManager.update('pay_method', method);
|
|
243
297
|
}
|
|
244
298
|
} catch (dbError) {
|
|
245
|
-
console.warn(
|
|
299
|
+
console.warn('[PaymentModule] 无法缓存支付方式,pay_method 表不存在');
|
|
246
300
|
}
|
|
247
|
-
await this.core.effects.emit(
|
|
248
|
-
|
|
249
|
-
payMethods
|
|
250
|
-
);
|
|
251
|
-
this.logInfo("getPayMethodListAsync completed successfully", {
|
|
301
|
+
await this.core.effects.emit(`${this.name}:onPaymentMethodsLoaded`, payMethods);
|
|
302
|
+
this.logInfo('getPayMethodListAsync completed successfully', {
|
|
252
303
|
payMethods
|
|
253
304
|
});
|
|
254
305
|
return payMethods;
|
|
255
306
|
} catch (error) {
|
|
256
|
-
console.error(
|
|
257
|
-
this.logError(
|
|
307
|
+
console.error('[PaymentModule] 获取支付方式列表失败', error);
|
|
308
|
+
this.logError('getPayMethodListAsync failed', error);
|
|
309
|
+
// 如果所有操作都失败,返回空数组
|
|
258
310
|
return [];
|
|
259
311
|
}
|
|
260
312
|
}
|
|
313
|
+
|
|
261
314
|
/**
|
|
262
315
|
* 后台刷新支付方式列表
|
|
263
316
|
*/
|
|
264
317
|
async refreshPaymentMethodsInBackground(cachedMethods) {
|
|
265
|
-
this.logInfo(
|
|
318
|
+
this.logInfo('Starting refreshPaymentMethodsInBackground', {
|
|
266
319
|
cachedMethodsCount: cachedMethods.length
|
|
267
320
|
});
|
|
268
321
|
try {
|
|
269
|
-
|
|
270
|
-
const response = await this.request.get(
|
|
322
|
+
// 从服务器获取最新数据
|
|
323
|
+
const response = await this.request.get('/pay/custom-payment/all');
|
|
271
324
|
response.data = this.filterPayMethods(response.data);
|
|
272
325
|
const newPayMethods = response.data || [];
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
);
|
|
326
|
+
|
|
327
|
+
// 检查是否有变化
|
|
328
|
+
const hasChanges = this.hasPaymentMethodsChanged(cachedMethods, newPayMethods);
|
|
277
329
|
if (hasChanges) {
|
|
278
|
-
|
|
279
|
-
this.logInfo("Payment methods updated in background", {
|
|
330
|
+
this.logInfo('Payment methods updated in background', {
|
|
280
331
|
oldCount: cachedMethods.length,
|
|
281
332
|
newCount: newPayMethods.length
|
|
282
333
|
});
|
|
334
|
+
|
|
335
|
+
// 更新缓存
|
|
283
336
|
try {
|
|
337
|
+
// 先清除旧数据
|
|
284
338
|
for (const method of cachedMethods) {
|
|
285
|
-
await this.dbManager.delete(
|
|
339
|
+
await this.dbManager.delete('pay_method', method.id);
|
|
286
340
|
}
|
|
341
|
+
// 添加新数据
|
|
287
342
|
for (const method of newPayMethods) {
|
|
288
|
-
await this.dbManager.update(
|
|
343
|
+
await this.dbManager.update('pay_method', method);
|
|
289
344
|
}
|
|
290
345
|
} catch (dbError) {
|
|
291
|
-
console.warn(
|
|
346
|
+
console.warn('[PaymentModule] 无法更新支付方式缓存', dbError);
|
|
292
347
|
}
|
|
348
|
+
|
|
349
|
+
// 通知外部支付方式已变化
|
|
293
350
|
const eventData = {
|
|
294
351
|
oldMethods: cachedMethods,
|
|
295
352
|
newMethods: newPayMethods
|
|
296
353
|
};
|
|
297
|
-
await this.core.effects.emit(
|
|
298
|
-
|
|
299
|
-
eventData
|
|
300
|
-
);
|
|
301
|
-
} else {
|
|
302
|
-
console.log("[PaymentModule] 支付方式列表无变化");
|
|
303
|
-
}
|
|
354
|
+
await this.core.effects.emit(`${this.name}:onPaymentMethodsChanged`, eventData);
|
|
355
|
+
} else {}
|
|
304
356
|
} catch (error) {
|
|
305
|
-
console.error(
|
|
357
|
+
console.error('[PaymentModule] 后台刷新支付方式失败', error);
|
|
306
358
|
}
|
|
307
359
|
}
|
|
360
|
+
|
|
308
361
|
/**
|
|
309
362
|
* 检查支付方式列表是否有变化
|
|
310
363
|
*/
|
|
@@ -312,101 +365,137 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
312
365
|
if (oldMethods.length !== newMethods.length) {
|
|
313
366
|
return true;
|
|
314
367
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
);
|
|
368
|
+
|
|
369
|
+
// 创建旧数据的 Map 便于查找
|
|
370
|
+
const oldMethodsMap = new Map(oldMethods.map(method => [method.id, method]));
|
|
371
|
+
|
|
372
|
+
// 检查每个新方法是否与旧方法相同
|
|
318
373
|
for (const newMethod of newMethods) {
|
|
319
374
|
const oldMethod = oldMethodsMap.get(newMethod.id);
|
|
320
375
|
if (!oldMethod) {
|
|
321
|
-
return true;
|
|
376
|
+
return true; // 新增方法
|
|
322
377
|
}
|
|
378
|
+
|
|
379
|
+
// 检查关键字段是否有变化
|
|
323
380
|
if (oldMethod.code !== newMethod.code || oldMethod.name !== newMethod.name || oldMethod.type !== newMethod.type || oldMethod.description !== newMethod.description || oldMethod.status !== newMethod.status || oldMethod.disable !== newMethod.disable || oldMethod.is_surcharge !== newMethod.is_surcharge || oldMethod.fixed !== newMethod.fixed || oldMethod.percentage !== newMethod.percentage || oldMethod.enabled !== newMethod.enabled || JSON.stringify(oldMethod.channel_application || []) !== JSON.stringify(newMethod.channel_application || []) || JSON.stringify(oldMethod.companies || []) !== JSON.stringify(newMethod.companies || []) || JSON.stringify(oldMethod.metadata || {}) !== JSON.stringify(newMethod.metadata || {})) {
|
|
324
|
-
|
|
325
|
-
id: newMethod.id,
|
|
326
|
-
changes: {
|
|
327
|
-
code: oldMethod.code !== newMethod.code ? { old: oldMethod.code, new: newMethod.code } : void 0,
|
|
328
|
-
name: oldMethod.name !== newMethod.name ? { old: oldMethod.name, new: newMethod.name } : void 0,
|
|
329
|
-
type: oldMethod.type !== newMethod.type ? { old: oldMethod.type, new: newMethod.type } : void 0,
|
|
330
|
-
description: oldMethod.description !== newMethod.description ? { old: oldMethod.description, new: newMethod.description } : void 0,
|
|
331
|
-
status: oldMethod.status !== newMethod.status ? { old: oldMethod.status, new: newMethod.status } : void 0,
|
|
332
|
-
disable: oldMethod.disable !== newMethod.disable ? { old: oldMethod.disable, new: newMethod.disable } : void 0,
|
|
333
|
-
is_surcharge: oldMethod.is_surcharge !== newMethod.is_surcharge ? { old: oldMethod.is_surcharge, new: newMethod.is_surcharge } : void 0,
|
|
334
|
-
fixed: oldMethod.fixed !== newMethod.fixed ? { old: oldMethod.fixed, new: newMethod.fixed } : void 0,
|
|
335
|
-
percentage: oldMethod.percentage !== newMethod.percentage ? { old: oldMethod.percentage, new: newMethod.percentage } : void 0,
|
|
336
|
-
enabled: oldMethod.enabled !== newMethod.enabled ? { old: oldMethod.enabled, new: newMethod.enabled } : void 0,
|
|
337
|
-
channel_application: JSON.stringify(oldMethod.channel_application || []) !== JSON.stringify(newMethod.channel_application || []) ? { old: oldMethod.channel_application, new: newMethod.channel_application } : void 0,
|
|
338
|
-
companies: JSON.stringify(oldMethod.companies || []) !== JSON.stringify(newMethod.companies || []) ? { old: oldMethod.companies, new: newMethod.companies } : void 0,
|
|
339
|
-
metadata: JSON.stringify(oldMethod.metadata || {}) !== JSON.stringify(newMethod.metadata || {}) ? { old: oldMethod.metadata, new: newMethod.metadata } : void 0
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
return true;
|
|
381
|
+
return true; // 方法属性有变化
|
|
343
382
|
}
|
|
344
383
|
}
|
|
345
384
|
return false;
|
|
346
385
|
}
|
|
386
|
+
|
|
347
387
|
/**
|
|
348
388
|
* 获取订单列表
|
|
349
389
|
*/
|
|
350
390
|
async getOrderListAsync() {
|
|
351
391
|
try {
|
|
352
|
-
return await this.dbManager.getAll(
|
|
392
|
+
return await this.dbManager.getAll('order');
|
|
353
393
|
} catch (error) {
|
|
354
|
-
console.error(
|
|
394
|
+
console.error('[PaymentModule] 获取订单列表失败', error);
|
|
355
395
|
return [];
|
|
356
396
|
}
|
|
357
397
|
}
|
|
398
|
+
|
|
358
399
|
/**
|
|
359
400
|
* 根据订单UUID获取支付订单(新方法)
|
|
360
401
|
*/
|
|
361
402
|
async getPaymentOrderByUuidAsync(orderUuid) {
|
|
362
403
|
try {
|
|
363
|
-
return await this.dbManager.get(
|
|
404
|
+
return await this.dbManager.get('order', orderUuid, true);
|
|
364
405
|
} catch (error) {
|
|
365
|
-
console.error(
|
|
406
|
+
console.error('[PaymentModule] 获取支付订单失败', error);
|
|
366
407
|
return null;
|
|
367
408
|
}
|
|
368
409
|
}
|
|
410
|
+
|
|
369
411
|
/**
|
|
370
412
|
* 创建支付订单(新方法,专注支付数据)
|
|
371
413
|
*/
|
|
372
414
|
async createPaymentOrderAsync(params) {
|
|
373
|
-
this.logInfo(
|
|
415
|
+
this.logInfo('Starting createPaymentOrderAsync', {
|
|
374
416
|
orderId: params.order_id,
|
|
375
417
|
totalAmount: params.total_amount
|
|
376
418
|
});
|
|
377
419
|
try {
|
|
420
|
+
// 检测是否有重复的 order_id
|
|
421
|
+
// console.time('createLocalOrderAsync: getExistingOrder')
|
|
422
|
+
// const existingOrder = await this.dbManager.get('order', params.order_id);
|
|
423
|
+
// const existingOrders = await this.dbManager.getAll('order');
|
|
424
|
+
// const existingOrder = existingOrders.find(
|
|
425
|
+
// (order: PaymentOrder) => String(order.id) === String(params.order_id),
|
|
426
|
+
// );
|
|
427
|
+
|
|
428
|
+
// this.logInfo('createPaymentOrderAsync existingOrder', {
|
|
429
|
+
// existingOrder
|
|
430
|
+
// });
|
|
431
|
+
// console.timeEnd('createLocalOrderAsync: getExistingOrder')
|
|
432
|
+
// const existingOrder = existingOrders.find(
|
|
433
|
+
// (order: PaymentOrder) => String(order.id) === String(params.order_id),
|
|
434
|
+
// );
|
|
435
|
+
|
|
436
|
+
// if (existingOrder) {
|
|
437
|
+
// // 如果存在相同 order_id 的订单,更新该订单信息
|
|
438
|
+
// this.logInfo(
|
|
439
|
+
// `createPaymentOrderAsync found duplicate order ID: ${params.order_id}, updating existing payment order`,
|
|
440
|
+
// );
|
|
441
|
+
|
|
442
|
+
// // const originalOrder = { ...existingOrder };
|
|
443
|
+
// existingOrder.order_info = params.order_info;
|
|
444
|
+
// existingOrder.total_amount = params.total_amount;
|
|
445
|
+
// existingOrder.is_deposit = params.is_deposit || 0;
|
|
446
|
+
// existingOrder.deposit_amount = params.deposit_amount || '0.00';
|
|
447
|
+
|
|
448
|
+
// // 重新计算待付金额
|
|
449
|
+
// this.recalculateOrderAmount(existingOrder);
|
|
450
|
+
|
|
451
|
+
// // 更新到数据库
|
|
452
|
+
// await this.dbManager.update('order', existingOrder);
|
|
453
|
+
|
|
454
|
+
// // 触发更新事件
|
|
455
|
+
// this.core.effects.emit(
|
|
456
|
+
// `${this.name}:onOrderUpdated`,
|
|
457
|
+
// existingOrder,
|
|
458
|
+
// );
|
|
459
|
+
|
|
460
|
+
// return existingOrder;
|
|
461
|
+
// } else {
|
|
462
|
+
// 创建新的支付订单
|
|
378
463
|
const newOrder = {
|
|
379
|
-
uuid: (0,
|
|
464
|
+
uuid: (0, _utils.getUniqueId)('pay_order_'),
|
|
380
465
|
id: params.order_id,
|
|
381
466
|
order_id: params.order_id,
|
|
382
467
|
order_info: params.order_info,
|
|
383
|
-
payment_status:
|
|
468
|
+
payment_status: _types.PaymentStatus.Processing,
|
|
384
469
|
payment: [],
|
|
385
470
|
adjust_offline_payments: [],
|
|
386
471
|
total_amount: params.total_amount,
|
|
387
472
|
expect_amount: params.total_amount,
|
|
388
|
-
tax_fee:
|
|
473
|
+
tax_fee: '0.00',
|
|
389
474
|
is_deposit: params.is_deposit || 0,
|
|
390
|
-
deposit_amount: params.deposit_amount ||
|
|
475
|
+
deposit_amount: params.deposit_amount || '0.00'
|
|
391
476
|
};
|
|
477
|
+
|
|
478
|
+
// 🔧 新增: 处理云端已存在的支付项
|
|
392
479
|
if (params.existPayment && params.existPayment.length > 0) {
|
|
393
|
-
const currentTime = formatDateTime(
|
|
394
|
-
newOrder.payment = params.existPayment.map(
|
|
480
|
+
const currentTime = formatDateTime(new Date());
|
|
481
|
+
newOrder.payment = params.existPayment.map(payment => ({
|
|
395
482
|
...payment,
|
|
396
483
|
isSynced: true,
|
|
397
484
|
// 标记为已同步
|
|
398
|
-
status: payment.status ||
|
|
485
|
+
status: payment.status || 'active',
|
|
399
486
|
// 如果云端支付项已有时间戳,则保留;否则使用当前时间
|
|
400
487
|
created_at: payment.created_at || currentTime,
|
|
401
488
|
updated_at: payment.updated_at || currentTime
|
|
402
489
|
}));
|
|
490
|
+
|
|
491
|
+
// 重新计算待付金额
|
|
403
492
|
this.recalculateOrderAmount(newOrder);
|
|
404
|
-
this.logInfo(
|
|
493
|
+
this.logInfo('创建订单时包含云端支付项', {
|
|
405
494
|
orderId: params.order_id,
|
|
406
495
|
existPaymentCount: params.existPayment.length,
|
|
407
496
|
totalAmount: newOrder.total_amount,
|
|
408
497
|
expectAmount: newOrder.expect_amount,
|
|
409
|
-
paymentDetails: params.existPayment.map(
|
|
498
|
+
paymentDetails: params.existPayment.map(p => ({
|
|
410
499
|
uuid: p.uuid,
|
|
411
500
|
code: p.code,
|
|
412
501
|
amount: p.amount,
|
|
@@ -416,67 +505,75 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
416
505
|
}))
|
|
417
506
|
});
|
|
418
507
|
}
|
|
508
|
+
|
|
509
|
+
// 🚀 性能监控:记录数据库添加操作耗时
|
|
419
510
|
const dbAddStartTime = Date.now();
|
|
420
|
-
await this.dbManager.add(
|
|
511
|
+
await this.dbManager.add('order', newOrder, true);
|
|
421
512
|
const dbAddDuration = Date.now() - dbAddStartTime;
|
|
422
|
-
this.logInfo(
|
|
423
|
-
operation:
|
|
424
|
-
table:
|
|
513
|
+
this.logInfo('Database add operation completed', {
|
|
514
|
+
operation: 'dbManager.add',
|
|
515
|
+
table: 'order',
|
|
425
516
|
orderUuid: newOrder.uuid,
|
|
426
517
|
orderId: newOrder.order_id,
|
|
427
518
|
duration: `${dbAddDuration}ms`,
|
|
428
|
-
performance: dbAddDuration > 100 ?
|
|
519
|
+
performance: dbAddDuration > 100 ? 'slow' : dbAddDuration > 50 ? 'medium' : 'fast'
|
|
429
520
|
});
|
|
430
521
|
setTimeout(() => {
|
|
431
522
|
this.core.effects.emit(`${this.name}:onOrderAdded`, newOrder);
|
|
432
523
|
}, 0);
|
|
433
524
|
return newOrder;
|
|
525
|
+
// }
|
|
434
526
|
} catch (error) {
|
|
435
|
-
console.error(
|
|
436
|
-
this.logError(
|
|
527
|
+
console.error('[PaymentModule] 创建支付订单失败', error);
|
|
528
|
+
this.logError('createPaymentOrderAsync failed', error, {
|
|
437
529
|
orderId: params.order_id
|
|
438
530
|
});
|
|
439
531
|
throw error;
|
|
440
532
|
}
|
|
441
533
|
}
|
|
534
|
+
|
|
442
535
|
/**
|
|
443
536
|
* 删除支付订单(新方法)
|
|
444
537
|
*/
|
|
445
538
|
async deletePaymentOrderAsync(orderUuid) {
|
|
446
539
|
try {
|
|
447
|
-
const order = await this.dbManager.get(
|
|
540
|
+
const order = await this.dbManager.get('order', orderUuid);
|
|
448
541
|
if (order) {
|
|
449
|
-
await this.dbManager.delete(
|
|
542
|
+
await this.dbManager.delete('order', orderUuid);
|
|
450
543
|
await this.core.effects.emit(`${this.name}:onOrderDeleted`, order);
|
|
451
|
-
console.log("[PaymentModule] 支付订单删除成功:", orderUuid);
|
|
452
544
|
}
|
|
453
545
|
} catch (error) {
|
|
454
|
-
console.error(
|
|
546
|
+
console.error('[PaymentModule] 删除支付订单失败', error);
|
|
455
547
|
throw error;
|
|
456
548
|
}
|
|
457
549
|
}
|
|
550
|
+
|
|
458
551
|
/**
|
|
459
552
|
* 更新订单
|
|
460
553
|
*/
|
|
461
554
|
async updateOrderAsync(orderUuid, params) {
|
|
462
555
|
try {
|
|
463
|
-
const order = await this.dbManager.get(
|
|
556
|
+
const order = await this.dbManager.get('order', orderUuid);
|
|
464
557
|
if (order) {
|
|
465
|
-
const updatedOrder = {
|
|
558
|
+
const updatedOrder = {
|
|
559
|
+
...order,
|
|
560
|
+
...params
|
|
561
|
+
};
|
|
466
562
|
this.recalculateOrderAmount(updatedOrder);
|
|
467
|
-
await this.dbManager.update(
|
|
563
|
+
await this.dbManager.update('order', updatedOrder);
|
|
468
564
|
await this.core.effects.emit(`${this.name}:onOrderUpdated`, updatedOrder);
|
|
469
565
|
await this.core.effects.emit(`${this.name}:onOrderChanged`, {
|
|
470
|
-
action:
|
|
566
|
+
action: 'update',
|
|
471
567
|
order: updatedOrder,
|
|
472
568
|
originalOrder: order
|
|
473
569
|
});
|
|
474
570
|
}
|
|
475
571
|
} catch (error) {
|
|
476
|
-
console.error(
|
|
572
|
+
console.error('[PaymentModule] 更新订单失败', error);
|
|
477
573
|
throw error;
|
|
478
574
|
}
|
|
479
575
|
}
|
|
576
|
+
|
|
480
577
|
/**
|
|
481
578
|
* 基于UUID替换订单ID
|
|
482
579
|
*
|
|
@@ -488,28 +585,35 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
488
585
|
* @returns 更新后的订单对象,如果订单不存在则返回null
|
|
489
586
|
*/
|
|
490
587
|
async replaceOrderIdByUuidAsync(orderUuid, newOrderId) {
|
|
491
|
-
this.logInfo(
|
|
588
|
+
this.logInfo('Starting replaceOrderIdByUuidAsync', {
|
|
492
589
|
orderUuid,
|
|
493
590
|
newOrderId
|
|
494
591
|
});
|
|
495
592
|
try {
|
|
496
|
-
|
|
593
|
+
// 获取现有订单
|
|
594
|
+
const existingOrder = await this.dbManager.get('order', orderUuid);
|
|
497
595
|
if (!existingOrder) {
|
|
498
|
-
this.logWarning(
|
|
596
|
+
this.logWarning('Order not found for UUID replacement', {
|
|
597
|
+
orderUuid
|
|
598
|
+
});
|
|
499
599
|
return null;
|
|
500
600
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
);
|
|
601
|
+
|
|
602
|
+
// 检查新的订单ID是否已经存在
|
|
603
|
+
const allOrders = await this.dbManager.getAll('order');
|
|
604
|
+
const duplicateOrder = allOrders.find(order => String(order.order_id) === String(newOrderId) && order.uuid !== orderUuid);
|
|
505
605
|
if (duplicateOrder) {
|
|
506
|
-
this.logWarning(
|
|
606
|
+
this.logWarning('New order ID already exists', {
|
|
507
607
|
newOrderId,
|
|
508
608
|
existingOrderUuid: duplicateOrder.uuid
|
|
509
609
|
});
|
|
510
610
|
throw new Error(`订单ID ${newOrderId} 已存在`);
|
|
511
611
|
}
|
|
612
|
+
|
|
613
|
+
// 保存原始订单ID用于日志
|
|
512
614
|
const originalOrderId = existingOrder.id;
|
|
615
|
+
|
|
616
|
+
// 更新订单ID
|
|
513
617
|
const updatedOrder = {
|
|
514
618
|
...existingOrder,
|
|
515
619
|
id: newOrderId,
|
|
@@ -520,13 +624,17 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
520
624
|
order_id: newOrderId,
|
|
521
625
|
// 保留原始本地订单ID作为参考
|
|
522
626
|
original_local_order_id: originalOrderId,
|
|
523
|
-
updated_at:
|
|
627
|
+
updated_at: new Date().toISOString()
|
|
524
628
|
}
|
|
525
629
|
};
|
|
526
|
-
|
|
630
|
+
|
|
631
|
+
// 更新到数据库
|
|
632
|
+
await this.dbManager.update('order', updatedOrder);
|
|
633
|
+
|
|
634
|
+
// 触发事件
|
|
527
635
|
await this.core.effects.emit(`${this.name}:onOrderUpdated`, updatedOrder);
|
|
528
636
|
await this.core.effects.emit(`${this.name}:onOrderChanged`, {
|
|
529
|
-
action:
|
|
637
|
+
action: 'order_id_replaced',
|
|
530
638
|
order: updatedOrder,
|
|
531
639
|
originalOrder: existingOrder,
|
|
532
640
|
metadata: {
|
|
@@ -534,22 +642,22 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
534
642
|
newOrderId
|
|
535
643
|
}
|
|
536
644
|
});
|
|
537
|
-
this.logInfo(
|
|
645
|
+
this.logInfo('Order ID replacement completed successfully', {
|
|
538
646
|
orderUuid,
|
|
539
647
|
originalOrderId,
|
|
540
648
|
newOrderId
|
|
541
649
|
});
|
|
542
|
-
console.log(`[PaymentModule] 订单ID替换成功: ${originalOrderId} → ${newOrderId}`);
|
|
543
650
|
return updatedOrder;
|
|
544
651
|
} catch (error) {
|
|
545
|
-
console.error(
|
|
546
|
-
this.logError(
|
|
652
|
+
console.error('[PaymentModule] 替换订单ID失败', error);
|
|
653
|
+
this.logError('replaceOrderIdByUuidAsync failed', error, {
|
|
547
654
|
orderUuid,
|
|
548
655
|
newOrderId
|
|
549
656
|
});
|
|
550
657
|
throw error;
|
|
551
658
|
}
|
|
552
659
|
}
|
|
660
|
+
|
|
553
661
|
/**
|
|
554
662
|
* 获取支付项(新方法)
|
|
555
663
|
*
|
|
@@ -559,15 +667,18 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
559
667
|
*/
|
|
560
668
|
async getPaymentItemsAsync(orderUuid, includeVoided = false) {
|
|
561
669
|
if (!orderUuid) {
|
|
562
|
-
throw new Error(
|
|
670
|
+
throw new Error('orderUuid is required');
|
|
563
671
|
}
|
|
564
672
|
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
565
|
-
const allPayments =
|
|
673
|
+
const allPayments = order?.payment || [];
|
|
566
674
|
if (includeVoided) {
|
|
567
675
|
return allPayments;
|
|
568
676
|
}
|
|
569
|
-
|
|
677
|
+
|
|
678
|
+
// 默认只返回活跃的支付项
|
|
679
|
+
return allPayments.filter(payment => payment.status !== 'voided');
|
|
570
680
|
}
|
|
681
|
+
|
|
571
682
|
/**
|
|
572
683
|
* 获取所有支付项(包括已撤销的)
|
|
573
684
|
*
|
|
@@ -577,47 +688,51 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
577
688
|
async getAllPaymentItemsAsync(orderUuid) {
|
|
578
689
|
return this.getPaymentItemsAsync(orderUuid, true);
|
|
579
690
|
}
|
|
691
|
+
|
|
580
692
|
/**
|
|
581
693
|
* 为某个订单添加支付项(新方法)
|
|
582
694
|
*/
|
|
583
695
|
async addPaymentItemAsync(orderUuid, paymentItem) {
|
|
584
|
-
|
|
585
|
-
this.logInfo("Starting addPaymentItemAsync", {
|
|
696
|
+
this.logInfo('Starting addPaymentItemAsync', {
|
|
586
697
|
orderUuid,
|
|
587
698
|
paymentAmount: paymentItem.amount,
|
|
588
699
|
paymentCode: paymentItem.code,
|
|
589
700
|
orderPaymentType: paymentItem.order_payment_type
|
|
590
701
|
});
|
|
591
702
|
try {
|
|
592
|
-
this.logInfo(
|
|
703
|
+
this.logInfo('准备获取订单', {
|
|
593
704
|
orderUuid
|
|
594
705
|
});
|
|
595
706
|
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
596
|
-
this.logInfo(
|
|
707
|
+
this.logInfo('获取订单信息成功', {
|
|
597
708
|
orderUuid,
|
|
598
709
|
order
|
|
599
710
|
});
|
|
600
711
|
if (!order) {
|
|
601
712
|
throw new Error(`Order not found: ${orderUuid}`);
|
|
602
713
|
}
|
|
603
|
-
|
|
714
|
+
|
|
715
|
+
// 🔒 支付锁检查:如果订单待付金额已经为0,不允许继续添加支付项
|
|
716
|
+
const expectAmount = new _decimal.Decimal(order.expect_amount);
|
|
604
717
|
const paidDepositAmount = order.payment.reduce((sum, payment) => {
|
|
605
|
-
if (payment.order_payment_type ===
|
|
606
|
-
return sum.plus(new
|
|
718
|
+
if (payment.order_payment_type === 'deposit' && payment.status !== 'voided') {
|
|
719
|
+
return sum.plus(new _decimal.Decimal(payment.amount));
|
|
607
720
|
}
|
|
608
721
|
return sum;
|
|
609
|
-
}, new
|
|
610
|
-
const expectedDepositAmount = new
|
|
722
|
+
}, new _decimal.Decimal(0));
|
|
723
|
+
const expectedDepositAmount = new _decimal.Decimal(order.deposit_amount || '0').sub(paidDepositAmount);
|
|
724
|
+
|
|
725
|
+
// 有一种特殊情况,订单金额为 0,但是定金金额>0,且此时是定金状态的,允许添加支付项
|
|
611
726
|
if (expectAmount.lte(0) && expectedDepositAmount.eq(0)) {
|
|
612
727
|
const warningMessage = `订单 ${orderUuid} 待付金额已为0,不允许添加新的支付项`;
|
|
613
|
-
console.warn(
|
|
728
|
+
console.warn('[PaymentModule] Payment lock triggered:', {
|
|
614
729
|
orderUuid,
|
|
615
730
|
expectAmount: order.expect_amount,
|
|
616
731
|
attemptedPaymentAmount: paymentItem.amount,
|
|
617
732
|
attemptedPaymentCode: paymentItem.code,
|
|
618
|
-
reason:
|
|
733
|
+
reason: 'Order already fully paid'
|
|
619
734
|
});
|
|
620
|
-
this.logError(
|
|
735
|
+
this.logError('addPaymentItemAsync blocked by payment lock', new Error(warningMessage), {
|
|
621
736
|
orderUuid,
|
|
622
737
|
expectAmount: order.expect_amount,
|
|
623
738
|
paymentItem
|
|
@@ -625,12 +740,12 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
625
740
|
throw new Error(warningMessage);
|
|
626
741
|
}
|
|
627
742
|
let paymentUuid;
|
|
628
|
-
if (
|
|
743
|
+
if (paymentItem.metadata?.unique_payment_number) {
|
|
629
744
|
paymentUuid = paymentItem.metadata.unique_payment_number;
|
|
630
745
|
} else {
|
|
631
|
-
paymentUuid = (0,
|
|
746
|
+
paymentUuid = (0, _utils.getUniqueId)('payment_');
|
|
632
747
|
}
|
|
633
|
-
const currentTime = formatDateTime(
|
|
748
|
+
const currentTime = formatDateTime(new Date());
|
|
634
749
|
const newPaymentItem = {
|
|
635
750
|
uuid: paymentUuid,
|
|
636
751
|
custom_payment_id: paymentItem.custom_payment_id || 0,
|
|
@@ -638,116 +753,121 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
638
753
|
code: paymentItem.code,
|
|
639
754
|
type: paymentItem.type,
|
|
640
755
|
amount: formatAmount(paymentItem.amount),
|
|
641
|
-
voucher_id: paymentItem.voucher_id ||
|
|
642
|
-
rounding_amount: paymentItem.rounding_amount ||
|
|
756
|
+
voucher_id: paymentItem.voucher_id || '',
|
|
757
|
+
rounding_amount: paymentItem.rounding_amount || '0.00',
|
|
643
758
|
service_charge: paymentItem.service_charge,
|
|
644
|
-
status:
|
|
759
|
+
status: 'active',
|
|
645
760
|
// 新支付项默认为活跃状态
|
|
646
|
-
order_payment_type: paymentItem.order_payment_type ||
|
|
761
|
+
order_payment_type: paymentItem.order_payment_type || 'normal',
|
|
647
762
|
// 默认为正常支付
|
|
648
763
|
created_at: currentTime,
|
|
649
764
|
// 创建时间
|
|
650
765
|
updated_at: currentTime,
|
|
651
766
|
// 更新时间
|
|
652
|
-
wallet_pass_usage_unit: paymentItem
|
|
653
|
-
wallet_pass_use_value: paymentItem
|
|
767
|
+
wallet_pass_usage_unit: paymentItem?.wallet_pass_usage_unit,
|
|
768
|
+
wallet_pass_use_value: paymentItem?.wallet_pass_use_value,
|
|
654
769
|
metadata: {
|
|
655
770
|
...paymentItem.metadata,
|
|
656
771
|
// 保留传入的所有 metadata 字段
|
|
657
|
-
unique_payment_number: paymentUuid
|
|
658
|
-
// 设置唯一支付号为支付项的 uuid
|
|
772
|
+
unique_payment_number: paymentUuid // 设置唯一支付号为支付项的 uuid
|
|
659
773
|
}
|
|
660
774
|
};
|
|
661
775
|
order.payment.push(newPaymentItem);
|
|
662
776
|
this.recalculateOrderAmount(order);
|
|
663
|
-
this.logInfo(
|
|
777
|
+
this.logInfo('开始更新订单支付项', {
|
|
664
778
|
orderUuid,
|
|
665
779
|
order
|
|
666
780
|
});
|
|
667
|
-
await this.dbManager.update(
|
|
668
|
-
this.logInfo(
|
|
781
|
+
await this.dbManager.update('order', order, true);
|
|
782
|
+
this.logInfo('更新订单支付项完成', {
|
|
669
783
|
orderUuid
|
|
670
784
|
});
|
|
671
785
|
this.core.effects.emit(`${this.name}:onPaymentAdded`, {
|
|
672
786
|
orderUuid,
|
|
673
787
|
payment: newPaymentItem
|
|
674
788
|
});
|
|
675
|
-
this.logInfo(
|
|
789
|
+
this.logInfo('addPaymentItemAsync completed successfully', {
|
|
676
790
|
orderUuid,
|
|
677
791
|
paymentUuid: newPaymentItem.uuid,
|
|
678
|
-
uniquePaymentNumber:
|
|
792
|
+
uniquePaymentNumber: newPaymentItem.metadata?.unique_payment_number,
|
|
679
793
|
newExpectAmount: order.expect_amount,
|
|
680
794
|
paymentAmount: newPaymentItem.amount,
|
|
681
795
|
paymentCode: newPaymentItem.code,
|
|
682
796
|
orderPaymentType: newPaymentItem.order_payment_type,
|
|
683
797
|
metadataFields: Object.keys(newPaymentItem.metadata || {}),
|
|
684
798
|
// 现金支付找零信息
|
|
685
|
-
actualPaidAmount:
|
|
686
|
-
changeGivenAmount:
|
|
799
|
+
actualPaidAmount: newPaymentItem.metadata?.actual_paid_amount,
|
|
800
|
+
changeGivenAmount: newPaymentItem.metadata?.change_given_amount
|
|
687
801
|
});
|
|
688
802
|
} catch (error) {
|
|
689
|
-
console.error(
|
|
690
|
-
this.logError(
|
|
803
|
+
console.error('[PaymentModule] 添加支付项失败', error);
|
|
804
|
+
this.logError('addPaymentItemAsync failed', error, {
|
|
691
805
|
orderUuid,
|
|
692
806
|
paymentItem
|
|
693
807
|
});
|
|
694
808
|
throw error;
|
|
695
809
|
}
|
|
696
810
|
}
|
|
811
|
+
|
|
697
812
|
/**
|
|
698
813
|
* 删除一个支付项 - 标记删除而非物理删除
|
|
699
814
|
*/
|
|
700
815
|
async deletePaymentAsync(orderUuid, paymentUuid) {
|
|
701
|
-
this.logInfo(
|
|
816
|
+
this.logInfo('Starting deletePaymentAsync (mark as voided)', {
|
|
817
|
+
orderUuid,
|
|
818
|
+
paymentUuid
|
|
819
|
+
});
|
|
702
820
|
try {
|
|
703
|
-
const order = await this.dbManager.get(
|
|
821
|
+
const order = await this.dbManager.get('order', orderUuid);
|
|
704
822
|
if (!order) {
|
|
705
|
-
throw new Error(
|
|
823
|
+
throw new Error('订单不存在');
|
|
706
824
|
}
|
|
707
|
-
const paymentItem = order.payment.find(
|
|
708
|
-
(payment) => payment.uuid === paymentUuid
|
|
709
|
-
);
|
|
825
|
+
const paymentItem = order.payment.find(payment => payment.uuid === paymentUuid);
|
|
710
826
|
if (!paymentItem) {
|
|
711
827
|
throw new Error(`支付项不存在: ${paymentUuid}`);
|
|
712
828
|
}
|
|
713
|
-
|
|
829
|
+
|
|
830
|
+
// 检查是否已经被删除(撤销)
|
|
831
|
+
if (paymentItem.status === 'voided') {
|
|
714
832
|
console.warn(`[PaymentModule] 支付项 ${paymentUuid} 已经被删除,跳过操作`);
|
|
715
833
|
return;
|
|
716
834
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
paymentItem.
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
});
|
|
835
|
+
|
|
836
|
+
// 标记删除而不是物理删除
|
|
837
|
+
paymentItem.status = 'voided';
|
|
838
|
+
paymentItem.origin_amount = paymentItem.amount; // 保存原始金额
|
|
839
|
+
paymentItem.amount = '0.00'; // 将金额设为0,不参与订单金额计算
|
|
840
|
+
|
|
841
|
+
// 重新计算待付金额
|
|
725
842
|
this.recalculateOrderAmount(order);
|
|
726
|
-
|
|
843
|
+
|
|
844
|
+
// 更新到 IndexDB
|
|
845
|
+
await this.dbManager.update('order', order);
|
|
727
846
|
await this.core.effects.emit(`${this.name}:onPaymentDeleted`, {
|
|
728
847
|
order,
|
|
729
|
-
paymentItem
|
|
848
|
+
paymentItem: paymentItem
|
|
730
849
|
});
|
|
731
850
|
await this.core.effects.emit(`${this.name}:onOrderChanged`, {
|
|
732
|
-
action:
|
|
851
|
+
action: 'payment_delete',
|
|
733
852
|
order,
|
|
734
|
-
paymentItem
|
|
853
|
+
paymentItem: paymentItem
|
|
735
854
|
});
|
|
736
|
-
this.logInfo(
|
|
855
|
+
this.logInfo('deletePaymentAsync completed successfully (marked as voided)', {
|
|
737
856
|
orderUuid,
|
|
738
857
|
paymentUuid,
|
|
739
858
|
originalAmount: paymentItem.origin_amount,
|
|
740
859
|
newExpectAmount: order.expect_amount
|
|
741
860
|
});
|
|
742
861
|
} catch (error) {
|
|
743
|
-
console.error(
|
|
744
|
-
this.logError(
|
|
862
|
+
console.error('[PaymentModule] 删除支付项失败', error);
|
|
863
|
+
this.logError('deletePaymentAsync failed', error, {
|
|
745
864
|
orderUuid,
|
|
746
865
|
paymentUuid
|
|
747
866
|
});
|
|
748
867
|
throw error;
|
|
749
868
|
}
|
|
750
869
|
}
|
|
870
|
+
|
|
751
871
|
/**
|
|
752
872
|
* 批量更新代金券类支付项(覆盖更新)
|
|
753
873
|
*
|
|
@@ -756,12 +876,16 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
756
876
|
*/
|
|
757
877
|
async updateVoucherPaymentItemsAsync(orderUuid, voucherPaymentItems) {
|
|
758
878
|
return this.runVoucherUpdateLocked(orderUuid, async () => {
|
|
759
|
-
const {
|
|
760
|
-
|
|
879
|
+
const {
|
|
880
|
+
items: normalizedVoucherItems,
|
|
881
|
+
originalCount,
|
|
882
|
+
normalizedCount
|
|
883
|
+
} = this.normalizeVoucherPaymentItems(voucherPaymentItems);
|
|
884
|
+
this.logInfo('Starting updateVoucherPaymentItemsAsync', {
|
|
761
885
|
orderUuid,
|
|
762
886
|
originalVoucherCount: originalCount,
|
|
763
887
|
normalizedVoucherCount: normalizedCount,
|
|
764
|
-
voucherItems: normalizedVoucherItems.map(
|
|
888
|
+
voucherItems: normalizedVoucherItems.map(item => ({
|
|
765
889
|
code: item.code,
|
|
766
890
|
amount: item.amount,
|
|
767
891
|
voucher_id: item.voucher_id,
|
|
@@ -769,7 +893,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
769
893
|
}))
|
|
770
894
|
});
|
|
771
895
|
if (originalCount !== normalizedCount) {
|
|
772
|
-
console.warn(
|
|
896
|
+
console.warn('[PaymentModule] voucherPaymentItems detected duplicates (deduped by voucher_id + order_payment_type)', {
|
|
773
897
|
orderUuid,
|
|
774
898
|
originalCount,
|
|
775
899
|
normalizedCount
|
|
@@ -780,71 +904,52 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
780
904
|
if (!order) {
|
|
781
905
|
throw new Error(`订单不存在: ${orderUuid}`);
|
|
782
906
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
existingVoucherCount: existingVoucherItems.length,
|
|
789
|
-
existingItems: existingVoucherItems.map((item) => ({
|
|
790
|
-
uuid: item.uuid,
|
|
791
|
-
code: item.code,
|
|
792
|
-
amount: item.amount,
|
|
793
|
-
voucher_id: item.voucher_id,
|
|
794
|
-
isSynced: item.isSynced
|
|
795
|
-
}))
|
|
796
|
-
});
|
|
907
|
+
|
|
908
|
+
// 1. 查找所有现有的代金券类支付项(带 voucher_id 且状态不是 voided)并且还没有同步给后端
|
|
909
|
+
// 如果同步给了后端的voucher 不允许删除
|
|
910
|
+
const existingVoucherItems = order.payment.filter(payment => payment.voucher_id && payment.status !== 'voided' && !payment.isSynced);
|
|
911
|
+
// 2. 删除所有现有的代金券支付项(仅删除未同步的)
|
|
797
912
|
for (const voucherItem of existingVoucherItems) {
|
|
798
|
-
console.log(`[PaymentModule] 删除现有代金券支付项: ${voucherItem.uuid}`);
|
|
799
913
|
await this.deletePaymentAsync(orderUuid, voucherItem.uuid);
|
|
800
914
|
}
|
|
915
|
+
|
|
916
|
+
// 3. 添加新的代金券支付项(幂等:如果已存在同 voucher_id + order_payment_type 的 active 项则跳过)
|
|
801
917
|
const orderAfterDelete = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
802
918
|
if (!orderAfterDelete) {
|
|
803
919
|
throw new Error(`订单不存在: ${orderUuid}`);
|
|
804
920
|
}
|
|
805
|
-
const existingActiveVoucherKeys = new Set(
|
|
806
|
-
orderAfterDelete.payment.filter((p) => p.voucher_id && p.status !== "voided" && !p.isSynced).map((p) => `${p.voucher_id}|${p.order_payment_type || "normal"}`)
|
|
807
|
-
);
|
|
808
|
-
console.log("[PaymentModule] 添加新的代金券支付项:", {
|
|
809
|
-
orderUuid,
|
|
810
|
-
newItemCount: normalizedVoucherItems.length
|
|
811
|
-
});
|
|
921
|
+
const existingActiveVoucherKeys = new Set(orderAfterDelete.payment.filter(p => p.voucher_id && p.status !== 'voided' && !p.isSynced).map(p => `${p.voucher_id}|${p.order_payment_type || 'normal'}`));
|
|
812
922
|
for (const voucherItem of normalizedVoucherItems) {
|
|
813
|
-
const orderPaymentType = voucherItem.order_payment_type ||
|
|
923
|
+
const orderPaymentType = voucherItem.order_payment_type || 'normal';
|
|
814
924
|
const key = `${voucherItem.voucher_id}|${orderPaymentType}`;
|
|
815
925
|
if (existingActiveVoucherKeys.has(key)) {
|
|
816
|
-
console.warn(
|
|
926
|
+
console.warn('[PaymentModule] Skip adding voucher payment item because it already exists (active)', {
|
|
817
927
|
orderUuid,
|
|
818
928
|
voucher_id: voucherItem.voucher_id,
|
|
819
929
|
order_payment_type: orderPaymentType
|
|
820
930
|
});
|
|
821
931
|
continue;
|
|
822
932
|
}
|
|
823
|
-
console.log(`[PaymentModule] 添加代金券支付项:`, {
|
|
824
|
-
code: voucherItem.code,
|
|
825
|
-
amount: voucherItem.amount,
|
|
826
|
-
voucher_id: voucherItem.voucher_id,
|
|
827
|
-
order_payment_type: orderPaymentType
|
|
828
|
-
});
|
|
829
933
|
await this.addPaymentItemAsync(orderUuid, voucherItem);
|
|
830
934
|
existingActiveVoucherKeys.add(key);
|
|
831
935
|
}
|
|
936
|
+
|
|
937
|
+
// 4. 触发支付项更新事件
|
|
832
938
|
const updatedOrder = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
833
939
|
await this.core.effects.emit(`${this.name}:onPaymentAdded`, {
|
|
834
940
|
orderUuid,
|
|
835
941
|
order: updatedOrder,
|
|
836
|
-
payment: null
|
|
837
|
-
// 批量操作不提供单个支付项
|
|
942
|
+
payment: null // 批量操作不提供单个支付项
|
|
838
943
|
});
|
|
839
|
-
this.logInfo(
|
|
944
|
+
this.logInfo('updateVoucherPaymentItemsAsync completed successfully', {
|
|
840
945
|
orderUuid,
|
|
841
946
|
removedVoucherCount: existingVoucherItems.length,
|
|
842
947
|
addedVoucherCount: normalizedVoucherItems.length,
|
|
843
|
-
finalExpectAmount: updatedOrder
|
|
948
|
+
finalExpectAmount: updatedOrder?.expect_amount
|
|
844
949
|
});
|
|
845
950
|
} catch (error) {
|
|
846
|
-
console.error(
|
|
847
|
-
this.logError(
|
|
951
|
+
console.error('[PaymentModule] 批量更新代金券支付项失败:', error);
|
|
952
|
+
this.logError('updateVoucherPaymentItemsAsync failed', error, {
|
|
848
953
|
orderUuid,
|
|
849
954
|
voucherPaymentItems
|
|
850
955
|
});
|
|
@@ -852,79 +957,94 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
852
957
|
}
|
|
853
958
|
});
|
|
854
959
|
}
|
|
960
|
+
|
|
855
961
|
/**
|
|
856
962
|
* 更新一个支付项
|
|
857
963
|
*/
|
|
858
964
|
async updatePaymentAsync(orderUuid, paymentUuid, params) {
|
|
859
965
|
try {
|
|
860
|
-
const order = await this.dbManager.get(
|
|
966
|
+
const order = await this.dbManager.get('order', orderUuid);
|
|
861
967
|
if (!order) {
|
|
862
|
-
throw new Error(
|
|
968
|
+
throw new Error('订单不存在');
|
|
863
969
|
}
|
|
864
|
-
const paymentItem = order.payment.find(
|
|
865
|
-
(payment) => payment.uuid === paymentUuid
|
|
866
|
-
);
|
|
970
|
+
const paymentItem = order.payment.find(payment => payment.uuid === paymentUuid);
|
|
867
971
|
if (paymentItem) {
|
|
868
|
-
|
|
869
|
-
|
|
972
|
+
// 如果更新参数中包含 amount,先格式化
|
|
973
|
+
const formattedParams = {
|
|
974
|
+
...params
|
|
975
|
+
};
|
|
976
|
+
if ('amount' in formattedParams && formattedParams.amount !== undefined) {
|
|
870
977
|
formattedParams.amount = formatAmount(formattedParams.amount);
|
|
871
978
|
}
|
|
872
979
|
Object.assign(paymentItem, formattedParams);
|
|
980
|
+
|
|
981
|
+
// 重新计算待付金额
|
|
873
982
|
this.recalculateOrderAmount(order);
|
|
874
|
-
|
|
983
|
+
|
|
984
|
+
// 更新到 IndexDB
|
|
985
|
+
await this.dbManager.update('order', order);
|
|
875
986
|
await this.core.effects.emit(`${this.name}:onPaymentUpdated`, {
|
|
876
987
|
order,
|
|
877
988
|
paymentItem
|
|
878
989
|
});
|
|
879
990
|
await this.core.effects.emit(`${this.name}:onOrderChanged`, {
|
|
880
|
-
action:
|
|
991
|
+
action: 'payment_update',
|
|
881
992
|
order,
|
|
882
993
|
paymentItem
|
|
883
994
|
});
|
|
884
995
|
}
|
|
885
996
|
} catch (error) {
|
|
886
|
-
console.error(
|
|
997
|
+
console.error('[PaymentModule] 更新支付项失败', error);
|
|
887
998
|
throw error;
|
|
888
999
|
}
|
|
889
1000
|
}
|
|
1001
|
+
|
|
890
1002
|
/**
|
|
891
1003
|
* 提交支付
|
|
892
1004
|
*/
|
|
893
1005
|
async submitPayAsync(orderUuid) {
|
|
894
|
-
this.logInfo(
|
|
1006
|
+
this.logInfo('Starting submitPayAsync', {
|
|
1007
|
+
orderUuid
|
|
1008
|
+
});
|
|
895
1009
|
try {
|
|
896
1010
|
let orderToSubmit;
|
|
897
1011
|
if (orderUuid) {
|
|
898
|
-
const order = await this.dbManager.get(
|
|
1012
|
+
const order = await this.dbManager.get('order', orderUuid);
|
|
899
1013
|
orderToSubmit = order ? [order] : [];
|
|
900
1014
|
} else {
|
|
901
|
-
const allOrders = await this.dbManager.getAll(
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
);
|
|
1015
|
+
const allOrders = await this.dbManager.getAll('order');
|
|
1016
|
+
// 包括正在处理中的订单和部分支付的订单(可能添加了新的支付项)
|
|
1017
|
+
orderToSubmit = allOrders.filter(order => order.payment_status === _types.PaymentStatus.Processing || order.payment_status === _types.PaymentStatus.PartiallyPaid);
|
|
905
1018
|
}
|
|
906
1019
|
for (const order of orderToSubmit) {
|
|
907
1020
|
await this.submitSingleOrderPayment(order);
|
|
908
1021
|
}
|
|
909
|
-
const result = {
|
|
910
|
-
|
|
1022
|
+
const result = {
|
|
1023
|
+
status: 'success'
|
|
1024
|
+
};
|
|
1025
|
+
this.logInfo('submitPayAsync completed', {
|
|
911
1026
|
result: result.status,
|
|
912
1027
|
processedOrdersCount: orderToSubmit.length
|
|
913
1028
|
});
|
|
914
1029
|
return result;
|
|
915
1030
|
} catch (error) {
|
|
916
|
-
console.error(
|
|
917
|
-
this.logError(
|
|
918
|
-
|
|
1031
|
+
console.error('[PaymentModule] 提交支付失败', error);
|
|
1032
|
+
this.logError('submitPayAsync failed', error, {
|
|
1033
|
+
orderUuid
|
|
1034
|
+
});
|
|
1035
|
+
return {
|
|
1036
|
+
status: 'failed'
|
|
1037
|
+
};
|
|
919
1038
|
}
|
|
920
1039
|
}
|
|
1040
|
+
|
|
921
1041
|
/**
|
|
922
1042
|
* 提交单个订单的支付(推送到任务队列)
|
|
923
1043
|
*/
|
|
924
1044
|
async submitSingleOrderPayment(order) {
|
|
925
1045
|
try {
|
|
926
1046
|
const paymentData = {
|
|
927
|
-
payments: order.payment.map(
|
|
1047
|
+
payments: order.payment.map(payment => ({
|
|
928
1048
|
uuid: payment.uuid,
|
|
929
1049
|
amount: payment.amount,
|
|
930
1050
|
code: payment.code,
|
|
@@ -936,37 +1056,41 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
936
1056
|
rounding_amount: payment.rounding_amount,
|
|
937
1057
|
service_charge: payment.service_charge
|
|
938
1058
|
})),
|
|
939
|
-
payment_status:
|
|
1059
|
+
payment_status: 'pending'
|
|
940
1060
|
};
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
);
|
|
945
|
-
|
|
1061
|
+
|
|
1062
|
+
// 计算总支付金额
|
|
1063
|
+
const totalPaidAmount = paymentData.payments.reduce((sum, payment) => sum.plus(payment.amount), new _decimal.Decimal(0));
|
|
1064
|
+
const orderTotalAmount = new _decimal.Decimal(order.total_amount);
|
|
1065
|
+
|
|
1066
|
+
// 根据支付金额判断订单状态
|
|
946
1067
|
if (totalPaidAmount.gte(orderTotalAmount)) {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
`[PaymentModule] 订单 ${order.uuid} 支付完成,金额: ${totalPaidAmount.toString()}/${orderTotalAmount.toString()}`
|
|
950
|
-
);
|
|
1068
|
+
// 支付金额足够,标记为已完成
|
|
1069
|
+
order.payment_status = _types.PaymentStatus.Finished;
|
|
951
1070
|
} else {
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
`[PaymentModule] 订单 ${order.uuid} 部分支付,金额: ${totalPaidAmount.toString()}/${orderTotalAmount.toString()}`
|
|
955
|
-
);
|
|
1071
|
+
// 支付金额不足,标记为部分支付
|
|
1072
|
+
order.payment_status = _types.PaymentStatus.PartiallyPaid;
|
|
956
1073
|
}
|
|
957
|
-
|
|
958
|
-
|
|
1074
|
+
|
|
1075
|
+
// 给后端标记一下是全部支付(paid)还是部分支付
|
|
1076
|
+
paymentData.payment_status = order.payment_status === _types.PaymentStatus.Finished ? 'paid' : 'partially_paid';
|
|
1077
|
+
|
|
1078
|
+
// 更新订单状态到数据库
|
|
1079
|
+
await this.dbManager.update('order', order);
|
|
1080
|
+
|
|
1081
|
+
// 检查支付列表是否为空
|
|
959
1082
|
if (paymentData.payments.length === 0) {
|
|
960
|
-
|
|
961
|
-
this.logWarning("Empty payment list", {
|
|
1083
|
+
this.logWarning('Empty payment list', {
|
|
962
1084
|
orderUuid: order.uuid,
|
|
963
1085
|
orderId: order.order_id
|
|
964
1086
|
});
|
|
965
1087
|
return;
|
|
966
1088
|
}
|
|
1089
|
+
|
|
1090
|
+
// 触发支付提交事件
|
|
967
1091
|
await this.core.effects.emit(`${this.name}:onPaymentSubmitted`, order);
|
|
968
1092
|
await this.core.effects.emit(`${this.name}:onOrderChanged`, {
|
|
969
|
-
action:
|
|
1093
|
+
action: 'submit',
|
|
970
1094
|
order
|
|
971
1095
|
});
|
|
972
1096
|
} catch (error) {
|
|
@@ -974,168 +1098,163 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
974
1098
|
throw error;
|
|
975
1099
|
}
|
|
976
1100
|
}
|
|
1101
|
+
|
|
977
1102
|
/**
|
|
978
1103
|
* 获取订单剩余待付金额
|
|
979
1104
|
*/
|
|
980
1105
|
async getRemainingOrderAmountAsync(orderUuid) {
|
|
981
1106
|
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
982
1107
|
if (!order) {
|
|
983
|
-
throw new Error(
|
|
1108
|
+
throw new Error('订单不存在');
|
|
984
1109
|
}
|
|
985
|
-
return new
|
|
1110
|
+
return new _decimal.Decimal(order.expect_amount).toNumber();
|
|
986
1111
|
}
|
|
1112
|
+
|
|
987
1113
|
/**
|
|
988
1114
|
* 在比如现金支付界面的地方,用户输入了一个金额,在下方显示剩余多少金额,通过此方法获取
|
|
989
1115
|
*/
|
|
990
1116
|
async getRemainingOrderAmountWithInputAsync(inputAmount, orderUuid) {
|
|
991
1117
|
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
992
1118
|
if (!order) {
|
|
993
|
-
throw new Error(
|
|
1119
|
+
throw new Error('订单不存在');
|
|
994
1120
|
}
|
|
995
|
-
|
|
996
|
-
|
|
1121
|
+
|
|
1122
|
+
// 对输入金额做保护,确保是有效的数字
|
|
1123
|
+
if (inputAmount === null || inputAmount === undefined) {
|
|
1124
|
+
// 如果输入为空,返回原始的待付金额
|
|
1125
|
+
return new _decimal.Decimal(order.expect_amount).toNumber();
|
|
997
1126
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1127
|
+
|
|
1128
|
+
// 处理字符串类型的输入
|
|
1129
|
+
if (typeof inputAmount === 'string') {
|
|
1130
|
+
if (inputAmount.trim() === '') {
|
|
1131
|
+
// 如果输入为空字符串,返回原始的待付金额
|
|
1132
|
+
return new _decimal.Decimal(order.expect_amount).toNumber();
|
|
1001
1133
|
}
|
|
1002
1134
|
}
|
|
1003
|
-
|
|
1135
|
+
|
|
1136
|
+
// 处理数字类型的输入
|
|
1137
|
+
if (typeof inputAmount === 'number') {
|
|
1004
1138
|
if (isNaN(inputAmount) || !isFinite(inputAmount)) {
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
);
|
|
1008
|
-
return new import_decimal.Decimal(order.expect_amount).toNumber();
|
|
1139
|
+
// 如果输入是 NaN 或无穷大,返回原始的待付金额
|
|
1140
|
+
console.warn(`[PaymentModule] 输入金额不是有效数字: ${inputAmount},返回原始待付金额`);
|
|
1141
|
+
return new _decimal.Decimal(order.expect_amount).toNumber();
|
|
1009
1142
|
}
|
|
1010
1143
|
}
|
|
1011
1144
|
try {
|
|
1012
|
-
const inputDecimal = new
|
|
1013
|
-
return new
|
|
1145
|
+
const inputDecimal = new _decimal.Decimal(inputAmount);
|
|
1146
|
+
return new _decimal.Decimal(order.expect_amount).minus(inputDecimal).toNumber();
|
|
1014
1147
|
} catch (error) {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
);
|
|
1018
|
-
return new import_decimal.Decimal(order.expect_amount).toNumber();
|
|
1148
|
+
// 如果输入不是有效的数字,返回原始的待付金额
|
|
1149
|
+
console.warn(`[PaymentModule] 输入金额格式无效: ${inputAmount},返回原始待付金额`);
|
|
1150
|
+
return new _decimal.Decimal(order.expect_amount).toNumber();
|
|
1019
1151
|
}
|
|
1020
1152
|
}
|
|
1153
|
+
|
|
1021
1154
|
/**
|
|
1022
1155
|
* 重新计算订单金额
|
|
1023
1156
|
*/
|
|
1024
1157
|
recalculateOrderAmount(order) {
|
|
1025
|
-
const totalAmount = new
|
|
1026
|
-
const paidAmount = order.payment.reduce(
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
return sum;
|
|
1031
|
-
}
|
|
1032
|
-
const paymentAmount = new import_decimal.Decimal(payment.amount || 0);
|
|
1033
|
-
const roundingAmount = new import_decimal.Decimal(payment.rounding_amount || 0);
|
|
1034
|
-
const effectiveAmount = paymentAmount.minus(roundingAmount);
|
|
1035
|
-
return sum.plus(effectiveAmount);
|
|
1036
|
-
} catch (error) {
|
|
1037
|
-
console.warn(`[PaymentModule] 无效的支付金额: amount=${payment.amount}, rounding_amount=${payment.rounding_amount},跳过计算`);
|
|
1158
|
+
const totalAmount = new _decimal.Decimal(order.total_amount);
|
|
1159
|
+
const paidAmount = order.payment.reduce((sum, payment) => {
|
|
1160
|
+
try {
|
|
1161
|
+
// 忽略已撤销的支付项
|
|
1162
|
+
if (payment.status === 'voided') {
|
|
1038
1163
|
return sum;
|
|
1039
1164
|
}
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
})),
|
|
1058
|
-
说明: "有效支付金额包含抹零计算(amount + |rounding_amount|)"
|
|
1059
|
-
});
|
|
1165
|
+
|
|
1166
|
+
// 计算有效支付金额:支付金额 + 抹零金额的绝对值
|
|
1167
|
+
// 当 rounding_amount 为负数时,表示抹掉的金额,按绝对值计算有效支付
|
|
1168
|
+
// 例如:amount=15, rounding_amount=-0.2,有效支付=15.2(抹掉0.2元零头)
|
|
1169
|
+
// 例2:amount=15,rounding_amount=0.2,有效支付 14.8
|
|
1170
|
+
const paymentAmount = new _decimal.Decimal(payment.amount || 0);
|
|
1171
|
+
const roundingAmount = new _decimal.Decimal(payment.rounding_amount || 0);
|
|
1172
|
+
const effectiveAmount = paymentAmount.minus(roundingAmount);
|
|
1173
|
+
return sum.plus(effectiveAmount);
|
|
1174
|
+
} catch (error) {
|
|
1175
|
+
console.warn(`[PaymentModule] 无效的支付金额: amount=${payment.amount}, rounding_amount=${payment.rounding_amount},跳过计算`);
|
|
1176
|
+
return sum;
|
|
1177
|
+
}
|
|
1178
|
+
}, new _decimal.Decimal(0));
|
|
1179
|
+
// 如果是定金模式,则使用deposit_amount 去减已付款金额
|
|
1180
|
+
const remainingAmount = order.is_deposit === 1 ? new _decimal.Decimal(order.deposit_amount).minus(paidAmount) : totalAmount.minus(paidAmount);
|
|
1181
|
+
order.expect_amount = _decimal.Decimal.max(0, remainingAmount).toFixed(2);
|
|
1060
1182
|
}
|
|
1183
|
+
|
|
1061
1184
|
/**
|
|
1062
1185
|
* 获取现金支付方式
|
|
1063
1186
|
*/
|
|
1064
1187
|
async getCashPaymentMethod() {
|
|
1065
1188
|
try {
|
|
1066
|
-
const payMethods = await this.dbManager.getAll(
|
|
1067
|
-
return payMethods.find(
|
|
1068
|
-
(method) => method.code === import_types.PaymentMethodType.Cash
|
|
1069
|
-
) || null;
|
|
1189
|
+
const payMethods = await this.dbManager.getAll('pay_method');
|
|
1190
|
+
return payMethods.find(method => method.code === _types.PaymentMethodType.Cash) || null;
|
|
1070
1191
|
} catch (error) {
|
|
1071
|
-
console.error(
|
|
1192
|
+
console.error('[PaymentModule] 获取现金支付方式失败', error);
|
|
1072
1193
|
return null;
|
|
1073
1194
|
}
|
|
1074
1195
|
}
|
|
1196
|
+
|
|
1075
1197
|
/**
|
|
1076
1198
|
* 获取Eftpos支付方式
|
|
1077
1199
|
*/
|
|
1078
1200
|
async getEftposPaymentMethod() {
|
|
1079
1201
|
try {
|
|
1080
|
-
const payMethods = await this.dbManager.getAll(
|
|
1081
|
-
return payMethods.find(
|
|
1082
|
-
(method) => method.code === import_types.PaymentMethodType.Eftpos
|
|
1083
|
-
) || null;
|
|
1202
|
+
const payMethods = await this.dbManager.getAll('pay_method');
|
|
1203
|
+
return payMethods.find(method => method.code === _types.PaymentMethodType.Eftpos) || null;
|
|
1084
1204
|
} catch (error) {
|
|
1085
|
-
console.error(
|
|
1205
|
+
console.error('[PaymentModule] 获取Eftpos支付方式失败', error);
|
|
1086
1206
|
return null;
|
|
1087
1207
|
}
|
|
1088
1208
|
}
|
|
1209
|
+
|
|
1089
1210
|
/**
|
|
1090
1211
|
* 获取钱包支付方式
|
|
1091
1212
|
*/
|
|
1092
1213
|
async getWalletPaymentMethod() {
|
|
1093
1214
|
try {
|
|
1094
|
-
const payMethods = await this.dbManager.getAll(
|
|
1095
|
-
return payMethods.find(
|
|
1096
|
-
(method) => method.code === import_types.PaymentMethodType.Wallet
|
|
1097
|
-
) || null;
|
|
1215
|
+
const payMethods = await this.dbManager.getAll('pay_method');
|
|
1216
|
+
return payMethods.find(method => method.code === _types.PaymentMethodType.Wallet) || null;
|
|
1098
1217
|
} catch (error) {
|
|
1099
|
-
console.error(
|
|
1218
|
+
console.error('[PaymentModule] 获取钱包支付方式失败', error);
|
|
1100
1219
|
return null;
|
|
1101
1220
|
}
|
|
1102
1221
|
}
|
|
1222
|
+
|
|
1103
1223
|
/**
|
|
1104
1224
|
* 确保支付模块所需的数据库表已创建
|
|
1105
1225
|
*/
|
|
1106
1226
|
async ensurePaymentTables() {
|
|
1107
1227
|
try {
|
|
1108
|
-
|
|
1228
|
+
// 尝试访问 pay_method 表,如果不存在会抛出错误
|
|
1229
|
+
await this.dbManager.getAll('pay_method');
|
|
1109
1230
|
} catch (error) {
|
|
1110
|
-
console.warn(
|
|
1111
|
-
"[PaymentModule] pay_method 表不存在,请在数据库配置中添加以下配置:"
|
|
1112
|
-
);
|
|
1231
|
+
console.warn('[PaymentModule] pay_method 表不存在,请在数据库配置中添加以下配置:');
|
|
1113
1232
|
console.warn('{ name: "pay_method", keyPath: "id" }');
|
|
1114
1233
|
}
|
|
1115
1234
|
try {
|
|
1116
|
-
|
|
1235
|
+
// 尝试访问 order 表,如果不存在会抛出错误
|
|
1236
|
+
await this.dbManager.getAll('order');
|
|
1117
1237
|
} catch (error) {
|
|
1118
|
-
console.warn(
|
|
1119
|
-
"[PaymentModule] order 表不存在,请在数据库配置中添加以下配置:"
|
|
1120
|
-
);
|
|
1238
|
+
console.warn('[PaymentModule] order 表不存在,请在数据库配置中添加以下配置:');
|
|
1121
1239
|
console.warn('{ name: "order", keyPath: "uuid" }');
|
|
1122
1240
|
}
|
|
1123
1241
|
}
|
|
1242
|
+
|
|
1124
1243
|
/**
|
|
1125
1244
|
* 获取部分支付的订单
|
|
1126
1245
|
*/
|
|
1127
1246
|
async getPartiallyPaidOrdersAsync() {
|
|
1128
1247
|
try {
|
|
1129
|
-
const allOrders = await this.dbManager.getAll(
|
|
1130
|
-
return allOrders.filter(
|
|
1131
|
-
(order) => order.payment_status === import_types.PaymentStatus.PartiallyPaid
|
|
1132
|
-
);
|
|
1248
|
+
const allOrders = await this.dbManager.getAll('order');
|
|
1249
|
+
return allOrders.filter(order => order.payment_status === _types.PaymentStatus.PartiallyPaid);
|
|
1133
1250
|
} catch (error) {
|
|
1134
|
-
console.error(
|
|
1251
|
+
console.error('[PaymentModule] 获取部分支付订单失败', error);
|
|
1135
1252
|
return [];
|
|
1136
1253
|
}
|
|
1137
1254
|
}
|
|
1255
|
+
|
|
1138
1256
|
// === 新的 API 方法实现 ===
|
|
1257
|
+
|
|
1139
1258
|
/**
|
|
1140
1259
|
* 智能金额舍入
|
|
1141
1260
|
*
|
|
@@ -1148,63 +1267,78 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
1148
1267
|
*/
|
|
1149
1268
|
async roundAmountAsync(originalAmount, interval, rule) {
|
|
1150
1269
|
try {
|
|
1151
|
-
|
|
1152
|
-
const
|
|
1270
|
+
// 参数验证
|
|
1271
|
+
const amount = new _decimal.Decimal(originalAmount);
|
|
1272
|
+
const roundingInterval = new _decimal.Decimal(interval);
|
|
1153
1273
|
if (roundingInterval.lte(0)) {
|
|
1154
|
-
throw new Error(
|
|
1274
|
+
throw new Error('舍入间隔必须大于 0');
|
|
1155
1275
|
}
|
|
1276
|
+
|
|
1277
|
+
// 支持的舍入间隔
|
|
1156
1278
|
const supportedIntervals = [0.05, 0.1, 0.5, 1];
|
|
1157
1279
|
const intervalValue = roundingInterval.toNumber();
|
|
1158
1280
|
if (!supportedIntervals.includes(intervalValue)) {
|
|
1159
|
-
console.warn(`[PaymentModule] 不支持的舍入间隔: ${intervalValue}, 支持的间隔: ${supportedIntervals.join(
|
|
1281
|
+
console.warn(`[PaymentModule] 不支持的舍入间隔: ${intervalValue}, 支持的间隔: ${supportedIntervals.join(', ')}`);
|
|
1160
1282
|
}
|
|
1283
|
+
|
|
1284
|
+
// 计算基础值:x / interval
|
|
1161
1285
|
const baseValue = amount.div(roundingInterval);
|
|
1162
|
-
console.log(`[PaymentModule] 舍入计算 - 原始金额: ${amount.toString()}, 间隔: ${intervalValue}, 基础值: ${baseValue.toString()}, 规则: ${rule}`);
|
|
1163
1286
|
let roundedValue;
|
|
1287
|
+
|
|
1288
|
+
// 根据舍入规则处理
|
|
1164
1289
|
switch (rule) {
|
|
1165
|
-
case
|
|
1166
|
-
case
|
|
1290
|
+
case _types.RoundingRule.Standard:
|
|
1291
|
+
case 'standard':
|
|
1292
|
+
// 标准舍入(中点向上)
|
|
1167
1293
|
roundedValue = this.standardRound(baseValue, true);
|
|
1168
1294
|
break;
|
|
1169
|
-
case
|
|
1170
|
-
case
|
|
1295
|
+
case _types.RoundingRule.StandardDown:
|
|
1296
|
+
case 'standard_down':
|
|
1297
|
+
// 标准舍入(中点向下)
|
|
1171
1298
|
roundedValue = this.standardRound(baseValue, false);
|
|
1172
1299
|
break;
|
|
1173
|
-
case
|
|
1174
|
-
case
|
|
1300
|
+
case _types.RoundingRule.AlwaysUp:
|
|
1301
|
+
case 'always_up':
|
|
1302
|
+
// 总是向上舍入
|
|
1175
1303
|
roundedValue = baseValue.ceil();
|
|
1176
1304
|
break;
|
|
1177
|
-
case
|
|
1178
|
-
case
|
|
1305
|
+
case _types.RoundingRule.AlwaysDown:
|
|
1306
|
+
case 'always_down':
|
|
1307
|
+
// 总是向下舍入
|
|
1179
1308
|
roundedValue = baseValue.floor();
|
|
1180
1309
|
break;
|
|
1181
1310
|
default:
|
|
1182
1311
|
throw new Error(`不支持的舍入规则: ${rule}`);
|
|
1183
1312
|
}
|
|
1313
|
+
|
|
1314
|
+
// 计算最终金额:roundedValue * interval
|
|
1184
1315
|
const finalAmount = roundedValue.mul(roundingInterval);
|
|
1185
1316
|
const originalAmountStr = amount.toFixed(2);
|
|
1317
|
+
|
|
1318
|
+
// 如果最终金额是 0 元,则不采用舍入金额,返回原始金额
|
|
1186
1319
|
if (finalAmount.eq(0)) {
|
|
1187
|
-
console.log(`[PaymentModule] 最终金额为0,返回原始金额: ${originalAmountStr}`);
|
|
1188
1320
|
return {
|
|
1189
1321
|
originalAmount: originalAmountStr,
|
|
1190
1322
|
roundedAmount: originalAmountStr,
|
|
1191
|
-
roundingDifference:
|
|
1323
|
+
roundingDifference: '0.00'
|
|
1192
1324
|
};
|
|
1193
1325
|
}
|
|
1194
1326
|
const roundedAmountStr = finalAmount.toFixed(2);
|
|
1327
|
+
|
|
1328
|
+
// 计算舍入差额
|
|
1195
1329
|
const roundingDifference = finalAmount.sub(amount);
|
|
1196
1330
|
const roundingDifferenceStr = roundingDifference.toFixed(2);
|
|
1197
|
-
console.log(`[PaymentModule] 舍入结果 - 原始金额: ${originalAmountStr}, 舍入后金额: ${roundedAmountStr}, 舍入差额: ${roundingDifferenceStr}`);
|
|
1198
1331
|
return {
|
|
1199
1332
|
originalAmount: originalAmountStr,
|
|
1200
1333
|
roundedAmount: roundedAmountStr,
|
|
1201
1334
|
roundingDifference: roundingDifferenceStr
|
|
1202
1335
|
};
|
|
1203
1336
|
} catch (error) {
|
|
1204
|
-
console.error(
|
|
1337
|
+
console.error('[PaymentModule] 金额舍入失败:', error);
|
|
1205
1338
|
throw new Error(`金额舍入失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
1206
1339
|
}
|
|
1207
1340
|
}
|
|
1341
|
+
|
|
1208
1342
|
/**
|
|
1209
1343
|
* 标准舍入处理(处理中点情况)
|
|
1210
1344
|
*
|
|
@@ -1215,18 +1349,18 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
1215
1349
|
standardRound(value, midpointUp) {
|
|
1216
1350
|
const floorValue = value.floor();
|
|
1217
1351
|
const fractionalPart = value.minus(floorValue);
|
|
1352
|
+
|
|
1353
|
+
// 检查是否是中点(小数部分 = 0.5)
|
|
1218
1354
|
if (fractionalPart.eq(0.5)) {
|
|
1355
|
+
// 中点情况,根据规则决定
|
|
1219
1356
|
return midpointUp ? floorValue.plus(1) : floorValue;
|
|
1220
1357
|
} else if (fractionalPart.gt(0.5)) {
|
|
1358
|
+
// 大于中点,向上舍入
|
|
1221
1359
|
return floorValue.plus(1);
|
|
1222
1360
|
} else {
|
|
1361
|
+
// 小于中点,向下舍入
|
|
1223
1362
|
return floorValue;
|
|
1224
1363
|
}
|
|
1225
1364
|
}
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
0 && (module.exports = {
|
|
1229
|
-
PaymentModule,
|
|
1230
|
-
generateRequestUniqueId,
|
|
1231
|
-
...require("./types")
|
|
1232
|
-
});
|
|
1365
|
+
}
|
|
1366
|
+
exports.PaymentModule = PaymentModule;
|