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