@pisell/pisellos 3.0.56 → 3.0.57
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 +2 -1
- package/dist/effects/index.d.ts +4 -3
- package/dist/effects/index.js +15 -6
- package/dist/modules/AccountList/index.d.ts +7 -1
- package/dist/modules/AccountList/index.js +81 -14
- package/dist/modules/AccountList/types.d.ts +28 -0
- package/dist/modules/AccountList/types.js +8 -0
- package/dist/modules/Cart/index.js +1 -1
- package/dist/modules/Cart/utils/changePrice.d.ts +2 -2
- package/dist/modules/Cart/utils/changePrice.js +1 -1
- package/dist/modules/Customer/constants.d.ts +7 -0
- package/dist/modules/Customer/constants.js +12 -0
- package/dist/modules/Customer/index.d.ts +122 -0
- package/dist/modules/Customer/index.js +697 -0
- package/dist/modules/Customer/types.d.ts +146 -0
- package/dist/modules/Customer/types.js +41 -0
- package/dist/modules/Payment/cash.d.ts +11 -0
- package/dist/modules/Payment/cash.js +78 -0
- package/dist/modules/Payment/eftpos.d.ts +11 -0
- package/dist/modules/Payment/eftpos.js +80 -0
- package/dist/modules/Payment/index.d.ts +273 -9
- package/dist/modules/Payment/index.js +2525 -109
- package/dist/modules/Payment/types.d.ts +382 -30
- package/dist/modules/Payment/types.js +116 -14
- package/dist/modules/Payment/wallet.d.ts +11 -0
- package/dist/modules/Payment/wallet.js +78 -0
- package/dist/modules/Payment/walletpass.d.ts +0 -0
- package/dist/modules/Payment/walletpass.js +0 -0
- package/dist/modules/ProductList/index.d.ts +13 -3
- package/dist/modules/ProductList/index.js +52 -42
- package/dist/modules/ProductList/types.d.ts +0 -1
- package/dist/modules/Rules/index.js +27 -14
- package/dist/modules/Rules/types.d.ts +1 -0
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +1 -0
- package/dist/plugins/app-types/app/app.d.ts +83 -0
- package/dist/plugins/app-types/app/const.d.ts +4 -0
- package/dist/plugins/app-types/app/index.d.ts +14 -0
- package/dist/plugins/app-types/applicationManager/application.d.ts +50 -0
- package/dist/plugins/app-types/applicationManager/index.d.ts +13 -0
- package/dist/plugins/app-types/config.d.ts +3 -0
- package/dist/plugins/app-types/cookie/index.d.ts +13 -0
- package/dist/plugins/app-types/data/index.d.ts +8 -0
- package/dist/plugins/app-types/history/config.d.ts +24 -0
- package/dist/plugins/app-types/history/index.d.ts +20 -0
- package/dist/plugins/app-types/history/type.d.ts +2 -0
- package/dist/plugins/app-types/hooks/index.d.ts +12 -0
- package/dist/plugins/app-types/hooks/useDelayedValue/index.d.ts +2 -0
- package/dist/plugins/app-types/hooks/useDispatch/index.d.ts +2 -0
- package/dist/plugins/app-types/hooks/useLowCode/index.d.ts +13 -0
- package/dist/plugins/app-types/hooks/useStore/index.d.ts +6 -0
- package/dist/plugins/app-types/index.d.ts +6 -0
- package/dist/plugins/app-types/indexDB/index.d.ts +178 -0
- package/dist/plugins/app-types/locales/en.d.ts +3 -0
- package/dist/plugins/app-types/locales/index.d.ts +37 -0
- package/dist/plugins/app-types/locales/original.d.ts +3 -0
- package/dist/plugins/app-types/locales/type.d.ts +19 -0
- package/dist/plugins/app-types/locales/zh-CN.d.ts +3 -0
- package/dist/plugins/app-types/locales/zh-HK.d.ts +3 -0
- package/dist/plugins/app-types/logger/feishu.d.ts +11 -0
- package/dist/plugins/app-types/logger/index.d.ts +122 -0
- package/dist/plugins/app-types/menuManager/hooks.d.ts +17 -0
- package/dist/plugins/app-types/menuManager/index.d.ts +28 -0
- package/dist/plugins/app-types/models/global.d.ts +32 -0
- package/dist/plugins/app-types/models/index.d.ts +45 -0
- package/dist/plugins/app-types/models/type.d.ts +2 -0
- package/dist/plugins/app-types/package.json +15 -0
- package/dist/plugins/app-types/plugin/index.d.ts +0 -0
- package/dist/plugins/app-types/pubsub/example.d.ts +5 -0
- package/dist/plugins/app-types/pubsub/index.d.ts +63 -0
- package/dist/plugins/app-types/request/cache.d.ts +46 -0
- package/dist/plugins/app-types/request/cancelToken.d.ts +38 -0
- package/dist/plugins/app-types/request/config.d.ts +3 -0
- package/dist/plugins/app-types/request/constants.d.ts +2 -0
- package/dist/plugins/app-types/request/index.d.ts +24 -0
- package/dist/plugins/app-types/request/pisell2Request.d.ts +6 -0
- package/dist/plugins/app-types/request/type.d.ts +41 -0
- package/dist/plugins/app-types/request/utils.d.ts +46 -0
- package/dist/plugins/app-types/routes/config.d.ts +7 -0
- package/dist/plugins/app-types/routes/index.d.ts +28 -0
- package/dist/plugins/app-types/socket/components/SocketMonitorPage.d.ts +6 -0
- package/dist/plugins/app-types/socket/components/index.d.ts +2 -0
- package/dist/plugins/app-types/socket/constants.d.ts +33 -0
- package/dist/plugins/app-types/socket/events.d.ts +31 -0
- package/dist/plugins/app-types/socket/heartbeat.d.ts +66 -0
- package/dist/plugins/app-types/socket/index.d.ts +61 -0
- package/dist/plugins/app-types/socket/monitor.d.ts +169 -0
- package/dist/plugins/app-types/socket/reconnect.d.ts +61 -0
- package/dist/plugins/app-types/socket/socket.d.ts +129 -0
- package/dist/plugins/app-types/socket/types.d.ts +85 -0
- package/dist/plugins/app-types/storage/index.d.ts +17 -0
- package/dist/plugins/app-types/tasks/index.d.ts +77 -0
- package/dist/plugins/app-types/tasks/type.d.ts +62 -0
- package/dist/plugins/app-types/tasks/useTasks.d.ts +5 -0
- package/dist/plugins/app-types/type.d.ts +2 -0
- package/dist/plugins/app-types/variables/VariablesProvider.d.ts +7 -0
- package/dist/plugins/app-types/variables/config.d.ts +3 -0
- package/dist/plugins/app-types/variables/index.d.ts +6 -0
- package/dist/plugins/app-types/variables/type.d.ts +2 -0
- package/dist/plugins/app-types/website/index.d.ts +6 -0
- package/dist/plugins/app.d.ts +8 -0
- package/dist/plugins/app.js +1 -0
- package/dist/plugins/window.d.ts +1 -0
- package/dist/solution/BookingByStep/index.js +59 -35
- package/dist/solution/BookingByStep/types.d.ts +3 -2
- package/dist/solution/BookingTicket/index.d.ts +172 -0
- package/dist/solution/BookingTicket/index.js +665 -0
- package/dist/solution/BookingTicket/types.d.ts +68 -0
- package/dist/solution/BookingTicket/types.js +43 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.d.ts +22 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +159 -0
- package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +16 -0
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +174 -0
- package/dist/solution/BookingTicket/utils/scan/index.d.ts +81 -0
- package/dist/solution/BookingTicket/utils/scan/index.js +285 -0
- package/dist/solution/BookingTicket/utils/scan/scanCache.d.ts +78 -0
- package/dist/solution/BookingTicket/utils/scan/scanCache.js +305 -0
- package/dist/solution/BuyTickets/index.d.ts +2 -2
- package/dist/solution/BuyTickets/index.js +1 -1
- package/dist/solution/Checkout/appointmentDemo.json +1 -0
- package/dist/solution/Checkout/index.d.ts +181 -0
- package/dist/solution/Checkout/index.js +1596 -0
- package/dist/solution/Checkout/types.d.ts +550 -0
- package/dist/solution/Checkout/types.js +132 -0
- package/dist/solution/Checkout/utils/index.d.ts +73 -0
- package/dist/solution/Checkout/utils/index.js +371 -0
- package/dist/solution/ShopDiscount/index.js +4 -2
- package/dist/solution/index.d.ts +2 -0
- package/dist/solution/index.js +3 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/utils/task.d.ts +40 -0
- package/dist/utils/task.js +171 -0
- package/dist/utils/watch.d.ts +102 -0
- package/dist/utils/watch.js +294 -0
- package/lib/core/index.js +1 -1
- package/lib/effects/index.d.ts +4 -3
- package/lib/effects/index.js +4 -1
- package/lib/modules/AccountList/index.d.ts +7 -1
- package/lib/modules/AccountList/index.js +27 -0
- package/lib/modules/AccountList/types.d.ts +28 -0
- package/lib/modules/Cart/index.js +1 -1
- package/lib/modules/Cart/utils/changePrice.d.ts +2 -2
- package/lib/modules/Cart/utils/changePrice.js +1 -1
- package/lib/modules/Customer/constants.d.ts +7 -0
- package/lib/modules/Customer/constants.js +39 -0
- package/lib/modules/Customer/index.d.ts +122 -0
- package/lib/modules/Customer/index.js +440 -0
- package/lib/modules/Customer/types.d.ts +146 -0
- package/lib/modules/Customer/types.js +37 -0
- package/lib/modules/Payment/cash.d.ts +11 -0
- package/lib/modules/Payment/cash.js +51 -0
- package/lib/modules/Payment/eftpos.d.ts +11 -0
- package/lib/modules/Payment/eftpos.js +51 -0
- package/lib/modules/Payment/index.d.ts +273 -9
- package/lib/modules/Payment/index.js +1285 -50
- package/lib/modules/Payment/types.d.ts +382 -30
- package/lib/modules/Payment/types.js +41 -6
- package/lib/modules/Payment/wallet.d.ts +11 -0
- package/lib/modules/Payment/wallet.js +51 -0
- package/lib/modules/Payment/walletpass.d.ts +0 -0
- package/lib/modules/Payment/walletpass.js +0 -0
- package/lib/modules/ProductList/index.d.ts +13 -3
- package/lib/modules/ProductList/index.js +37 -26
- package/lib/modules/ProductList/types.d.ts +0 -1
- package/lib/modules/Rules/index.js +20 -12
- package/lib/modules/Rules/types.d.ts +1 -0
- package/lib/modules/index.d.ts +1 -0
- package/lib/modules/index.js +2 -0
- package/lib/plugins/app-types/app/app.d.ts +83 -0
- package/lib/plugins/app-types/app/const.d.ts +4 -0
- package/lib/plugins/app-types/app/index.d.ts +14 -0
- package/lib/plugins/app-types/applicationManager/application.d.ts +50 -0
- package/lib/plugins/app-types/applicationManager/index.d.ts +13 -0
- package/lib/plugins/app-types/config.d.ts +3 -0
- package/lib/plugins/app-types/cookie/index.d.ts +13 -0
- package/lib/plugins/app-types/data/index.d.ts +8 -0
- package/lib/plugins/app-types/history/config.d.ts +24 -0
- package/lib/plugins/app-types/history/index.d.ts +20 -0
- package/lib/plugins/app-types/history/type.d.ts +2 -0
- package/lib/plugins/app-types/hooks/index.d.ts +12 -0
- package/lib/plugins/app-types/hooks/useDelayedValue/index.d.ts +2 -0
- package/lib/plugins/app-types/hooks/useDispatch/index.d.ts +2 -0
- package/lib/plugins/app-types/hooks/useLowCode/index.d.ts +13 -0
- package/lib/plugins/app-types/hooks/useStore/index.d.ts +6 -0
- package/lib/plugins/app-types/index.d.ts +6 -0
- package/lib/plugins/app-types/indexDB/index.d.ts +178 -0
- package/lib/plugins/app-types/locales/en.d.ts +3 -0
- package/lib/plugins/app-types/locales/index.d.ts +37 -0
- package/lib/plugins/app-types/locales/original.d.ts +3 -0
- package/lib/plugins/app-types/locales/type.d.ts +19 -0
- package/lib/plugins/app-types/locales/zh-CN.d.ts +3 -0
- package/lib/plugins/app-types/locales/zh-HK.d.ts +3 -0
- package/lib/plugins/app-types/logger/feishu.d.ts +11 -0
- package/lib/plugins/app-types/logger/index.d.ts +122 -0
- package/lib/plugins/app-types/menuManager/hooks.d.ts +17 -0
- package/lib/plugins/app-types/menuManager/index.d.ts +28 -0
- package/lib/plugins/app-types/models/global.d.ts +32 -0
- package/lib/plugins/app-types/models/index.d.ts +45 -0
- package/lib/plugins/app-types/models/type.d.ts +2 -0
- package/lib/plugins/app-types/package.json +15 -0
- package/lib/plugins/app-types/plugin/index.d.ts +0 -0
- package/lib/plugins/app-types/pubsub/example.d.ts +5 -0
- package/lib/plugins/app-types/pubsub/index.d.ts +63 -0
- package/lib/plugins/app-types/request/cache.d.ts +46 -0
- package/lib/plugins/app-types/request/cancelToken.d.ts +38 -0
- package/lib/plugins/app-types/request/config.d.ts +3 -0
- package/lib/plugins/app-types/request/constants.d.ts +2 -0
- package/lib/plugins/app-types/request/index.d.ts +24 -0
- package/lib/plugins/app-types/request/pisell2Request.d.ts +6 -0
- package/lib/plugins/app-types/request/type.d.ts +41 -0
- package/lib/plugins/app-types/request/utils.d.ts +46 -0
- package/lib/plugins/app-types/routes/config.d.ts +7 -0
- package/lib/plugins/app-types/routes/index.d.ts +28 -0
- package/lib/plugins/app-types/socket/components/SocketMonitorPage.d.ts +6 -0
- package/lib/plugins/app-types/socket/components/index.d.ts +2 -0
- package/lib/plugins/app-types/socket/constants.d.ts +33 -0
- package/lib/plugins/app-types/socket/events.d.ts +31 -0
- package/lib/plugins/app-types/socket/heartbeat.d.ts +66 -0
- package/lib/plugins/app-types/socket/index.d.ts +61 -0
- package/lib/plugins/app-types/socket/monitor.d.ts +169 -0
- package/lib/plugins/app-types/socket/reconnect.d.ts +61 -0
- package/lib/plugins/app-types/socket/socket.d.ts +129 -0
- package/lib/plugins/app-types/socket/types.d.ts +85 -0
- package/lib/plugins/app-types/storage/index.d.ts +17 -0
- package/lib/plugins/app-types/tasks/index.d.ts +77 -0
- package/lib/plugins/app-types/tasks/type.d.ts +62 -0
- package/lib/plugins/app-types/tasks/useTasks.d.ts +5 -0
- package/lib/plugins/app-types/type.d.ts +2 -0
- package/lib/plugins/app-types/variables/VariablesProvider.d.ts +7 -0
- package/lib/plugins/app-types/variables/config.d.ts +3 -0
- package/lib/plugins/app-types/variables/index.d.ts +6 -0
- package/lib/plugins/app-types/variables/type.d.ts +2 -0
- package/lib/plugins/app-types/website/index.d.ts +6 -0
- package/lib/plugins/app.d.ts +8 -0
- package/lib/plugins/app.js +17 -0
- package/lib/plugins/window.d.ts +1 -0
- package/lib/solution/BookingByStep/index.js +40 -29
- package/lib/solution/BookingByStep/types.d.ts +3 -2
- package/lib/solution/BookingTicket/index.d.ts +172 -0
- package/lib/solution/BookingTicket/index.js +399 -0
- package/lib/solution/BookingTicket/types.d.ts +68 -0
- package/lib/solution/BookingTicket/types.js +72 -0
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.d.ts +22 -0
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +117 -0
- package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +16 -0
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +125 -0
- package/lib/solution/BookingTicket/utils/scan/index.d.ts +81 -0
- package/lib/solution/BookingTicket/utils/scan/index.js +210 -0
- package/lib/solution/BookingTicket/utils/scan/scanCache.d.ts +78 -0
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +231 -0
- package/lib/solution/BuyTickets/index.d.ts +2 -2
- package/lib/solution/BuyTickets/index.js +1 -1
- package/lib/solution/Checkout/appointmentDemo.json +1 -0
- package/lib/solution/Checkout/index.d.ts +181 -0
- package/lib/solution/Checkout/index.js +864 -0
- package/lib/solution/Checkout/types.d.ts +550 -0
- package/lib/solution/Checkout/types.js +75 -0
- package/lib/solution/Checkout/utils/index.d.ts +73 -0
- package/lib/solution/Checkout/utils/index.js +266 -0
- package/lib/solution/ShopDiscount/index.js +2 -1
- package/lib/solution/index.d.ts +2 -0
- package/lib/solution/index.js +5 -1
- package/lib/types/index.d.ts +3 -1
- package/lib/utils/task.d.ts +40 -0
- package/lib/utils/task.js +109 -0
- package/lib/utils/watch.d.ts +102 -0
- package/lib/utils/watch.js +217 -0
- package/package.json +4 -2
|
@@ -14,74 +14,1309 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
14
14
|
}
|
|
15
15
|
return to;
|
|
16
16
|
};
|
|
17
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
17
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
19
|
|
|
19
20
|
// src/modules/Payment/index.ts
|
|
20
21
|
var Payment_exports = {};
|
|
21
22
|
__export(Payment_exports, {
|
|
22
|
-
PaymentModule: () => PaymentModule
|
|
23
|
+
PaymentModule: () => PaymentModule,
|
|
24
|
+
generateRequestUniqueId: () => generateRequestUniqueId
|
|
23
25
|
});
|
|
24
26
|
module.exports = __toCommonJS(Payment_exports);
|
|
25
27
|
var import_BaseModule = require("../BaseModule");
|
|
26
28
|
var import_types = require("./types");
|
|
29
|
+
var import_utils = require("../Cart/utils");
|
|
30
|
+
var import_cash = require("./cash");
|
|
31
|
+
var import_eftpos = require("./eftpos");
|
|
32
|
+
var import_wallet = require("./wallet");
|
|
33
|
+
var import_decimal = require("decimal.js");
|
|
34
|
+
__reExport(Payment_exports, require("./types"), module.exports);
|
|
35
|
+
function formatAmount(amount) {
|
|
36
|
+
try {
|
|
37
|
+
const decimal = new import_decimal.Decimal(amount);
|
|
38
|
+
return decimal.toFixed(2);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.warn(`[PaymentModule] 金额格式化失败: ${amount},使用默认值 0.00`);
|
|
41
|
+
return "0.00";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function generateRequestUniqueId() {
|
|
45
|
+
const now = /* @__PURE__ */ new Date();
|
|
46
|
+
const year = now.getFullYear();
|
|
47
|
+
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
48
|
+
const day = String(now.getDate()).padStart(2, "0");
|
|
49
|
+
const hour = String(now.getHours()).padStart(2, "0");
|
|
50
|
+
const minute = String(now.getMinutes()).padStart(2, "0");
|
|
51
|
+
const second = String(now.getSeconds()).padStart(2, "0");
|
|
52
|
+
const millisecond = String(now.getMilliseconds()).padStart(3, "0");
|
|
53
|
+
const randomDigits = Math.floor(Math.random() * 9e3) + 1e3;
|
|
54
|
+
return `${year}${month}${day}${hour}${minute}${second}${millisecond}${randomDigits}`;
|
|
55
|
+
}
|
|
27
56
|
var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
28
57
|
constructor(name, version) {
|
|
29
58
|
super(name, version);
|
|
30
|
-
this.defaultName = "
|
|
59
|
+
this.defaultName = "pay";
|
|
31
60
|
this.defaultVersion = "1.0.0";
|
|
32
|
-
this.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
};
|
|
61
|
+
this.cash = new import_cash.CashPaymentImpl(this);
|
|
62
|
+
this.eftpos = new import_eftpos.EftposPaymentImpl(this);
|
|
63
|
+
this.wallet = new import_wallet.WalletPaymentImpl(this);
|
|
36
64
|
}
|
|
37
65
|
async initialize(core, options) {
|
|
38
66
|
this.core = core;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
67
|
+
this.store = options.store;
|
|
68
|
+
this.request = core.getPlugin("request");
|
|
69
|
+
const appPlugin = core.getPlugin("app");
|
|
70
|
+
if (!this.request) {
|
|
71
|
+
throw new Error("支付模块需要 request 插件支持");
|
|
72
|
+
}
|
|
73
|
+
if (!appPlugin) {
|
|
74
|
+
throw new Error("支付模块需要 app 插件支持");
|
|
75
|
+
}
|
|
76
|
+
this.app = appPlugin.getApp();
|
|
77
|
+
this.dbManager = this.app.dbManager;
|
|
78
|
+
this.logger = this.app.logger;
|
|
79
|
+
await this.ensurePaymentTables();
|
|
80
|
+
this.registerTaskHandlers();
|
|
81
|
+
this.registerNetworkHandlers();
|
|
82
|
+
console.log("[PaymentModule] 初始化完成");
|
|
83
|
+
this.logInfo("PaymentModule initialized successfully");
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 记录信息日志
|
|
87
|
+
*/
|
|
88
|
+
logInfo(title, metadata) {
|
|
89
|
+
if (this.logger) {
|
|
90
|
+
this.logger.addLog({
|
|
91
|
+
type: "info",
|
|
92
|
+
title: `[PaymentModule] ${title}`,
|
|
93
|
+
metadata: metadata || {}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 记录警告日志
|
|
99
|
+
*/
|
|
100
|
+
logWarning(title, metadata) {
|
|
101
|
+
if (this.logger) {
|
|
102
|
+
this.logger.addLog({
|
|
103
|
+
type: "warning",
|
|
104
|
+
title: `[PaymentModule] ${title}`,
|
|
105
|
+
metadata: metadata || {}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 记录错误日志
|
|
111
|
+
*/
|
|
112
|
+
logError(title, error, metadata) {
|
|
113
|
+
if (this.logger) {
|
|
114
|
+
this.logger.addLog({
|
|
115
|
+
type: "error",
|
|
116
|
+
title: `[PaymentModule] ${title}`,
|
|
117
|
+
metadata: {
|
|
118
|
+
error: error ? {
|
|
119
|
+
message: error.message,
|
|
120
|
+
stack: error.stack,
|
|
121
|
+
code: error.code,
|
|
122
|
+
...error
|
|
123
|
+
} : void 0,
|
|
124
|
+
...metadata || {}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 记录调试日志
|
|
131
|
+
*/
|
|
132
|
+
logDebug(title, metadata) {
|
|
133
|
+
if (this.logger) {
|
|
134
|
+
this.logger.addLog({
|
|
135
|
+
type: "debug",
|
|
136
|
+
title: `[PaymentModule] ${title}`,
|
|
137
|
+
metadata: metadata || {}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 网络恢复以后,尝试执行队列
|
|
143
|
+
*
|
|
144
|
+
*/
|
|
145
|
+
registerNetworkHandlers() {
|
|
146
|
+
const network = this.app.plugins.get("network");
|
|
147
|
+
this.logInfo("Registering network status listener");
|
|
148
|
+
network == null ? void 0 : network.addListener("networkStatusChange", async (status) => {
|
|
149
|
+
console.log("网络状态:", status.connected);
|
|
150
|
+
this.logInfo("Network status changed", {
|
|
151
|
+
connected: status.connected,
|
|
152
|
+
previousStatus: status.previousStatus
|
|
153
|
+
});
|
|
154
|
+
if (status.connected) {
|
|
155
|
+
this.logInfo("Network reconnected - triggering payment sync queue");
|
|
156
|
+
const requeuedCount = await this.recheckAndRequeueUnsyncedOrders();
|
|
157
|
+
if (requeuedCount > 0) {
|
|
158
|
+
await this.runPaymentSyncQueue();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* 获取支付方式列表
|
|
165
|
+
*/
|
|
166
|
+
async getPayMethodListAsync() {
|
|
167
|
+
this.logInfo("Starting getPayMethodListAsync");
|
|
168
|
+
try {
|
|
169
|
+
let cachedMethods = [];
|
|
170
|
+
try {
|
|
171
|
+
cachedMethods = await this.dbManager.getAll("pay_method");
|
|
172
|
+
} catch (dbError) {
|
|
173
|
+
console.warn("[PaymentModule] pay_method 表不存在,将从服务器获取数据");
|
|
174
|
+
}
|
|
175
|
+
const hasCache = cachedMethods.length > 0;
|
|
176
|
+
if (hasCache) {
|
|
177
|
+
this.refreshPaymentMethodsInBackground(cachedMethods);
|
|
178
|
+
return cachedMethods;
|
|
179
|
+
}
|
|
180
|
+
const response = await this.request.get("/pay/custom-payment/available");
|
|
181
|
+
const payMethods = response.data || [];
|
|
182
|
+
try {
|
|
183
|
+
for (const method of payMethods) {
|
|
184
|
+
await this.dbManager.update("pay_method", method);
|
|
185
|
+
}
|
|
186
|
+
} catch (dbError) {
|
|
187
|
+
console.warn("[PaymentModule] 无法缓存支付方式,pay_method 表不存在");
|
|
188
|
+
}
|
|
189
|
+
await this.core.effects.emit(
|
|
190
|
+
import_types.PaymentHooks.OnPaymentMethodsLoaded,
|
|
191
|
+
payMethods
|
|
192
|
+
);
|
|
193
|
+
this.logInfo("getPayMethodListAsync completed successfully", {
|
|
194
|
+
methodCount: payMethods.length,
|
|
195
|
+
hasCache: cachedMethods.length > 0
|
|
196
|
+
});
|
|
197
|
+
return payMethods;
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.error("[PaymentModule] 获取支付方式列表失败", error);
|
|
200
|
+
this.logError("getPayMethodListAsync failed", error);
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* 后台刷新支付方式列表
|
|
206
|
+
*/
|
|
207
|
+
async refreshPaymentMethodsInBackground(cachedMethods) {
|
|
208
|
+
this.logInfo("Starting refreshPaymentMethodsInBackground", {
|
|
209
|
+
cachedMethodsCount: cachedMethods.length
|
|
210
|
+
});
|
|
211
|
+
try {
|
|
212
|
+
console.log("[PaymentModule] 后台刷新支付方式列表...");
|
|
213
|
+
const response = await this.request.get("/pay/custom-payment/available");
|
|
214
|
+
const newPayMethods = response.data || [];
|
|
215
|
+
const hasChanges = this.hasPaymentMethodsChanged(
|
|
216
|
+
cachedMethods,
|
|
217
|
+
newPayMethods
|
|
218
|
+
);
|
|
219
|
+
if (hasChanges) {
|
|
220
|
+
console.log("[PaymentModule] 支付方式列表已更新");
|
|
221
|
+
this.logInfo("Payment methods updated in background", {
|
|
222
|
+
oldCount: cachedMethods.length,
|
|
223
|
+
newCount: newPayMethods.length
|
|
224
|
+
});
|
|
225
|
+
try {
|
|
226
|
+
for (const method of cachedMethods) {
|
|
227
|
+
await this.dbManager.delete("pay_method", method.id);
|
|
228
|
+
}
|
|
229
|
+
for (const method of newPayMethods) {
|
|
230
|
+
await this.dbManager.update("pay_method", method);
|
|
231
|
+
}
|
|
232
|
+
} catch (dbError) {
|
|
233
|
+
console.warn("[PaymentModule] 无法更新支付方式缓存", dbError);
|
|
234
|
+
}
|
|
235
|
+
const eventData = {
|
|
236
|
+
oldMethods: cachedMethods,
|
|
237
|
+
newMethods: newPayMethods
|
|
238
|
+
};
|
|
239
|
+
await this.core.effects.emit(
|
|
240
|
+
import_types.PaymentHooks.OnPaymentMethodsChanged,
|
|
241
|
+
eventData
|
|
242
|
+
);
|
|
243
|
+
} else {
|
|
244
|
+
console.log("[PaymentModule] 支付方式列表无变化");
|
|
245
|
+
}
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.error("[PaymentModule] 后台刷新支付方式失败", error);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* 检查支付方式列表是否有变化
|
|
252
|
+
*/
|
|
253
|
+
hasPaymentMethodsChanged(oldMethods, newMethods) {
|
|
254
|
+
if (oldMethods.length !== newMethods.length) {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
const oldMethodsMap = new Map(
|
|
258
|
+
oldMethods.map((method) => [method.id, method])
|
|
259
|
+
);
|
|
260
|
+
for (const newMethod of newMethods) {
|
|
261
|
+
const oldMethod = oldMethodsMap.get(newMethod.id);
|
|
262
|
+
if (!oldMethod) {
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
if (oldMethod.code !== newMethod.code || oldMethod.name !== newMethod.name || oldMethod.type !== newMethod.type || oldMethod.enabled !== newMethod.enabled) {
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* 获取订单列表
|
|
273
|
+
*/
|
|
274
|
+
async getOrderListAsync() {
|
|
275
|
+
try {
|
|
276
|
+
return await this.dbManager.getAll("order");
|
|
277
|
+
} catch (error) {
|
|
278
|
+
console.error("[PaymentModule] 获取订单列表失败", error);
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* 根据订单UUID获取支付订单(新方法)
|
|
284
|
+
*/
|
|
285
|
+
async getPaymentOrderByUuidAsync(orderUuid) {
|
|
286
|
+
try {
|
|
287
|
+
return await this.dbManager.get("order", orderUuid);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
console.error("[PaymentModule] 获取支付订单失败", error);
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* 创建支付订单(新方法,专注支付数据)
|
|
295
|
+
*/
|
|
296
|
+
async createPaymentOrderAsync(params) {
|
|
297
|
+
this.logInfo("Starting createPaymentOrderAsync", {
|
|
298
|
+
orderId: params.order_id,
|
|
299
|
+
totalAmount: params.total_amount
|
|
300
|
+
});
|
|
301
|
+
try {
|
|
302
|
+
const existingOrders = await this.dbManager.getAll("order");
|
|
303
|
+
const existingOrder = existingOrders.find(
|
|
304
|
+
(order) => String(order.id) === String(params.order_id)
|
|
305
|
+
);
|
|
306
|
+
if (existingOrder) {
|
|
307
|
+
console.log(
|
|
308
|
+
`[PaymentModule] 发现重复订单 ID: ${params.order_id},更新现有支付订单`
|
|
309
|
+
);
|
|
310
|
+
const originalOrder = { ...existingOrder };
|
|
311
|
+
existingOrder.order_info = params.order_info;
|
|
312
|
+
existingOrder.total_amount = params.total_amount;
|
|
313
|
+
existingOrder.is_deposit = params.is_deposit || 0;
|
|
314
|
+
existingOrder.deposit_amount = params.deposit_amount || "0.00";
|
|
315
|
+
this.recalculateOrderAmount(existingOrder);
|
|
316
|
+
await this.dbManager.update("order", existingOrder);
|
|
317
|
+
await this.core.effects.emit(
|
|
318
|
+
import_types.PaymentHooks.OnOrderUpdated,
|
|
319
|
+
existingOrder
|
|
320
|
+
);
|
|
321
|
+
return existingOrder;
|
|
322
|
+
} else {
|
|
323
|
+
const newOrder = {
|
|
324
|
+
uuid: (0, import_utils.getUniqueId)("pay_order_"),
|
|
325
|
+
id: params.order_id,
|
|
326
|
+
order_id: params.order_id,
|
|
327
|
+
order_info: params.order_info,
|
|
328
|
+
payment_status: import_types.PaymentStatus.Processing,
|
|
329
|
+
payment: [],
|
|
330
|
+
adjust_offline_payments: [],
|
|
331
|
+
total_amount: params.total_amount,
|
|
332
|
+
expect_amount: params.total_amount,
|
|
333
|
+
tax_fee: "0.00",
|
|
334
|
+
is_deposit: params.is_deposit || 0,
|
|
335
|
+
deposit_amount: params.deposit_amount || "0.00"
|
|
336
|
+
};
|
|
337
|
+
await this.dbManager.add("order", newOrder);
|
|
338
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderAdded, newOrder);
|
|
339
|
+
this.logInfo("createPaymentOrderAsync completed - new payment order created", {
|
|
340
|
+
orderUuid: newOrder.uuid,
|
|
341
|
+
orderId: newOrder.id
|
|
342
|
+
});
|
|
343
|
+
return newOrder;
|
|
344
|
+
}
|
|
345
|
+
} catch (error) {
|
|
346
|
+
console.error("[PaymentModule] 创建支付订单失败", error);
|
|
347
|
+
this.logError("createPaymentOrderAsync failed", error, {
|
|
348
|
+
orderId: params.order_id
|
|
349
|
+
});
|
|
350
|
+
throw error;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* 往交易组中添加订单(兼容性方法)
|
|
355
|
+
* @deprecated 使用 createPaymentOrderAsync 替代
|
|
356
|
+
*/
|
|
357
|
+
async pushOrderAsync(params) {
|
|
358
|
+
console.warn("[PaymentModule] pushOrderAsync 已废弃,请使用 createPaymentOrderAsync 替代");
|
|
359
|
+
return this.createPaymentOrderAsync(params);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* 删除支付订单(新方法)
|
|
363
|
+
*/
|
|
364
|
+
async deletePaymentOrderAsync(orderUuid) {
|
|
365
|
+
try {
|
|
366
|
+
const order = await this.dbManager.get("order", orderUuid);
|
|
367
|
+
if (order) {
|
|
368
|
+
await this.dbManager.delete("order", orderUuid);
|
|
369
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderDeleted, order);
|
|
370
|
+
console.log("[PaymentModule] 支付订单删除成功:", orderUuid);
|
|
371
|
+
}
|
|
372
|
+
} catch (error) {
|
|
373
|
+
console.error("[PaymentModule] 删除支付订单失败", error);
|
|
374
|
+
throw error;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* 删除订单(兼容性方法)
|
|
379
|
+
* @deprecated 使用 deletePaymentOrderAsync 替代
|
|
380
|
+
*/
|
|
381
|
+
async deleteOrderAsync(orderUuid) {
|
|
382
|
+
console.warn("[PaymentModule] deleteOrderAsync 已废弃,请使用 deletePaymentOrderAsync 替代");
|
|
383
|
+
return this.deletePaymentOrderAsync(orderUuid);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* 更新订单
|
|
387
|
+
*/
|
|
388
|
+
async updateOrderAsync(orderUuid, params) {
|
|
389
|
+
try {
|
|
390
|
+
const order = await this.dbManager.get("order", orderUuid);
|
|
391
|
+
if (order) {
|
|
392
|
+
const updatedOrder = { ...order, ...params };
|
|
393
|
+
await this.dbManager.update("order", updatedOrder);
|
|
394
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderUpdated, updatedOrder);
|
|
395
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
396
|
+
action: "update",
|
|
397
|
+
order: updatedOrder,
|
|
398
|
+
originalOrder: order
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
} catch (error) {
|
|
402
|
+
console.error("[PaymentModule] 更新订单失败", error);
|
|
403
|
+
throw error;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* 基于UUID替换订单ID
|
|
408
|
+
*
|
|
409
|
+
* 此方法用于将本地虚拟订单ID替换为真实的订单ID。
|
|
410
|
+
* 当前端模拟下单流程完成后,后端返回真实订单ID时调用此方法。
|
|
411
|
+
*
|
|
412
|
+
* @param orderUuid 订单的UUID
|
|
413
|
+
* @param newOrderId 新的订单ID (来自后端)
|
|
414
|
+
* @returns 更新后的订单对象,如果订单不存在则返回null
|
|
415
|
+
*/
|
|
416
|
+
async replaceOrderIdByUuidAsync(orderUuid, newOrderId) {
|
|
417
|
+
this.logInfo("Starting replaceOrderIdByUuidAsync", {
|
|
418
|
+
orderUuid,
|
|
419
|
+
newOrderId
|
|
420
|
+
});
|
|
421
|
+
try {
|
|
422
|
+
const existingOrder = await this.dbManager.get("order", orderUuid);
|
|
423
|
+
if (!existingOrder) {
|
|
424
|
+
this.logWarning("Order not found for UUID replacement", { orderUuid });
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
const allOrders = await this.dbManager.getAll("order");
|
|
428
|
+
const duplicateOrder = allOrders.find(
|
|
429
|
+
(order) => String(order.order_id) === String(newOrderId) && order.uuid !== orderUuid
|
|
430
|
+
);
|
|
431
|
+
if (duplicateOrder) {
|
|
432
|
+
this.logWarning("New order ID already exists", {
|
|
433
|
+
newOrderId,
|
|
434
|
+
existingOrderUuid: duplicateOrder.uuid
|
|
435
|
+
});
|
|
436
|
+
throw new Error(`订单ID ${newOrderId} 已存在`);
|
|
437
|
+
}
|
|
438
|
+
const originalOrderId = existingOrder.id;
|
|
439
|
+
const updatedOrder = {
|
|
440
|
+
...existingOrder,
|
|
441
|
+
id: newOrderId,
|
|
442
|
+
order_info: {
|
|
443
|
+
...existingOrder.order_info,
|
|
444
|
+
order_id: newOrderId,
|
|
445
|
+
// 保留原始本地订单ID作为参考
|
|
446
|
+
original_local_order_id: originalOrderId,
|
|
447
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
await this.dbManager.update("order", updatedOrder);
|
|
451
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderUpdated, updatedOrder);
|
|
452
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
453
|
+
action: "order_id_replaced",
|
|
454
|
+
order: updatedOrder,
|
|
455
|
+
originalOrder: existingOrder,
|
|
456
|
+
metadata: {
|
|
457
|
+
originalOrderId,
|
|
458
|
+
newOrderId
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
this.logInfo("Order ID replacement completed successfully", {
|
|
462
|
+
orderUuid,
|
|
463
|
+
originalOrderId,
|
|
464
|
+
newOrderId
|
|
465
|
+
});
|
|
466
|
+
console.log(`[PaymentModule] 订单ID替换成功: ${originalOrderId} → ${newOrderId}`);
|
|
467
|
+
return updatedOrder;
|
|
468
|
+
} catch (error) {
|
|
469
|
+
console.error("[PaymentModule] 替换订单ID失败", error);
|
|
470
|
+
this.logError("replaceOrderIdByUuidAsync failed", error, {
|
|
471
|
+
orderUuid,
|
|
472
|
+
newOrderId
|
|
473
|
+
});
|
|
474
|
+
throw error;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* 获取支付项(新方法)
|
|
479
|
+
*/
|
|
480
|
+
async getPaymentItemsAsync(orderUuid) {
|
|
481
|
+
if (!orderUuid) {
|
|
482
|
+
throw new Error("orderUuid is required");
|
|
483
|
+
}
|
|
484
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
485
|
+
return (order == null ? void 0 : order.payment) || [];
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* 获取支付项(兼容性方法)
|
|
489
|
+
* @deprecated 使用 getPaymentItemsAsync 替代
|
|
490
|
+
*/
|
|
491
|
+
async getPaymentAsync(orderUuid) {
|
|
492
|
+
console.warn("[PaymentModule] getPaymentAsync 已废弃,请使用 getPaymentItemsAsync 替代");
|
|
493
|
+
return this.getPaymentItemsAsync(orderUuid);
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* 为某个订单添加支付项(新方法)
|
|
497
|
+
*/
|
|
498
|
+
async addPaymentItemAsync(orderUuid, paymentItem) {
|
|
499
|
+
this.logInfo("Starting addPaymentItemAsync", {
|
|
500
|
+
orderUuid,
|
|
501
|
+
paymentAmount: paymentItem.amount,
|
|
502
|
+
paymentCode: paymentItem.code
|
|
503
|
+
});
|
|
504
|
+
try {
|
|
505
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
506
|
+
if (!order) {
|
|
507
|
+
throw new Error(`Order not found: ${orderUuid}`);
|
|
508
|
+
}
|
|
509
|
+
const newPaymentItem = {
|
|
510
|
+
uuid: (0, import_utils.getUniqueId)("payment_"),
|
|
511
|
+
id: paymentItem.id || 0,
|
|
512
|
+
name: paymentItem.name,
|
|
513
|
+
code: paymentItem.code,
|
|
514
|
+
type: paymentItem.type,
|
|
515
|
+
amount: formatAmount(paymentItem.amount),
|
|
516
|
+
voucher_id: paymentItem.voucher_id || "",
|
|
517
|
+
rounding_amount: "0.00",
|
|
518
|
+
service_charge: { percentage: "0.00", amount: "0.00" },
|
|
519
|
+
isSynced: false
|
|
520
|
+
};
|
|
521
|
+
order.payment.push(newPaymentItem);
|
|
522
|
+
this.recalculateOrderAmount(order);
|
|
523
|
+
await this.dbManager.update("order", order);
|
|
524
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentAdded, {
|
|
525
|
+
orderUuid,
|
|
526
|
+
payment: newPaymentItem
|
|
527
|
+
});
|
|
528
|
+
this.logInfo("addPaymentItemAsync completed successfully", {
|
|
529
|
+
orderUuid,
|
|
530
|
+
paymentUuid: newPaymentItem.uuid,
|
|
531
|
+
newExpectAmount: order.expect_amount
|
|
532
|
+
});
|
|
533
|
+
} catch (error) {
|
|
534
|
+
console.error("[PaymentModule] 添加支付项失败", error);
|
|
535
|
+
this.logError("addPaymentItemAsync failed", error, {
|
|
536
|
+
orderUuid,
|
|
537
|
+
paymentItem
|
|
538
|
+
});
|
|
539
|
+
throw error;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* 为某个订单设置一个支付项(兼容性方法)
|
|
544
|
+
* @deprecated 使用 addPaymentItemAsync 替代
|
|
545
|
+
*/
|
|
546
|
+
async pushPaymentAsync(orderUuid, paymentItem) {
|
|
547
|
+
console.warn("[PaymentModule] pushPaymentAsync 已废弃,请使用 addPaymentItemAsync 替代");
|
|
548
|
+
return this.addPaymentItemAsync(orderUuid, paymentItem);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* 删除一个支付项
|
|
552
|
+
*/
|
|
553
|
+
async deletePaymentAsync(orderUuid, paymentUuid) {
|
|
554
|
+
this.logInfo("Starting deletePaymentAsync", { orderUuid, paymentUuid });
|
|
555
|
+
try {
|
|
556
|
+
const order = await this.dbManager.get("order", orderUuid);
|
|
557
|
+
if (!order) {
|
|
558
|
+
throw new Error("订单不存在");
|
|
559
|
+
}
|
|
560
|
+
const index = order.payment.findIndex(
|
|
561
|
+
(payment) => payment.uuid === paymentUuid
|
|
562
|
+
);
|
|
563
|
+
if (index > -1) {
|
|
564
|
+
const deletedPayment = order.payment.splice(index, 1)[0];
|
|
565
|
+
this.recalculateOrderAmount(order);
|
|
566
|
+
await this.dbManager.update("order", order);
|
|
567
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentDeleted, {
|
|
568
|
+
order,
|
|
569
|
+
paymentItem: deletedPayment
|
|
570
|
+
});
|
|
571
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
572
|
+
action: "payment_delete",
|
|
573
|
+
order,
|
|
574
|
+
paymentItem: deletedPayment
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
} catch (error) {
|
|
578
|
+
console.error("[PaymentModule] 删除支付项失败", error);
|
|
579
|
+
throw error;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* 更新一个支付项
|
|
584
|
+
*/
|
|
585
|
+
async updatePaymentAsync(orderUuid, paymentUuid, params) {
|
|
586
|
+
try {
|
|
587
|
+
const order = await this.dbManager.get("order", orderUuid);
|
|
588
|
+
if (!order) {
|
|
589
|
+
throw new Error("订单不存在");
|
|
590
|
+
}
|
|
591
|
+
const paymentItem = order.payment.find(
|
|
592
|
+
(payment) => payment.uuid === paymentUuid
|
|
593
|
+
);
|
|
594
|
+
if (paymentItem) {
|
|
595
|
+
const formattedParams = { ...params };
|
|
596
|
+
if ("amount" in formattedParams && formattedParams.amount !== void 0) {
|
|
597
|
+
formattedParams.amount = formatAmount(formattedParams.amount);
|
|
598
|
+
}
|
|
599
|
+
Object.assign(paymentItem, formattedParams);
|
|
600
|
+
this.recalculateOrderAmount(order);
|
|
601
|
+
await this.dbManager.update("order", order);
|
|
602
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentUpdated, {
|
|
603
|
+
order,
|
|
604
|
+
paymentItem
|
|
605
|
+
});
|
|
606
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
607
|
+
action: "payment_update",
|
|
608
|
+
order,
|
|
609
|
+
paymentItem
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
} catch (error) {
|
|
613
|
+
console.error("[PaymentModule] 更新支付项失败", error);
|
|
614
|
+
throw error;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* 提交支付
|
|
619
|
+
*/
|
|
620
|
+
async submitPayAsync(orderUuid) {
|
|
621
|
+
this.logInfo("Starting submitPayAsync", { orderUuid });
|
|
622
|
+
try {
|
|
623
|
+
let orderToSubmit;
|
|
624
|
+
if (orderUuid) {
|
|
625
|
+
const order = await this.dbManager.get("order", orderUuid);
|
|
626
|
+
orderToSubmit = order ? [order] : [];
|
|
627
|
+
} else {
|
|
628
|
+
const allOrders2 = await this.dbManager.getAll("order");
|
|
629
|
+
orderToSubmit = allOrders2.filter(
|
|
630
|
+
(order) => order.payment_status === import_types.PaymentStatus.Processing || order.payment_status === import_types.PaymentStatus.PartiallyPaid
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
for (const order of orderToSubmit) {
|
|
634
|
+
await this.submitSingleOrderPayment(order);
|
|
635
|
+
}
|
|
636
|
+
await this.runPaymentSyncQueue();
|
|
637
|
+
const allOrders = await this.dbManager.getAll("order");
|
|
638
|
+
const allOrdersProcessed = allOrders.every(
|
|
639
|
+
(order) => order.payment.every((payment) => payment.isSynced === true)
|
|
640
|
+
);
|
|
641
|
+
if (allOrdersProcessed) {
|
|
642
|
+
const result = { status: "success" };
|
|
643
|
+
this.logInfo("submitPayAsync completed", {
|
|
644
|
+
result: result.status,
|
|
645
|
+
processedOrdersCount: allOrders.length
|
|
646
|
+
});
|
|
647
|
+
return result;
|
|
648
|
+
} else {
|
|
649
|
+
this.logWarning("submitPayAsync completed with unprocessed orders", {
|
|
650
|
+
totalOrders: allOrders.length
|
|
651
|
+
});
|
|
652
|
+
return { status: "failed" };
|
|
653
|
+
}
|
|
654
|
+
} catch (error) {
|
|
655
|
+
console.error("[PaymentModule] 提交支付失败", error);
|
|
656
|
+
this.logError("submitPayAsync failed", error, { orderUuid });
|
|
657
|
+
return { status: "failed" };
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* 提交单个订单的支付(推送到任务队列)
|
|
662
|
+
*/
|
|
663
|
+
async submitSingleOrderPayment(order) {
|
|
664
|
+
try {
|
|
665
|
+
const paymentData = {
|
|
666
|
+
payments: order.payment.map((payment) => ({
|
|
667
|
+
uuid: payment.uuid,
|
|
668
|
+
amount: payment.amount,
|
|
669
|
+
code: payment.code,
|
|
670
|
+
id: payment.id,
|
|
671
|
+
name: payment.name,
|
|
672
|
+
type: payment.type,
|
|
673
|
+
voucher_id: payment.voucher_id,
|
|
674
|
+
metadata: payment.metadata,
|
|
675
|
+
rounding_amount: payment.rounding_amount,
|
|
676
|
+
service_charge: payment.service_charge
|
|
677
|
+
})),
|
|
678
|
+
payment_status: "pending"
|
|
679
|
+
};
|
|
680
|
+
const totalPaidAmount = paymentData.payments.reduce(
|
|
681
|
+
(sum, payment) => sum.plus(payment.amount),
|
|
682
|
+
new import_decimal.Decimal(0)
|
|
683
|
+
);
|
|
684
|
+
const orderTotalAmount = new import_decimal.Decimal(order.total_amount);
|
|
685
|
+
if (totalPaidAmount.gte(orderTotalAmount)) {
|
|
686
|
+
order.payment_status = import_types.PaymentStatus.Finished;
|
|
687
|
+
console.log(
|
|
688
|
+
`[PaymentModule] 订单 ${order.uuid} 支付完成,金额: ${totalPaidAmount.toString()}/${orderTotalAmount.toString()}`
|
|
689
|
+
);
|
|
690
|
+
} else {
|
|
691
|
+
order.payment_status = import_types.PaymentStatus.PartiallyPaid;
|
|
692
|
+
console.log(
|
|
693
|
+
`[PaymentModule] 订单 ${order.uuid} 部分支付,金额: ${totalPaidAmount.toString()}/${orderTotalAmount.toString()}`
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
paymentData.payment_status = order.payment_status === import_types.PaymentStatus.Finished ? "paid" : "partially_paid";
|
|
697
|
+
await this.dbManager.update("order", order);
|
|
698
|
+
if (paymentData.payments.length === 0) {
|
|
699
|
+
console.log(`[PaymentModule] 订单 ${order.uuid} 支付列表为空,跳过队列推送`);
|
|
700
|
+
this.logWarning("Empty payment queue submission", {
|
|
701
|
+
orderUuid: order.uuid,
|
|
702
|
+
orderId: order.order_id
|
|
703
|
+
});
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
await this.addToSyncQueue(order, paymentData);
|
|
707
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentSubmitted, order);
|
|
708
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
709
|
+
action: "submit",
|
|
710
|
+
order
|
|
711
|
+
});
|
|
712
|
+
} catch (error) {
|
|
713
|
+
console.error(`[PaymentModule] 订单 ${order.uuid} 支付提交失败`, error);
|
|
714
|
+
throw error;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* 添加到同步任务队列
|
|
719
|
+
*/
|
|
720
|
+
async addToSyncQueue(order, paymentData) {
|
|
721
|
+
try {
|
|
722
|
+
console.log(`[PaymentModule] 订单 ${order.uuid} 已添加到同步队列`);
|
|
723
|
+
if (this.app.tasksManager) {
|
|
724
|
+
this.app.tasksManager.addTask({
|
|
725
|
+
module: "payment",
|
|
726
|
+
queueId: "payment_sync",
|
|
727
|
+
tasks: [
|
|
728
|
+
{
|
|
729
|
+
id: `payment_${order.uuid}`,
|
|
730
|
+
action: "syncPayment",
|
|
731
|
+
payload: {
|
|
732
|
+
orderUuid: order.uuid,
|
|
733
|
+
orderId: order.order_id,
|
|
734
|
+
paymentData,
|
|
735
|
+
core: this.core
|
|
736
|
+
},
|
|
737
|
+
maxRetries: 3,
|
|
738
|
+
type: "cloud"
|
|
739
|
+
}
|
|
740
|
+
]
|
|
741
|
+
});
|
|
742
|
+
console.log(`[PaymentModule] 订单 ${order.uuid} 同步任务已添加到队列`);
|
|
743
|
+
} else {
|
|
744
|
+
console.warn("[PaymentModule] TasksManager 未初始化,无法添加同步任务");
|
|
745
|
+
}
|
|
746
|
+
} catch (error) {
|
|
747
|
+
console.error("[PaymentModule] 添加同步任务失败", error);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* 获取订单剩余待付金额
|
|
752
|
+
*/
|
|
753
|
+
async getRemainingOrderAmountAsync(orderUuid) {
|
|
754
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
755
|
+
if (!order) {
|
|
756
|
+
throw new Error("订单不存在");
|
|
757
|
+
}
|
|
758
|
+
return new import_decimal.Decimal(order.expect_amount).toNumber();
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* 在比如现金支付界面的地方,用户输入了一个金额,在下方显示剩余多少金额,通过此方法获取
|
|
762
|
+
*/
|
|
763
|
+
async getRemainingOrderAmountWithInputAsync(inputAmount, orderUuid) {
|
|
764
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
765
|
+
if (!order) {
|
|
766
|
+
throw new Error("订单不存在");
|
|
767
|
+
}
|
|
768
|
+
if (inputAmount === null || inputAmount === void 0) {
|
|
769
|
+
return new import_decimal.Decimal(order.expect_amount).toNumber();
|
|
770
|
+
}
|
|
771
|
+
if (typeof inputAmount === "string") {
|
|
772
|
+
if (inputAmount.trim() === "") {
|
|
773
|
+
return new import_decimal.Decimal(order.expect_amount).toNumber();
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
if (typeof inputAmount === "number") {
|
|
777
|
+
if (isNaN(inputAmount) || !isFinite(inputAmount)) {
|
|
778
|
+
console.warn(
|
|
779
|
+
`[PaymentModule] 输入金额不是有效数字: ${inputAmount},返回原始待付金额`
|
|
780
|
+
);
|
|
781
|
+
return new import_decimal.Decimal(order.expect_amount).toNumber();
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
try {
|
|
785
|
+
const inputDecimal = new import_decimal.Decimal(inputAmount);
|
|
786
|
+
return new import_decimal.Decimal(order.expect_amount).minus(inputDecimal).toNumber();
|
|
787
|
+
} catch (error) {
|
|
788
|
+
console.warn(
|
|
789
|
+
`[PaymentModule] 输入金额格式无效: ${inputAmount},返回原始待付金额`
|
|
790
|
+
);
|
|
791
|
+
return new import_decimal.Decimal(order.expect_amount).toNumber();
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* 重新计算订单金额
|
|
796
|
+
*/
|
|
797
|
+
recalculateOrderAmount(order) {
|
|
798
|
+
const totalAmount = new import_decimal.Decimal(order.total_amount);
|
|
799
|
+
const paidAmount = order.payment.reduce(
|
|
800
|
+
(sum, payment) => {
|
|
801
|
+
try {
|
|
802
|
+
return sum.plus(payment.amount);
|
|
803
|
+
} catch (error) {
|
|
804
|
+
console.warn(`[PaymentModule] 无效的支付金额: ${payment.amount},跳过计算`);
|
|
805
|
+
return sum;
|
|
806
|
+
}
|
|
807
|
+
},
|
|
808
|
+
new import_decimal.Decimal(0)
|
|
809
|
+
);
|
|
810
|
+
const remainingAmount = totalAmount.minus(paidAmount);
|
|
811
|
+
order.expect_amount = import_decimal.Decimal.max(0, remainingAmount).toFixed(2);
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* 获取现金支付方式
|
|
815
|
+
*/
|
|
816
|
+
async getCashPaymentMethod() {
|
|
817
|
+
try {
|
|
818
|
+
const payMethods = await this.dbManager.getAll("pay_method");
|
|
819
|
+
return payMethods.find(
|
|
820
|
+
(method) => method.code === import_types.PaymentMethodType.Cash
|
|
821
|
+
) || null;
|
|
822
|
+
} catch (error) {
|
|
823
|
+
console.error("[PaymentModule] 获取现金支付方式失败", error);
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* 获取Eftpos支付方式
|
|
829
|
+
*/
|
|
830
|
+
async getEftposPaymentMethod() {
|
|
831
|
+
try {
|
|
832
|
+
const payMethods = await this.dbManager.getAll("pay_method");
|
|
833
|
+
return payMethods.find(
|
|
834
|
+
(method) => method.code === import_types.PaymentMethodType.Eftpos
|
|
835
|
+
) || null;
|
|
836
|
+
} catch (error) {
|
|
837
|
+
console.error("[PaymentModule] 获取Eftpos支付方式失败", error);
|
|
838
|
+
return null;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* 获取钱包支付方式
|
|
843
|
+
*/
|
|
844
|
+
async getWalletPaymentMethod() {
|
|
845
|
+
try {
|
|
846
|
+
const payMethods = await this.dbManager.getAll("pay_method");
|
|
847
|
+
return payMethods.find(
|
|
848
|
+
(method) => method.code === import_types.PaymentMethodType.Wallet
|
|
849
|
+
) || null;
|
|
850
|
+
} catch (error) {
|
|
851
|
+
console.error("[PaymentModule] 获取钱包支付方式失败", error);
|
|
852
|
+
return null;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* 注册任务处理函数
|
|
857
|
+
*/
|
|
858
|
+
registerTaskHandlers() {
|
|
859
|
+
if (this.app.tasksManager) {
|
|
860
|
+
this.app.tasksManager.addTaskFunction(
|
|
861
|
+
"syncPayment",
|
|
862
|
+
PaymentModule.syncPaymentTask
|
|
863
|
+
);
|
|
864
|
+
console.log("[PaymentModule] 任务处理函数已注册");
|
|
865
|
+
} else {
|
|
866
|
+
console.warn(
|
|
867
|
+
"[PaymentModule] TasksManager 未初始化,无法注册任务处理函数"
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* 静态方法:处理支付同步任务(后台网络同步)
|
|
873
|
+
* 这个方法里不允许用 this,因为需要作为静态方法注入到任务队列里
|
|
874
|
+
*/
|
|
875
|
+
static async syncPaymentTask(payload) {
|
|
876
|
+
var _a, _b, _c, _d, _e, _f;
|
|
877
|
+
const { orderUuid, orderId, paymentData, core } = payload.task.payload;
|
|
878
|
+
console.log(`[PaymentModule] 开始后台同步支付,订单ID: ${orderId}`);
|
|
879
|
+
paymentData.request_unique = generateRequestUniqueId();
|
|
880
|
+
const app = window.app;
|
|
881
|
+
const logger = app == null ? void 0 : app.logger;
|
|
882
|
+
if (logger) {
|
|
883
|
+
logger.addLog({
|
|
884
|
+
type: "info",
|
|
885
|
+
title: "[PaymentModule] Starting syncPaymentTask",
|
|
886
|
+
metadata: {
|
|
887
|
+
orderUuid,
|
|
888
|
+
orderId,
|
|
889
|
+
paymentDataKeys: Object.keys(paymentData)
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
if (!app) {
|
|
894
|
+
throw new Error("App 实例未找到");
|
|
895
|
+
}
|
|
896
|
+
const request = app.request;
|
|
897
|
+
if (!request) {
|
|
898
|
+
throw new Error("Request 插件未找到");
|
|
899
|
+
}
|
|
900
|
+
const dbManager = app.dbManager;
|
|
901
|
+
if (!dbManager) {
|
|
902
|
+
throw new Error("DBManager 未找到");
|
|
903
|
+
}
|
|
904
|
+
try {
|
|
905
|
+
const requestRes = await request.post(
|
|
906
|
+
`/shop/order/${orderId}/order-payment`,
|
|
907
|
+
paymentData,
|
|
908
|
+
{ noToast: true }
|
|
909
|
+
);
|
|
910
|
+
if (requestRes.status === true) {
|
|
911
|
+
const order = await dbManager.get("order", orderUuid);
|
|
912
|
+
if (order) {
|
|
913
|
+
order.payment.forEach((payment) => {
|
|
914
|
+
payment.isSynced = true;
|
|
915
|
+
delete payment.syncError;
|
|
916
|
+
});
|
|
917
|
+
await dbManager.update("order", order);
|
|
918
|
+
console.log(`[PaymentModule] 订单 ${orderUuid} 同步状态已更新`);
|
|
919
|
+
}
|
|
920
|
+
console.log(`[PaymentModule] 订单 ${orderUuid} 后台同步成功`);
|
|
921
|
+
await core.effects.emit("payment:onPaymentSyncSuccess", {
|
|
922
|
+
orderUuid,
|
|
923
|
+
orderId,
|
|
924
|
+
timestamp: Date.now()
|
|
925
|
+
});
|
|
926
|
+
console.log(
|
|
927
|
+
`[PaymentModule] 已通过 effects 通知前端订单 ${orderUuid} 同步成功`
|
|
928
|
+
);
|
|
929
|
+
if (logger) {
|
|
930
|
+
logger.addLog({
|
|
931
|
+
type: "info",
|
|
932
|
+
title: "[PaymentModule] syncPaymentTask completed successfully",
|
|
933
|
+
metadata: { orderUuid, orderId }
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
return { status: "success", orderUuid, orderId };
|
|
937
|
+
} else {
|
|
938
|
+
console.log(`[PaymentModule] 接口返回失败,订单 ${orderUuid} 同步失败`);
|
|
939
|
+
const businessError = new Error(requestRes.message || "接口返回失败");
|
|
940
|
+
businessError.response = { status: 200 };
|
|
941
|
+
businessError.isBusinessError = true;
|
|
942
|
+
businessError.responseData = requestRes;
|
|
943
|
+
throw businessError;
|
|
944
|
+
}
|
|
945
|
+
} catch (error) {
|
|
946
|
+
console.error("[PaymentModule] 后台同步失败:", error);
|
|
947
|
+
const isNetworkError = !error.response && !error.status && (error.code === "NETWORK_ERROR" || error.code === "ERR_NETWORK" || error.code === "ECONNREFUSED" || error.code === "ENOTFOUND" || error.code === "ETIMEDOUT" || ((_a = error.message) == null ? void 0 : _a.includes("网络")) || ((_b = error.message) == null ? void 0 : _b.includes("network")) || ((_c = error.message) == null ? void 0 : _c.includes("fetch")));
|
|
948
|
+
if (isNetworkError) {
|
|
949
|
+
console.log(`[PaymentModule] 网络错误,订单 ${orderUuid} 将重试同步`);
|
|
950
|
+
if (logger) {
|
|
951
|
+
logger.addLog({
|
|
952
|
+
type: "warning",
|
|
953
|
+
title: "[PaymentModule] syncPaymentTask network error - will retry",
|
|
954
|
+
metadata: {
|
|
955
|
+
orderUuid,
|
|
956
|
+
orderId,
|
|
957
|
+
errorCode: error.code,
|
|
958
|
+
errorMessage: error.message
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
throw error;
|
|
963
|
+
} else {
|
|
964
|
+
console.log(
|
|
965
|
+
`[PaymentModule] 业务错误,订单 ${orderUuid} 同步失败,通知前端`
|
|
966
|
+
);
|
|
967
|
+
try {
|
|
968
|
+
if (core && core.effects) {
|
|
969
|
+
const errorData = {
|
|
970
|
+
orderUuid,
|
|
971
|
+
orderId,
|
|
972
|
+
error: error.message || "业务错误",
|
|
973
|
+
errorCode: error.code,
|
|
974
|
+
statusCode: ((_d = error.response) == null ? void 0 : _d.status) || error.status,
|
|
975
|
+
timestamp: Date.now()
|
|
976
|
+
};
|
|
977
|
+
if (error.isBusinessError && error.responseData) {
|
|
978
|
+
errorData.error = error.responseData.message || error.message || "接口返回失败";
|
|
979
|
+
errorData.responseData = error.responseData;
|
|
980
|
+
}
|
|
981
|
+
await core.effects.emit("payment:onPaymentSyncError", errorData);
|
|
982
|
+
console.log(
|
|
983
|
+
`[PaymentModule] 已通过 effects 通知前端订单 ${orderUuid} 同步错误`
|
|
984
|
+
);
|
|
985
|
+
} else {
|
|
986
|
+
console.warn(
|
|
987
|
+
`[PaymentModule] 无法获取 core 实例,无法通知前端错误`
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
if (logger) {
|
|
991
|
+
logger.addLog({
|
|
992
|
+
type: "error",
|
|
993
|
+
title: "[PaymentModule] syncPaymentTask business error",
|
|
994
|
+
metadata: {
|
|
995
|
+
orderUuid,
|
|
996
|
+
orderId,
|
|
997
|
+
errorCode: error.code,
|
|
998
|
+
errorMessage: error.message,
|
|
999
|
+
statusCode: ((_e = error.response) == null ? void 0 : _e.status) || error.status,
|
|
1000
|
+
isBusinessError: error.isBusinessError
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
} catch (notifyError) {
|
|
1005
|
+
console.error(`[PaymentModule] 通知前端同步错误失败:`, notifyError);
|
|
1006
|
+
if (logger) {
|
|
1007
|
+
logger.addLog({
|
|
1008
|
+
type: "error",
|
|
1009
|
+
title: "[PaymentModule] Failed to notify frontend of sync error",
|
|
1010
|
+
metadata: {
|
|
1011
|
+
orderUuid,
|
|
1012
|
+
orderId,
|
|
1013
|
+
notifyError: notifyError instanceof Error ? notifyError.message : String(notifyError)
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
const order = await dbManager.get("order", orderUuid);
|
|
1019
|
+
if (order) {
|
|
1020
|
+
order.payment.forEach((payment) => {
|
|
1021
|
+
payment.isSynced = true;
|
|
1022
|
+
});
|
|
1023
|
+
await dbManager.update("order", order);
|
|
1024
|
+
console.log(
|
|
1025
|
+
`[PaymentModule] 订单 ${orderUuid} 业务错误,已标记为已同步`
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
return {
|
|
1029
|
+
status: "completed_with_error",
|
|
1030
|
+
orderUuid,
|
|
1031
|
+
orderId,
|
|
1032
|
+
error: error.message || "业务错误",
|
|
1033
|
+
statusCode: ((_f = error.response) == null ? void 0 : _f.status) || error.status
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* 确保支付模块所需的数据库表已创建
|
|
1040
|
+
*/
|
|
1041
|
+
async ensurePaymentTables() {
|
|
1042
|
+
try {
|
|
1043
|
+
await this.dbManager.getAll("pay_method");
|
|
1044
|
+
} catch (error) {
|
|
1045
|
+
console.warn(
|
|
1046
|
+
"[PaymentModule] pay_method 表不存在,请在数据库配置中添加以下配置:"
|
|
1047
|
+
);
|
|
1048
|
+
console.warn('{ name: "pay_method", keyPath: "id" }');
|
|
1049
|
+
}
|
|
1050
|
+
try {
|
|
1051
|
+
await this.dbManager.getAll("order");
|
|
1052
|
+
} catch (error) {
|
|
1053
|
+
console.warn(
|
|
1054
|
+
"[PaymentModule] order 表不存在,请在数据库配置中添加以下配置:"
|
|
1055
|
+
);
|
|
1056
|
+
console.warn('{ name: "order", keyPath: "uuid" }');
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* 获取部分支付的订单
|
|
1061
|
+
*/
|
|
1062
|
+
async getPartiallyPaidOrdersAsync() {
|
|
1063
|
+
try {
|
|
1064
|
+
const allOrders = await this.dbManager.getAll("order");
|
|
1065
|
+
return allOrders.filter(
|
|
1066
|
+
(order) => order.payment_status === import_types.PaymentStatus.PartiallyPaid
|
|
1067
|
+
);
|
|
1068
|
+
} catch (error) {
|
|
1069
|
+
console.error("[PaymentModule] 获取部分支付订单失败", error);
|
|
1070
|
+
return [];
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
/**
|
|
1074
|
+
* 获取未同步到服务器的订单
|
|
1075
|
+
*/
|
|
1076
|
+
async getUnsyncedOrdersAsync() {
|
|
1077
|
+
try {
|
|
1078
|
+
const allOrders = await this.dbManager.getAll("order");
|
|
1079
|
+
return allOrders.filter((order) => {
|
|
1080
|
+
return (order.payment_status === import_types.PaymentStatus.Finished || order.payment_status === import_types.PaymentStatus.PartiallyPaid) && order.payment.some((payment) => !payment.isSynced);
|
|
1081
|
+
});
|
|
1082
|
+
} catch (error) {
|
|
1083
|
+
console.error("[PaymentModule] 获取未同步订单失败", error);
|
|
1084
|
+
return [];
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* 清理已完成且已同步的订单
|
|
1089
|
+
* 注意:只清理完全支付的订单,部分支付的订单保留以便继续支付
|
|
1090
|
+
*/
|
|
1091
|
+
async cleanupFinishedOrders() {
|
|
1092
|
+
try {
|
|
1093
|
+
const allOrders = await this.dbManager.getAll("order");
|
|
1094
|
+
const finishedAndSyncedOrders = allOrders.filter(
|
|
1095
|
+
(order) => order.payment_status === import_types.PaymentStatus.Finished && order.payment.every((payment) => payment.isSynced)
|
|
1096
|
+
);
|
|
1097
|
+
for (const order of finishedAndSyncedOrders) {
|
|
1098
|
+
await this.deleteOrderAsync(order.uuid);
|
|
1099
|
+
}
|
|
1100
|
+
console.log(
|
|
1101
|
+
`[PaymentModule] 清理了 ${finishedAndSyncedOrders.length} 个已完成且已同步的订单`
|
|
1102
|
+
);
|
|
1103
|
+
} catch (error) {
|
|
1104
|
+
console.error("[PaymentModule] 清理已完成订单失败", error);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* 检测未同步的订单并重新加入任务队列
|
|
1109
|
+
*
|
|
1110
|
+
* 此方法专门用于处理因网络问题导致任务队列执行失败但队列被清空的情况。
|
|
1111
|
+
* 它会检查本地 IndexDB 中所有未同步的订单(isSynced: false),
|
|
1112
|
+
* 并将这些订单重新添加到任务队列中。
|
|
1113
|
+
*
|
|
1114
|
+
* 使用场景:
|
|
1115
|
+
* - 网络恢复后重新检查未同步的订单
|
|
1116
|
+
* - 应用启动时检查并重新排队未完成的支付
|
|
1117
|
+
* - 用户手动重试前的预检查
|
|
1118
|
+
*
|
|
1119
|
+
* @returns Promise<number> 返回重新加入队列的订单数量
|
|
1120
|
+
*/
|
|
1121
|
+
async recheckAndRequeueUnsyncedOrders() {
|
|
1122
|
+
this.logInfo("Starting recheckAndRequeueUnsyncedOrders");
|
|
1123
|
+
try {
|
|
1124
|
+
if (!this.app.tasksManager) {
|
|
1125
|
+
console.warn(
|
|
1126
|
+
"[PaymentModule] TasksManager 未初始化,无法重新排队未同步订单"
|
|
1127
|
+
);
|
|
1128
|
+
this.logWarning(
|
|
1129
|
+
"TasksManager not initialized, cannot requeue unsynced orders"
|
|
1130
|
+
);
|
|
1131
|
+
return 0;
|
|
1132
|
+
}
|
|
1133
|
+
const unsyncedOrders = await this.getUnsyncedOrdersAsync();
|
|
1134
|
+
if (unsyncedOrders.length === 0) {
|
|
1135
|
+
console.log("[PaymentModule] 没有发现未同步的订单");
|
|
1136
|
+
this.logInfo("No unsynced orders found");
|
|
1137
|
+
return 0;
|
|
1138
|
+
}
|
|
1139
|
+
console.log(
|
|
1140
|
+
`[PaymentModule] 发现 ${unsyncedOrders.length} 个未同步的订单,开始重新加入任务队列`
|
|
1141
|
+
);
|
|
1142
|
+
this.logInfo("Found unsynced orders, adding to sync queue", {
|
|
1143
|
+
unsyncedCount: unsyncedOrders.length,
|
|
1144
|
+
orderUuids: unsyncedOrders.map((o) => o.uuid)
|
|
1145
|
+
});
|
|
1146
|
+
let requeuedCount = 0;
|
|
1147
|
+
for (const order of unsyncedOrders) {
|
|
1148
|
+
const success = await this.reAddOrderToSyncQueue(order);
|
|
1149
|
+
if (success) {
|
|
1150
|
+
requeuedCount++;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
console.log(
|
|
1154
|
+
`[PaymentModule] 成功重新加入 ${requeuedCount} 个订单到任务队列`
|
|
1155
|
+
);
|
|
1156
|
+
this.logInfo("Successfully requeued unsynced orders", {
|
|
1157
|
+
requeuedCount,
|
|
1158
|
+
totalFound: unsyncedOrders.length
|
|
1159
|
+
});
|
|
1160
|
+
return requeuedCount;
|
|
1161
|
+
} catch (error) {
|
|
1162
|
+
console.error("[PaymentModule] 重新排队未同步订单失败", error);
|
|
1163
|
+
this.logError("recheckAndRequeueUnsyncedOrders failed", error);
|
|
1164
|
+
return 0;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
/**
|
|
1168
|
+
* 手动执行支付同步队列
|
|
1169
|
+
* 外部可以调用此方法来触发支付同步任务的执行
|
|
1170
|
+
*
|
|
1171
|
+
* 注意:此方法只执行现有队列中的任务,不会检查未同步的订单。
|
|
1172
|
+
* 如果需要检查未同步订单,请先调用 recheckAndRequeueUnsyncedOrders()
|
|
1173
|
+
*
|
|
1174
|
+
* 使用示例:
|
|
1175
|
+
* ```typescript
|
|
1176
|
+
* // 1. 先检查并重新排队未同步订单,然后执行队列
|
|
1177
|
+
* const requeuedCount = await paymentModule.recheckAndRequeueUnsyncedOrders();
|
|
1178
|
+
* if (requeuedCount > 0) {
|
|
1179
|
+
* await paymentModule.runPaymentSyncQueue();
|
|
1180
|
+
* }
|
|
1181
|
+
*
|
|
1182
|
+
* // 2. 或者直接执行现有队列(不检查未同步订单)
|
|
1183
|
+
* await paymentModule.runPaymentSyncQueue();
|
|
1184
|
+
* ```
|
|
1185
|
+
*/
|
|
1186
|
+
async runPaymentSyncQueue() {
|
|
1187
|
+
this.logInfo("Starting runPaymentSyncQueue");
|
|
1188
|
+
try {
|
|
1189
|
+
if (!this.app.tasksManager) {
|
|
1190
|
+
console.warn("[PaymentModule] TasksManager 未初始化,无法执行同步队列");
|
|
1191
|
+
this.logWarning("TasksManager not initialized, cannot run sync queue");
|
|
1192
|
+
return;
|
|
1193
|
+
}
|
|
1194
|
+
const queue = this.app.tasksManager.getTaskQueue({
|
|
1195
|
+
module: "payment",
|
|
1196
|
+
queueId: "payment_sync"
|
|
1197
|
+
});
|
|
1198
|
+
if (!(queue == null ? void 0 : queue.length)) {
|
|
1199
|
+
console.log("[PaymentModule] 支付同步队列无内容,不执行");
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
console.log("[PaymentModule] 开始执行支付同步队列");
|
|
1203
|
+
await this.app.tasksManager.run({
|
|
1204
|
+
module: "payment",
|
|
1205
|
+
queueId: "payment_sync",
|
|
1206
|
+
callback: () => {
|
|
1207
|
+
console.log("[PaymentModule] 支付同步队列执行完成");
|
|
1208
|
+
if (this.logger) {
|
|
1209
|
+
this.logger.addLog({
|
|
1210
|
+
type: "info",
|
|
1211
|
+
title: "[PaymentModule] Payment sync queue completed",
|
|
1212
|
+
metadata: {}
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
});
|
|
1217
|
+
this.logInfo("runPaymentSyncQueue completed successfully");
|
|
1218
|
+
} catch (error) {
|
|
1219
|
+
console.error("[PaymentModule] 执行支付同步队列失败", error);
|
|
1220
|
+
this.logError("runPaymentSyncQueue failed", error);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* 重新将订单添加到同步队列
|
|
1225
|
+
* 用于处理因网络问题导致任务队列清空但订单未同步的情况
|
|
1226
|
+
*
|
|
1227
|
+
* @param order 要重新添加的订单
|
|
1228
|
+
* @returns Promise<boolean> 是否成功添加到队列
|
|
1229
|
+
*/
|
|
1230
|
+
async reAddOrderToSyncQueue(order) {
|
|
1231
|
+
try {
|
|
1232
|
+
const paymentData = {
|
|
1233
|
+
payments: order.payment.map((payment) => ({
|
|
1234
|
+
uuid: payment.uuid,
|
|
1235
|
+
amount: payment.amount,
|
|
1236
|
+
code: payment.code,
|
|
1237
|
+
id: payment.id,
|
|
1238
|
+
name: payment.name,
|
|
1239
|
+
type: payment.type,
|
|
1240
|
+
voucher_id: payment.voucher_id,
|
|
1241
|
+
metadata: payment.metadata,
|
|
1242
|
+
rounding_amount: payment.rounding_amount,
|
|
1243
|
+
service_charge: payment.service_charge
|
|
1244
|
+
})),
|
|
1245
|
+
payment_status: order.payment_status === import_types.PaymentStatus.Finished ? "paid" : "partially_paid"
|
|
1246
|
+
};
|
|
1247
|
+
const existingQueue = this.app.tasksManager.getTaskQueue({
|
|
1248
|
+
module: "payment",
|
|
1249
|
+
queueId: "payment_sync"
|
|
1250
|
+
});
|
|
1251
|
+
const taskId = `payment_${order.uuid}`;
|
|
1252
|
+
const taskExists = existingQueue == null ? void 0 : existingQueue.some((task) => task.id === taskId);
|
|
1253
|
+
if (taskExists) {
|
|
1254
|
+
console.log(
|
|
1255
|
+
`[PaymentModule] 任务 ${taskId} 已存在于队列中,跳过重复添加`
|
|
1256
|
+
);
|
|
1257
|
+
return false;
|
|
1258
|
+
}
|
|
1259
|
+
await this.addToSyncQueue(order, paymentData);
|
|
1260
|
+
console.log(`[PaymentModule] 订单 ${order.uuid} 已重新添加到同步队列`);
|
|
1261
|
+
this.logInfo("Order re-added to sync queue", {
|
|
1262
|
+
orderUuid: order.uuid,
|
|
1263
|
+
orderId: order.order_id,
|
|
1264
|
+
paymentStatus: order.payment_status,
|
|
1265
|
+
unsyncedPayments: order.payment.filter((p) => !p.isSynced).length
|
|
1266
|
+
});
|
|
1267
|
+
return true;
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
console.error(
|
|
1270
|
+
`[PaymentModule] 重新添加订单 ${order.uuid} 到同步队列失败`,
|
|
1271
|
+
error
|
|
1272
|
+
);
|
|
1273
|
+
this.logError("Failed to re-add order to sync queue", error, {
|
|
1274
|
+
orderUuid: order.uuid,
|
|
1275
|
+
orderId: order.order_id
|
|
1276
|
+
});
|
|
1277
|
+
return false;
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
// === 新的 API 方法实现 ===
|
|
1281
|
+
/**
|
|
1282
|
+
* 删除支付项(新方法)
|
|
1283
|
+
*/
|
|
1284
|
+
async deletePaymentItemAsync(orderUuid, paymentUuid) {
|
|
1285
|
+
console.warn("[PaymentModule] deletePaymentItemAsync 暂时使用 deletePaymentAsync 实现");
|
|
1286
|
+
return this.deletePaymentAsync(orderUuid, paymentUuid);
|
|
1287
|
+
}
|
|
1288
|
+
/**
|
|
1289
|
+
* 更新支付项(新方法)
|
|
1290
|
+
*/
|
|
1291
|
+
async updatePaymentItemAsync(orderUuid, paymentUuid, params) {
|
|
1292
|
+
console.warn("[PaymentModule] updatePaymentItemAsync 暂时使用 updatePaymentAsync 实现");
|
|
1293
|
+
return this.updatePaymentAsync(orderUuid, paymentUuid, params);
|
|
1294
|
+
}
|
|
1295
|
+
/**
|
|
1296
|
+
* 获取订单剩余待付金额(新方法)
|
|
1297
|
+
*/
|
|
1298
|
+
async getRemainingAmountAsync(orderUuid) {
|
|
1299
|
+
console.warn("[PaymentModule] getRemainingAmountAsync 暂时使用 getRemainingOrderAmountAsync 实现");
|
|
1300
|
+
return this.getRemainingOrderAmountAsync(orderUuid);
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* 获取订单剩余待付金额(基于用户输入的金额)(新方法)
|
|
1304
|
+
*/
|
|
1305
|
+
async getRemainingAmountWithInputAsync(inputAmount, orderUuid) {
|
|
1306
|
+
console.warn("[PaymentModule] getRemainingAmountWithInputAsync 暂时使用 getRemainingOrderAmountWithInputAsync 实现");
|
|
1307
|
+
return this.getRemainingOrderAmountWithInputAsync(inputAmount, orderUuid);
|
|
1308
|
+
}
|
|
1309
|
+
/**
|
|
1310
|
+
* 提交支付(新方法)
|
|
1311
|
+
*/
|
|
1312
|
+
async submitPaymentAsync(orderUuid) {
|
|
1313
|
+
console.warn("[PaymentModule] submitPaymentAsync 暂时使用 submitPayAsync 实现");
|
|
1314
|
+
return this.submitPayAsync(orderUuid);
|
|
82
1315
|
}
|
|
83
1316
|
};
|
|
84
1317
|
// Annotate the CommonJS export names for ESM import in node:
|
|
85
1318
|
0 && (module.exports = {
|
|
86
|
-
PaymentModule
|
|
1319
|
+
PaymentModule,
|
|
1320
|
+
generateRequestUniqueId,
|
|
1321
|
+
...require("./types")
|
|
87
1322
|
});
|