@pisell/pisellos 0.0.229 → 0.0.231
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/modules/Order/index.d.ts +13 -2
- package/dist/modules/Order/index.js +84 -1
- package/dist/modules/Order/types.d.ts +43 -0
- package/dist/modules/Order/types.js +8 -0
- package/dist/modules/Payment/cash.d.ts +8 -0
- package/dist/modules/Payment/cash.js +20 -1
- package/dist/modules/Payment/cashRecommendationAlgorithm.d.ts +22 -0
- package/dist/modules/Payment/cashRecommendationAlgorithm.js +423 -0
- package/dist/modules/Payment/eftpos.js +1 -1
- package/dist/modules/Payment/index.d.ts +57 -94
- package/dist/modules/Payment/index.js +810 -1109
- package/dist/modules/Payment/mx51.d.ts +0 -0
- package/dist/modules/Payment/mx51.js +0 -0
- package/dist/modules/Payment/types.d.ts +358 -50
- package/dist/modules/Payment/types.js +103 -4
- package/dist/modules/Payment/utils.d.ts +17 -0
- package/dist/modules/Payment/utils.js +62 -0
- package/dist/modules/Payment/walletpass.d.ts +96 -0
- package/dist/modules/Payment/walletpass.js +492 -0
- package/dist/modules/Schedule/index.d.ts +9 -0
- package/dist/modules/Schedule/index.js +60 -0
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/Checkout/appointmentDemo.json +1 -0
- package/dist/solution/Checkout/index.d.ts +415 -0
- package/dist/solution/Checkout/index.js +3622 -0
- package/dist/solution/Checkout/types.d.ts +737 -0
- package/dist/solution/Checkout/types.js +137 -0
- package/dist/solution/Checkout/utils/index.d.ts +73 -0
- package/dist/{modules/Payment/wallet.js → solution/Checkout/utils/index.js} +363 -70
- package/dist/solution/index.d.ts +1 -0
- package/dist/solution/index.js +2 -1
- package/lib/modules/Order/index.d.ts +13 -2
- package/lib/modules/Order/index.js +58 -1
- package/lib/modules/Order/types.d.ts +43 -0
- package/lib/modules/Payment/cash.d.ts +8 -0
- package/lib/modules/Payment/cash.js +14 -1
- package/lib/modules/Payment/cashRecommendationAlgorithm.d.ts +22 -0
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +342 -0
- package/lib/modules/Payment/eftpos.js +1 -1
- package/lib/modules/Payment/index.d.ts +57 -94
- package/lib/modules/Payment/index.js +363 -525
- package/lib/modules/Payment/mx51.d.ts +0 -0
- package/lib/modules/Payment/mx51.js +0 -0
- package/lib/modules/Payment/types.d.ts +358 -50
- package/lib/modules/Payment/types.js +37 -2
- package/lib/modules/Payment/utils.d.ts +17 -0
- package/lib/modules/Payment/utils.js +67 -0
- package/lib/modules/Payment/walletpass.d.ts +96 -0
- package/lib/modules/Payment/walletpass.js +304 -0
- package/lib/modules/Schedule/index.d.ts +9 -0
- package/lib/modules/Schedule/index.js +36 -0
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/Checkout/appointmentDemo.json +1 -0
- package/lib/solution/Checkout/index.d.ts +415 -0
- package/lib/solution/Checkout/index.js +2107 -0
- package/lib/solution/Checkout/types.d.ts +737 -0
- package/lib/solution/Checkout/types.js +80 -0
- package/lib/solution/Checkout/utils/index.d.ts +73 -0
- package/lib/solution/Checkout/utils/index.js +266 -0
- package/lib/solution/index.d.ts +1 -0
- package/lib/solution/index.js +3 -1
- package/package.json +1 -1
- package/dist/modules/Payment/wallet.d.ts +0 -11
- package/lib/modules/Payment/wallet.d.ts +0 -11
- package/lib/modules/Payment/wallet.js +0 -51
|
@@ -29,7 +29,7 @@ var import_types = require("./types");
|
|
|
29
29
|
var import_utils = require("../Cart/utils");
|
|
30
30
|
var import_cash = require("./cash");
|
|
31
31
|
var import_eftpos = require("./eftpos");
|
|
32
|
-
var
|
|
32
|
+
var import_walletpass = require("./walletpass");
|
|
33
33
|
var import_decimal = require("decimal.js");
|
|
34
34
|
__reExport(Payment_exports, require("./types"), module.exports);
|
|
35
35
|
function formatAmount(amount) {
|
|
@@ -60,7 +60,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
60
60
|
this.defaultVersion = "1.0.0";
|
|
61
61
|
this.cash = new import_cash.CashPaymentImpl(this);
|
|
62
62
|
this.eftpos = new import_eftpos.EftposPaymentImpl(this);
|
|
63
|
-
this.wallet = new
|
|
63
|
+
this.wallet = new import_walletpass.WalletPassPaymentImpl(this);
|
|
64
64
|
}
|
|
65
65
|
async initialize(core, options) {
|
|
66
66
|
this.core = core;
|
|
@@ -77,7 +77,6 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
77
77
|
this.dbManager = this.app.dbManager;
|
|
78
78
|
this.logger = this.app.logger;
|
|
79
79
|
await this.ensurePaymentTables();
|
|
80
|
-
this.registerTaskHandlers();
|
|
81
80
|
this.registerNetworkHandlers();
|
|
82
81
|
console.log("[PaymentModule] 初始化完成");
|
|
83
82
|
this.logInfo("PaymentModule initialized successfully");
|
|
@@ -152,11 +151,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
152
151
|
previousStatus: status.previousStatus
|
|
153
152
|
});
|
|
154
153
|
if (status.connected) {
|
|
155
|
-
this.logInfo("Network reconnected
|
|
156
|
-
const requeuedCount = await this.recheckAndRequeueUnsyncedOrders();
|
|
157
|
-
if (requeuedCount > 0) {
|
|
158
|
-
await this.runPaymentSyncQueue();
|
|
159
|
-
}
|
|
154
|
+
this.logInfo("Network reconnected");
|
|
160
155
|
}
|
|
161
156
|
});
|
|
162
157
|
}
|
|
@@ -177,7 +172,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
177
172
|
this.refreshPaymentMethodsInBackground(cachedMethods);
|
|
178
173
|
return cachedMethods;
|
|
179
174
|
}
|
|
180
|
-
const response = await this.request.get("/pay/custom-payment/available");
|
|
175
|
+
const response = await this.request.get("/pay/custom-payment/available", { channel: "pos" });
|
|
181
176
|
const payMethods = response.data || [];
|
|
182
177
|
try {
|
|
183
178
|
for (const method of payMethods) {
|
|
@@ -210,7 +205,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
210
205
|
});
|
|
211
206
|
try {
|
|
212
207
|
console.log("[PaymentModule] 后台刷新支付方式列表...");
|
|
213
|
-
const response = await this.request.get("/pay/custom-payment/available");
|
|
208
|
+
const response = await this.request.get("/pay/custom-payment/available", { channel: "pos" });
|
|
214
209
|
const newPayMethods = response.data || [];
|
|
215
210
|
const hasChanges = this.hasPaymentMethodsChanged(
|
|
216
211
|
cachedMethods,
|
|
@@ -280,96 +275,89 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
280
275
|
}
|
|
281
276
|
}
|
|
282
277
|
/**
|
|
283
|
-
*
|
|
278
|
+
* 根据订单UUID获取支付订单(新方法)
|
|
284
279
|
*/
|
|
285
|
-
async
|
|
280
|
+
async getPaymentOrderByUuidAsync(orderUuid) {
|
|
286
281
|
try {
|
|
287
282
|
return await this.dbManager.get("order", orderUuid);
|
|
288
283
|
} catch (error) {
|
|
289
|
-
console.error("[PaymentModule]
|
|
284
|
+
console.error("[PaymentModule] 获取支付订单失败", error);
|
|
290
285
|
return null;
|
|
291
286
|
}
|
|
292
287
|
}
|
|
293
288
|
/**
|
|
294
|
-
*
|
|
289
|
+
* 创建支付订单(新方法,专注支付数据)
|
|
295
290
|
*/
|
|
296
|
-
async
|
|
297
|
-
this.logInfo("Starting
|
|
298
|
-
orderId: params.
|
|
299
|
-
totalAmount: params.
|
|
291
|
+
async createPaymentOrderAsync(params) {
|
|
292
|
+
this.logInfo("Starting createPaymentOrderAsync", {
|
|
293
|
+
orderId: params.order_id,
|
|
294
|
+
totalAmount: params.total_amount
|
|
300
295
|
});
|
|
301
296
|
try {
|
|
302
297
|
const existingOrders = await this.dbManager.getAll("order");
|
|
303
298
|
const existingOrder = existingOrders.find(
|
|
304
|
-
(order) => order.id === params.
|
|
299
|
+
(order) => String(order.id) === String(params.order_id)
|
|
305
300
|
);
|
|
306
301
|
if (existingOrder) {
|
|
307
302
|
console.log(
|
|
308
|
-
`[PaymentModule] 发现重复订单 ID: ${params.
|
|
303
|
+
`[PaymentModule] 发现重复订单 ID: ${params.order_id},更新现有支付订单`
|
|
309
304
|
);
|
|
310
305
|
const originalOrder = { ...existingOrder };
|
|
311
306
|
existingOrder.order_info = params.order_info;
|
|
312
|
-
existingOrder.total_amount = params.
|
|
307
|
+
existingOrder.total_amount = params.total_amount;
|
|
308
|
+
existingOrder.is_deposit = params.is_deposit || 0;
|
|
309
|
+
existingOrder.deposit_amount = params.deposit_amount || "0.00";
|
|
313
310
|
this.recalculateOrderAmount(existingOrder);
|
|
314
311
|
await this.dbManager.update("order", existingOrder);
|
|
315
312
|
await this.core.effects.emit(
|
|
316
313
|
import_types.PaymentHooks.OnOrderUpdated,
|
|
317
314
|
existingOrder
|
|
318
315
|
);
|
|
319
|
-
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
320
|
-
action: "update",
|
|
321
|
-
order: existingOrder,
|
|
322
|
-
originalOrder
|
|
323
|
-
});
|
|
324
316
|
return existingOrder;
|
|
325
317
|
} else {
|
|
326
318
|
const newOrder = {
|
|
327
319
|
uuid: (0, import_utils.getUniqueId)("pay_order_"),
|
|
328
|
-
id: params.
|
|
320
|
+
id: params.order_id,
|
|
321
|
+
order_id: params.order_id,
|
|
329
322
|
order_info: params.order_info,
|
|
330
323
|
payment_status: import_types.PaymentStatus.Processing,
|
|
331
324
|
payment: [],
|
|
332
325
|
adjust_offline_payments: [],
|
|
333
|
-
total_amount: params.
|
|
334
|
-
expect_amount: params.
|
|
335
|
-
tax_fee: "0.00"
|
|
326
|
+
total_amount: params.total_amount,
|
|
327
|
+
expect_amount: params.total_amount,
|
|
328
|
+
tax_fee: "0.00",
|
|
329
|
+
is_deposit: params.is_deposit || 0,
|
|
330
|
+
deposit_amount: params.deposit_amount || "0.00"
|
|
336
331
|
};
|
|
337
332
|
await this.dbManager.add("order", newOrder);
|
|
338
333
|
await this.core.effects.emit(import_types.PaymentHooks.OnOrderAdded, newOrder);
|
|
339
|
-
|
|
340
|
-
action: "add",
|
|
341
|
-
order: newOrder
|
|
342
|
-
});
|
|
343
|
-
this.logInfo("pushOrderAsync completed - new order created", {
|
|
334
|
+
this.logInfo("createPaymentOrderAsync completed - new payment order created", {
|
|
344
335
|
orderUuid: newOrder.uuid,
|
|
345
336
|
orderId: newOrder.id
|
|
346
337
|
});
|
|
347
338
|
return newOrder;
|
|
348
339
|
}
|
|
349
340
|
} catch (error) {
|
|
350
|
-
console.error("[PaymentModule]
|
|
351
|
-
this.logError("
|
|
352
|
-
orderId: params.
|
|
341
|
+
console.error("[PaymentModule] 创建支付订单失败", error);
|
|
342
|
+
this.logError("createPaymentOrderAsync failed", error, {
|
|
343
|
+
orderId: params.order_id
|
|
353
344
|
});
|
|
354
345
|
throw error;
|
|
355
346
|
}
|
|
356
347
|
}
|
|
357
348
|
/**
|
|
358
|
-
*
|
|
349
|
+
* 删除支付订单(新方法)
|
|
359
350
|
*/
|
|
360
|
-
async
|
|
351
|
+
async deletePaymentOrderAsync(orderUuid) {
|
|
361
352
|
try {
|
|
362
353
|
const order = await this.dbManager.get("order", orderUuid);
|
|
363
354
|
if (order) {
|
|
364
355
|
await this.dbManager.delete("order", orderUuid);
|
|
365
356
|
await this.core.effects.emit(import_types.PaymentHooks.OnOrderDeleted, order);
|
|
366
|
-
|
|
367
|
-
action: "delete",
|
|
368
|
-
order
|
|
369
|
-
});
|
|
357
|
+
console.log("[PaymentModule] 支付订单删除成功:", orderUuid);
|
|
370
358
|
}
|
|
371
359
|
} catch (error) {
|
|
372
|
-
console.error("[PaymentModule]
|
|
360
|
+
console.error("[PaymentModule] 删除支付订单失败", error);
|
|
373
361
|
throw error;
|
|
374
362
|
}
|
|
375
363
|
}
|
|
@@ -395,56 +383,154 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
395
383
|
}
|
|
396
384
|
}
|
|
397
385
|
/**
|
|
398
|
-
*
|
|
386
|
+
* 基于UUID替换订单ID
|
|
387
|
+
*
|
|
388
|
+
* 此方法用于将本地虚拟订单ID替换为真实的订单ID。
|
|
389
|
+
* 当前端模拟下单流程完成后,后端返回真实订单ID时调用此方法。
|
|
390
|
+
*
|
|
391
|
+
* @param orderUuid 订单的UUID
|
|
392
|
+
* @param newOrderId 新的订单ID (来自后端)
|
|
393
|
+
* @returns 更新后的订单对象,如果订单不存在则返回null
|
|
399
394
|
*/
|
|
400
|
-
async
|
|
395
|
+
async replaceOrderIdByUuidAsync(orderUuid, newOrderId) {
|
|
396
|
+
this.logInfo("Starting replaceOrderIdByUuidAsync", {
|
|
397
|
+
orderUuid,
|
|
398
|
+
newOrderId
|
|
399
|
+
});
|
|
400
|
+
try {
|
|
401
|
+
const existingOrder = await this.dbManager.get("order", orderUuid);
|
|
402
|
+
if (!existingOrder) {
|
|
403
|
+
this.logWarning("Order not found for UUID replacement", { orderUuid });
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
const allOrders = await this.dbManager.getAll("order");
|
|
407
|
+
const duplicateOrder = allOrders.find(
|
|
408
|
+
(order) => String(order.order_id) === String(newOrderId) && order.uuid !== orderUuid
|
|
409
|
+
);
|
|
410
|
+
if (duplicateOrder) {
|
|
411
|
+
this.logWarning("New order ID already exists", {
|
|
412
|
+
newOrderId,
|
|
413
|
+
existingOrderUuid: duplicateOrder.uuid
|
|
414
|
+
});
|
|
415
|
+
throw new Error(`订单ID ${newOrderId} 已存在`);
|
|
416
|
+
}
|
|
417
|
+
const originalOrderId = existingOrder.id;
|
|
418
|
+
const updatedOrder = {
|
|
419
|
+
...existingOrder,
|
|
420
|
+
id: newOrderId,
|
|
421
|
+
order_id: newOrderId,
|
|
422
|
+
// 🔧 修复:同时更新根级的 order_id 字段
|
|
423
|
+
order_info: {
|
|
424
|
+
...existingOrder.order_info,
|
|
425
|
+
order_id: newOrderId,
|
|
426
|
+
// 保留原始本地订单ID作为参考
|
|
427
|
+
original_local_order_id: originalOrderId,
|
|
428
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
await this.dbManager.update("order", updatedOrder);
|
|
432
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderUpdated, updatedOrder);
|
|
433
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
434
|
+
action: "order_id_replaced",
|
|
435
|
+
order: updatedOrder,
|
|
436
|
+
originalOrder: existingOrder,
|
|
437
|
+
metadata: {
|
|
438
|
+
originalOrderId,
|
|
439
|
+
newOrderId
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
this.logInfo("Order ID replacement completed successfully", {
|
|
443
|
+
orderUuid,
|
|
444
|
+
originalOrderId,
|
|
445
|
+
newOrderId
|
|
446
|
+
});
|
|
447
|
+
console.log(`[PaymentModule] 订单ID替换成功: ${originalOrderId} → ${newOrderId}`);
|
|
448
|
+
return updatedOrder;
|
|
449
|
+
} catch (error) {
|
|
450
|
+
console.error("[PaymentModule] 替换订单ID失败", error);
|
|
451
|
+
this.logError("replaceOrderIdByUuidAsync failed", error, {
|
|
452
|
+
orderUuid,
|
|
453
|
+
newOrderId
|
|
454
|
+
});
|
|
455
|
+
throw error;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* 获取支付项(新方法)
|
|
460
|
+
*
|
|
461
|
+
* @param orderUuid 订单UUID
|
|
462
|
+
* @param includeVoided 是否包含已撤销的支付项,默认为false
|
|
463
|
+
* @returns 支付项数组
|
|
464
|
+
*/
|
|
465
|
+
async getPaymentItemsAsync(orderUuid, includeVoided = false) {
|
|
401
466
|
if (!orderUuid) {
|
|
402
467
|
throw new Error("orderUuid is required");
|
|
403
468
|
}
|
|
404
|
-
const order = await this.
|
|
405
|
-
|
|
469
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
470
|
+
const allPayments = (order == null ? void 0 : order.payment) || [];
|
|
471
|
+
if (includeVoided) {
|
|
472
|
+
return allPayments;
|
|
473
|
+
}
|
|
474
|
+
return allPayments.filter((payment) => payment.status !== "voided");
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* 获取所有支付项(包括已撤销的)
|
|
478
|
+
*
|
|
479
|
+
* @param orderUuid 订单UUID
|
|
480
|
+
* @returns 所有支付项数组(包括撤销的)
|
|
481
|
+
*/
|
|
482
|
+
async getAllPaymentItemsAsync(orderUuid) {
|
|
483
|
+
return this.getPaymentItemsAsync(orderUuid, true);
|
|
406
484
|
}
|
|
407
485
|
/**
|
|
408
|
-
*
|
|
486
|
+
* 为某个订单添加支付项(新方法)
|
|
409
487
|
*/
|
|
410
|
-
async
|
|
411
|
-
|
|
488
|
+
async addPaymentItemAsync(orderUuid, paymentItem) {
|
|
489
|
+
var _a;
|
|
490
|
+
this.logInfo("Starting addPaymentItemAsync", {
|
|
412
491
|
orderUuid,
|
|
413
492
|
paymentAmount: paymentItem.amount,
|
|
414
493
|
paymentCode: paymentItem.code
|
|
415
494
|
});
|
|
416
495
|
try {
|
|
417
|
-
const order = await this.
|
|
496
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
418
497
|
if (!order) {
|
|
419
|
-
throw new Error(
|
|
498
|
+
throw new Error(`Order not found: ${orderUuid}`);
|
|
420
499
|
}
|
|
500
|
+
const paymentUuid = (0, import_utils.getUniqueId)("payment_");
|
|
421
501
|
const newPaymentItem = {
|
|
422
|
-
|
|
502
|
+
uuid: paymentUuid,
|
|
503
|
+
id: paymentItem.id || 0,
|
|
504
|
+
name: paymentItem.name,
|
|
505
|
+
code: paymentItem.code,
|
|
506
|
+
type: paymentItem.type,
|
|
423
507
|
amount: formatAmount(paymentItem.amount),
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
508
|
+
voucher_id: paymentItem.voucher_id || "",
|
|
509
|
+
rounding_amount: "0.00",
|
|
510
|
+
service_charge: paymentItem.service_charge,
|
|
511
|
+
status: "active",
|
|
512
|
+
// 新支付项默认为活跃状态
|
|
513
|
+
metadata: {
|
|
514
|
+
unique_payment_number: paymentUuid
|
|
515
|
+
// 设置唯一支付号为支付项的 uuid
|
|
516
|
+
}
|
|
427
517
|
};
|
|
428
518
|
order.payment.push(newPaymentItem);
|
|
429
519
|
this.recalculateOrderAmount(order);
|
|
430
520
|
await this.dbManager.update("order", order);
|
|
431
521
|
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentAdded, {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
});
|
|
435
|
-
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
436
|
-
action: "payment_add",
|
|
437
|
-
order,
|
|
438
|
-
paymentItem: newPaymentItem
|
|
522
|
+
orderUuid,
|
|
523
|
+
payment: newPaymentItem
|
|
439
524
|
});
|
|
440
|
-
this.logInfo("
|
|
525
|
+
this.logInfo("addPaymentItemAsync completed successfully", {
|
|
441
526
|
orderUuid,
|
|
442
527
|
paymentUuid: newPaymentItem.uuid,
|
|
528
|
+
uniquePaymentNumber: (_a = newPaymentItem.metadata) == null ? void 0 : _a.unique_payment_number,
|
|
443
529
|
newExpectAmount: order.expect_amount
|
|
444
530
|
});
|
|
445
531
|
} catch (error) {
|
|
446
532
|
console.error("[PaymentModule] 添加支付项失败", error);
|
|
447
|
-
this.logError("
|
|
533
|
+
this.logError("addPaymentItemAsync failed", error, {
|
|
448
534
|
orderUuid,
|
|
449
535
|
paymentItem
|
|
450
536
|
});
|
|
@@ -452,34 +538,131 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
452
538
|
}
|
|
453
539
|
}
|
|
454
540
|
/**
|
|
455
|
-
* 删除一个支付项
|
|
541
|
+
* 删除一个支付项 - 标记删除而非物理删除
|
|
456
542
|
*/
|
|
457
543
|
async deletePaymentAsync(orderUuid, paymentUuid) {
|
|
458
|
-
this.logInfo("Starting deletePaymentAsync", { orderUuid, paymentUuid });
|
|
544
|
+
this.logInfo("Starting deletePaymentAsync (mark as voided)", { orderUuid, paymentUuid });
|
|
459
545
|
try {
|
|
460
546
|
const order = await this.dbManager.get("order", orderUuid);
|
|
461
547
|
if (!order) {
|
|
462
548
|
throw new Error("订单不存在");
|
|
463
549
|
}
|
|
464
|
-
const
|
|
550
|
+
const paymentItem = order.payment.find(
|
|
465
551
|
(payment) => payment.uuid === paymentUuid
|
|
466
552
|
);
|
|
467
|
-
if (
|
|
468
|
-
|
|
469
|
-
this.recalculateOrderAmount(order);
|
|
470
|
-
await this.dbManager.update("order", order);
|
|
471
|
-
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentDeleted, {
|
|
472
|
-
order,
|
|
473
|
-
paymentItem: deletedPayment
|
|
474
|
-
});
|
|
475
|
-
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
476
|
-
action: "payment_delete",
|
|
477
|
-
order,
|
|
478
|
-
paymentItem: deletedPayment
|
|
479
|
-
});
|
|
553
|
+
if (!paymentItem) {
|
|
554
|
+
throw new Error(`支付项不存在: ${paymentUuid}`);
|
|
480
555
|
}
|
|
556
|
+
if (paymentItem.status === "voided") {
|
|
557
|
+
console.warn(`[PaymentModule] 支付项 ${paymentUuid} 已经被删除,跳过操作`);
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
paymentItem.status = "voided";
|
|
561
|
+
paymentItem.origin_amount = paymentItem.amount;
|
|
562
|
+
paymentItem.amount = "0.00";
|
|
563
|
+
console.log(`[PaymentModule] 支付项标记为删除:`, {
|
|
564
|
+
uuid: paymentItem.uuid,
|
|
565
|
+
originalAmount: paymentItem.origin_amount,
|
|
566
|
+
status: paymentItem.status
|
|
567
|
+
});
|
|
568
|
+
this.recalculateOrderAmount(order);
|
|
569
|
+
await this.dbManager.update("order", order);
|
|
570
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentDeleted, {
|
|
571
|
+
order,
|
|
572
|
+
paymentItem
|
|
573
|
+
});
|
|
574
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
575
|
+
action: "payment_delete",
|
|
576
|
+
order,
|
|
577
|
+
paymentItem
|
|
578
|
+
});
|
|
579
|
+
this.logInfo("deletePaymentAsync completed successfully (marked as voided)", {
|
|
580
|
+
orderUuid,
|
|
581
|
+
paymentUuid,
|
|
582
|
+
originalAmount: paymentItem.origin_amount,
|
|
583
|
+
newExpectAmount: order.expect_amount
|
|
584
|
+
});
|
|
481
585
|
} catch (error) {
|
|
482
586
|
console.error("[PaymentModule] 删除支付项失败", error);
|
|
587
|
+
this.logError("deletePaymentAsync failed", error, {
|
|
588
|
+
orderUuid,
|
|
589
|
+
paymentUuid
|
|
590
|
+
});
|
|
591
|
+
throw error;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* 批量更新代金券类支付项(覆盖更新)
|
|
596
|
+
*
|
|
597
|
+
* 删除所有现有的带 voucher_id 的支付项,然后添加新的代金券支付项
|
|
598
|
+
* 这是一个覆盖式更新,确保代金券支付项的一致性
|
|
599
|
+
*/
|
|
600
|
+
async updateVoucherPaymentItemsAsync(orderUuid, voucherPaymentItems) {
|
|
601
|
+
this.logInfo("Starting updateVoucherPaymentItemsAsync", {
|
|
602
|
+
orderUuid,
|
|
603
|
+
newVoucherCount: voucherPaymentItems.length,
|
|
604
|
+
voucherItems: voucherPaymentItems.map((item) => ({
|
|
605
|
+
code: item.code,
|
|
606
|
+
amount: item.amount,
|
|
607
|
+
voucher_id: item.voucher_id
|
|
608
|
+
}))
|
|
609
|
+
});
|
|
610
|
+
try {
|
|
611
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
612
|
+
if (!order) {
|
|
613
|
+
throw new Error(`订单不存在: ${orderUuid}`);
|
|
614
|
+
}
|
|
615
|
+
const existingVoucherItems = order.payment.filter(
|
|
616
|
+
(payment) => payment.voucher_id && payment.status !== "voided"
|
|
617
|
+
);
|
|
618
|
+
console.log("[PaymentModule] 发现现有代金券支付项:", {
|
|
619
|
+
orderUuid,
|
|
620
|
+
existingVoucherCount: existingVoucherItems.length,
|
|
621
|
+
existingItems: existingVoucherItems.map((item) => ({
|
|
622
|
+
uuid: item.uuid,
|
|
623
|
+
code: item.code,
|
|
624
|
+
amount: item.amount,
|
|
625
|
+
voucher_id: item.voucher_id
|
|
626
|
+
}))
|
|
627
|
+
});
|
|
628
|
+
for (const voucherItem of existingVoucherItems) {
|
|
629
|
+
console.log(`[PaymentModule] 删除现有代金券支付项: ${voucherItem.uuid}`);
|
|
630
|
+
await this.deletePaymentAsync(orderUuid, voucherItem.uuid);
|
|
631
|
+
}
|
|
632
|
+
console.log("[PaymentModule] 添加新的代金券支付项:", {
|
|
633
|
+
orderUuid,
|
|
634
|
+
newItemCount: voucherPaymentItems.length
|
|
635
|
+
});
|
|
636
|
+
for (const voucherItem of voucherPaymentItems) {
|
|
637
|
+
if (!voucherItem.voucher_id) {
|
|
638
|
+
throw new Error(`代金券支付项缺少 voucher_id: ${JSON.stringify(voucherItem)}`);
|
|
639
|
+
}
|
|
640
|
+
console.log(`[PaymentModule] 添加代金券支付项:`, {
|
|
641
|
+
code: voucherItem.code,
|
|
642
|
+
amount: voucherItem.amount,
|
|
643
|
+
voucher_id: voucherItem.voucher_id
|
|
644
|
+
});
|
|
645
|
+
await this.addPaymentItemAsync(orderUuid, voucherItem);
|
|
646
|
+
}
|
|
647
|
+
const updatedOrder = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
648
|
+
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentAdded, {
|
|
649
|
+
orderUuid,
|
|
650
|
+
order: updatedOrder,
|
|
651
|
+
payment: null
|
|
652
|
+
// 批量操作不提供单个支付项
|
|
653
|
+
});
|
|
654
|
+
this.logInfo("updateVoucherPaymentItemsAsync completed successfully", {
|
|
655
|
+
orderUuid,
|
|
656
|
+
removedVoucherCount: existingVoucherItems.length,
|
|
657
|
+
addedVoucherCount: voucherPaymentItems.length,
|
|
658
|
+
finalExpectAmount: updatedOrder == null ? void 0 : updatedOrder.expect_amount
|
|
659
|
+
});
|
|
660
|
+
} catch (error) {
|
|
661
|
+
console.error("[PaymentModule] 批量更新代金券支付项失败:", error);
|
|
662
|
+
this.logError("updateVoucherPaymentItemsAsync failed", error, {
|
|
663
|
+
orderUuid,
|
|
664
|
+
voucherPaymentItems
|
|
665
|
+
});
|
|
483
666
|
throw error;
|
|
484
667
|
}
|
|
485
668
|
}
|
|
@@ -529,32 +712,20 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
529
712
|
const order = await this.dbManager.get("order", orderUuid);
|
|
530
713
|
orderToSubmit = order ? [order] : [];
|
|
531
714
|
} else {
|
|
532
|
-
const
|
|
533
|
-
orderToSubmit =
|
|
715
|
+
const allOrders = await this.dbManager.getAll("order");
|
|
716
|
+
orderToSubmit = allOrders.filter(
|
|
534
717
|
(order) => order.payment_status === import_types.PaymentStatus.Processing || order.payment_status === import_types.PaymentStatus.PartiallyPaid
|
|
535
718
|
);
|
|
536
719
|
}
|
|
537
720
|
for (const order of orderToSubmit) {
|
|
538
721
|
await this.submitSingleOrderPayment(order);
|
|
539
722
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
);
|
|
545
|
-
|
|
546
|
-
const result = { status: "success" };
|
|
547
|
-
this.logInfo("submitPayAsync completed", {
|
|
548
|
-
result: result.status,
|
|
549
|
-
processedOrdersCount: allOrders.length
|
|
550
|
-
});
|
|
551
|
-
return result;
|
|
552
|
-
} else {
|
|
553
|
-
this.logWarning("submitPayAsync completed with unprocessed orders", {
|
|
554
|
-
totalOrders: allOrders.length
|
|
555
|
-
});
|
|
556
|
-
return { status: "failed" };
|
|
557
|
-
}
|
|
723
|
+
const result = { status: "success" };
|
|
724
|
+
this.logInfo("submitPayAsync completed", {
|
|
725
|
+
result: result.status,
|
|
726
|
+
processedOrdersCount: orderToSubmit.length
|
|
727
|
+
});
|
|
728
|
+
return result;
|
|
558
729
|
} catch (error) {
|
|
559
730
|
console.error("[PaymentModule] 提交支付失败", error);
|
|
560
731
|
this.logError("submitPayAsync failed", error, { orderUuid });
|
|
@@ -585,7 +756,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
585
756
|
(sum, payment) => sum.plus(payment.amount),
|
|
586
757
|
new import_decimal.Decimal(0)
|
|
587
758
|
);
|
|
588
|
-
const orderTotalAmount = new import_decimal.Decimal(order.
|
|
759
|
+
const orderTotalAmount = new import_decimal.Decimal(order.total_amount);
|
|
589
760
|
if (totalPaidAmount.gte(orderTotalAmount)) {
|
|
590
761
|
order.payment_status = import_types.PaymentStatus.Finished;
|
|
591
762
|
console.log(
|
|
@@ -600,14 +771,13 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
600
771
|
paymentData.payment_status = order.payment_status === import_types.PaymentStatus.Finished ? "paid" : "partially_paid";
|
|
601
772
|
await this.dbManager.update("order", order);
|
|
602
773
|
if (paymentData.payments.length === 0) {
|
|
603
|
-
console.log(`[PaymentModule] 订单 ${order.uuid}
|
|
604
|
-
this.logWarning("Empty payment
|
|
774
|
+
console.log(`[PaymentModule] 订单 ${order.uuid} 支付列表为空,跳过支付处理`);
|
|
775
|
+
this.logWarning("Empty payment list", {
|
|
605
776
|
orderUuid: order.uuid,
|
|
606
|
-
orderId: order.
|
|
777
|
+
orderId: order.order_id
|
|
607
778
|
});
|
|
608
779
|
return;
|
|
609
780
|
}
|
|
610
|
-
await this.addToSyncQueue(order, paymentData);
|
|
611
781
|
await this.core.effects.emit(import_types.PaymentHooks.OnPaymentSubmitted, order);
|
|
612
782
|
await this.core.effects.emit(import_types.PaymentHooks.OnOrderChanged, {
|
|
613
783
|
action: "submit",
|
|
@@ -618,44 +788,11 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
618
788
|
throw error;
|
|
619
789
|
}
|
|
620
790
|
}
|
|
621
|
-
/**
|
|
622
|
-
* 添加到同步任务队列
|
|
623
|
-
*/
|
|
624
|
-
async addToSyncQueue(order, paymentData) {
|
|
625
|
-
try {
|
|
626
|
-
console.log(`[PaymentModule] 订单 ${order.uuid} 已添加到同步队列`);
|
|
627
|
-
if (this.app.tasksManager) {
|
|
628
|
-
this.app.tasksManager.addTask({
|
|
629
|
-
module: "payment",
|
|
630
|
-
queueId: "payment_sync",
|
|
631
|
-
tasks: [
|
|
632
|
-
{
|
|
633
|
-
id: `payment_${order.uuid}`,
|
|
634
|
-
action: "syncPayment",
|
|
635
|
-
payload: {
|
|
636
|
-
orderUuid: order.uuid,
|
|
637
|
-
orderId: order.order_info.order_id,
|
|
638
|
-
paymentData,
|
|
639
|
-
core: this.core
|
|
640
|
-
},
|
|
641
|
-
maxRetries: 3,
|
|
642
|
-
type: "cloud"
|
|
643
|
-
}
|
|
644
|
-
]
|
|
645
|
-
});
|
|
646
|
-
console.log(`[PaymentModule] 订单 ${order.uuid} 同步任务已添加到队列`);
|
|
647
|
-
} else {
|
|
648
|
-
console.warn("[PaymentModule] TasksManager 未初始化,无法添加同步任务");
|
|
649
|
-
}
|
|
650
|
-
} catch (error) {
|
|
651
|
-
console.error("[PaymentModule] 添加同步任务失败", error);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
791
|
/**
|
|
655
792
|
* 获取订单剩余待付金额
|
|
656
793
|
*/
|
|
657
794
|
async getRemainingOrderAmountAsync(orderUuid) {
|
|
658
|
-
const order = await this.
|
|
795
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
659
796
|
if (!order) {
|
|
660
797
|
throw new Error("订单不存在");
|
|
661
798
|
}
|
|
@@ -665,7 +802,7 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
665
802
|
* 在比如现金支付界面的地方,用户输入了一个金额,在下方显示剩余多少金额,通过此方法获取
|
|
666
803
|
*/
|
|
667
804
|
async getRemainingOrderAmountWithInputAsync(inputAmount, orderUuid) {
|
|
668
|
-
const order = await this.
|
|
805
|
+
const order = await this.getPaymentOrderByUuidAsync(orderUuid);
|
|
669
806
|
if (!order) {
|
|
670
807
|
throw new Error("订单不存在");
|
|
671
808
|
}
|
|
@@ -699,13 +836,31 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
699
836
|
* 重新计算订单金额
|
|
700
837
|
*/
|
|
701
838
|
recalculateOrderAmount(order) {
|
|
702
|
-
const totalAmount = new import_decimal.Decimal(order.
|
|
839
|
+
const totalAmount = new import_decimal.Decimal(order.total_amount);
|
|
703
840
|
const paidAmount = order.payment.reduce(
|
|
704
|
-
(sum, payment) =>
|
|
841
|
+
(sum, payment) => {
|
|
842
|
+
try {
|
|
843
|
+
if (payment.status === "voided") {
|
|
844
|
+
return sum;
|
|
845
|
+
}
|
|
846
|
+
return sum.plus(payment.amount);
|
|
847
|
+
} catch (error) {
|
|
848
|
+
console.warn(`[PaymentModule] 无效的支付金额: ${payment.amount},跳过计算`);
|
|
849
|
+
return sum;
|
|
850
|
+
}
|
|
851
|
+
},
|
|
705
852
|
new import_decimal.Decimal(0)
|
|
706
853
|
);
|
|
707
854
|
const remainingAmount = totalAmount.minus(paidAmount);
|
|
708
855
|
order.expect_amount = import_decimal.Decimal.max(0, remainingAmount).toFixed(2);
|
|
856
|
+
console.log(`[PaymentModule] 重新计算订单金额:`, {
|
|
857
|
+
orderUuid: order.uuid,
|
|
858
|
+
totalAmount: order.total_amount,
|
|
859
|
+
paidAmount: paidAmount.toFixed(2),
|
|
860
|
+
remainingAmount: order.expect_amount,
|
|
861
|
+
activePayments: order.payment.filter((p) => p.status !== "voided").length,
|
|
862
|
+
voidedPayments: order.payment.filter((p) => p.status === "voided").length
|
|
863
|
+
});
|
|
709
864
|
}
|
|
710
865
|
/**
|
|
711
866
|
* 获取现金支付方式
|
|
@@ -749,189 +904,6 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
749
904
|
return null;
|
|
750
905
|
}
|
|
751
906
|
}
|
|
752
|
-
/**
|
|
753
|
-
* 注册任务处理函数
|
|
754
|
-
*/
|
|
755
|
-
registerTaskHandlers() {
|
|
756
|
-
if (this.app.tasksManager) {
|
|
757
|
-
this.app.tasksManager.addTaskFunction(
|
|
758
|
-
"syncPayment",
|
|
759
|
-
PaymentModule.syncPaymentTask
|
|
760
|
-
);
|
|
761
|
-
console.log("[PaymentModule] 任务处理函数已注册");
|
|
762
|
-
} else {
|
|
763
|
-
console.warn(
|
|
764
|
-
"[PaymentModule] TasksManager 未初始化,无法注册任务处理函数"
|
|
765
|
-
);
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
/**
|
|
769
|
-
* 静态方法:处理支付同步任务(后台网络同步)
|
|
770
|
-
* 这个方法里不允许用 this,因为需要作为静态方法注入到任务队列里
|
|
771
|
-
*/
|
|
772
|
-
static async syncPaymentTask(payload) {
|
|
773
|
-
var _a, _b, _c, _d, _e, _f;
|
|
774
|
-
const { orderUuid, orderId, paymentData, core } = payload.task.payload;
|
|
775
|
-
console.log(`[PaymentModule] 开始后台同步支付,订单ID: ${orderId}`);
|
|
776
|
-
paymentData.request_unique = generateRequestUniqueId();
|
|
777
|
-
const app = window.app;
|
|
778
|
-
const logger = app == null ? void 0 : app.logger;
|
|
779
|
-
if (logger) {
|
|
780
|
-
logger.addLog({
|
|
781
|
-
type: "info",
|
|
782
|
-
title: "[PaymentModule] Starting syncPaymentTask",
|
|
783
|
-
metadata: {
|
|
784
|
-
orderUuid,
|
|
785
|
-
orderId,
|
|
786
|
-
paymentDataKeys: Object.keys(paymentData)
|
|
787
|
-
}
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
if (!app) {
|
|
791
|
-
throw new Error("App 实例未找到");
|
|
792
|
-
}
|
|
793
|
-
const request = app.request;
|
|
794
|
-
if (!request) {
|
|
795
|
-
throw new Error("Request 插件未找到");
|
|
796
|
-
}
|
|
797
|
-
const dbManager = app.dbManager;
|
|
798
|
-
if (!dbManager) {
|
|
799
|
-
throw new Error("DBManager 未找到");
|
|
800
|
-
}
|
|
801
|
-
try {
|
|
802
|
-
const requestRes = await request.post(
|
|
803
|
-
`/shop/order/${orderId}/order-payment`,
|
|
804
|
-
paymentData,
|
|
805
|
-
{ noToast: true }
|
|
806
|
-
);
|
|
807
|
-
if (requestRes.status === true) {
|
|
808
|
-
const order = await dbManager.get("order", orderUuid);
|
|
809
|
-
if (order) {
|
|
810
|
-
order.payment.forEach((payment) => {
|
|
811
|
-
payment.isSynced = true;
|
|
812
|
-
delete payment.syncError;
|
|
813
|
-
});
|
|
814
|
-
await dbManager.update("order", order);
|
|
815
|
-
console.log(`[PaymentModule] 订单 ${orderUuid} 同步状态已更新`);
|
|
816
|
-
}
|
|
817
|
-
console.log(`[PaymentModule] 订单 ${orderUuid} 后台同步成功`);
|
|
818
|
-
await core.effects.emit("payment:onPaymentSyncSuccess", {
|
|
819
|
-
orderUuid,
|
|
820
|
-
orderId,
|
|
821
|
-
timestamp: Date.now()
|
|
822
|
-
});
|
|
823
|
-
console.log(
|
|
824
|
-
`[PaymentModule] 已通过 effects 通知前端订单 ${orderUuid} 同步成功`
|
|
825
|
-
);
|
|
826
|
-
if (logger) {
|
|
827
|
-
logger.addLog({
|
|
828
|
-
type: "info",
|
|
829
|
-
title: "[PaymentModule] syncPaymentTask completed successfully",
|
|
830
|
-
metadata: { orderUuid, orderId }
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
return { status: "success", orderUuid, orderId };
|
|
834
|
-
} else {
|
|
835
|
-
console.log(`[PaymentModule] 接口返回失败,订单 ${orderUuid} 同步失败`);
|
|
836
|
-
const businessError = new Error(requestRes.message || "接口返回失败");
|
|
837
|
-
businessError.response = { status: 200 };
|
|
838
|
-
businessError.isBusinessError = true;
|
|
839
|
-
businessError.responseData = requestRes;
|
|
840
|
-
throw businessError;
|
|
841
|
-
}
|
|
842
|
-
} catch (error) {
|
|
843
|
-
console.error("[PaymentModule] 后台同步失败:", error);
|
|
844
|
-
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")));
|
|
845
|
-
if (isNetworkError) {
|
|
846
|
-
console.log(`[PaymentModule] 网络错误,订单 ${orderUuid} 将重试同步`);
|
|
847
|
-
if (logger) {
|
|
848
|
-
logger.addLog({
|
|
849
|
-
type: "warning",
|
|
850
|
-
title: "[PaymentModule] syncPaymentTask network error - will retry",
|
|
851
|
-
metadata: {
|
|
852
|
-
orderUuid,
|
|
853
|
-
orderId,
|
|
854
|
-
errorCode: error.code,
|
|
855
|
-
errorMessage: error.message
|
|
856
|
-
}
|
|
857
|
-
});
|
|
858
|
-
}
|
|
859
|
-
throw error;
|
|
860
|
-
} else {
|
|
861
|
-
console.log(
|
|
862
|
-
`[PaymentModule] 业务错误,订单 ${orderUuid} 同步失败,通知前端`
|
|
863
|
-
);
|
|
864
|
-
try {
|
|
865
|
-
if (core && core.effects) {
|
|
866
|
-
const errorData = {
|
|
867
|
-
orderUuid,
|
|
868
|
-
orderId,
|
|
869
|
-
error: error.message || "业务错误",
|
|
870
|
-
errorCode: error.code,
|
|
871
|
-
statusCode: ((_d = error.response) == null ? void 0 : _d.status) || error.status,
|
|
872
|
-
timestamp: Date.now()
|
|
873
|
-
};
|
|
874
|
-
if (error.isBusinessError && error.responseData) {
|
|
875
|
-
errorData.error = error.responseData.message || error.message || "接口返回失败";
|
|
876
|
-
errorData.responseData = error.responseData;
|
|
877
|
-
}
|
|
878
|
-
await core.effects.emit("payment:onPaymentSyncError", errorData);
|
|
879
|
-
console.log(
|
|
880
|
-
`[PaymentModule] 已通过 effects 通知前端订单 ${orderUuid} 同步错误`
|
|
881
|
-
);
|
|
882
|
-
} else {
|
|
883
|
-
console.warn(
|
|
884
|
-
`[PaymentModule] 无法获取 core 实例,无法通知前端错误`
|
|
885
|
-
);
|
|
886
|
-
}
|
|
887
|
-
if (logger) {
|
|
888
|
-
logger.addLog({
|
|
889
|
-
type: "error",
|
|
890
|
-
title: "[PaymentModule] syncPaymentTask business error",
|
|
891
|
-
metadata: {
|
|
892
|
-
orderUuid,
|
|
893
|
-
orderId,
|
|
894
|
-
errorCode: error.code,
|
|
895
|
-
errorMessage: error.message,
|
|
896
|
-
statusCode: ((_e = error.response) == null ? void 0 : _e.status) || error.status,
|
|
897
|
-
isBusinessError: error.isBusinessError
|
|
898
|
-
}
|
|
899
|
-
});
|
|
900
|
-
}
|
|
901
|
-
} catch (notifyError) {
|
|
902
|
-
console.error(`[PaymentModule] 通知前端同步错误失败:`, notifyError);
|
|
903
|
-
if (logger) {
|
|
904
|
-
logger.addLog({
|
|
905
|
-
type: "error",
|
|
906
|
-
title: "[PaymentModule] Failed to notify frontend of sync error",
|
|
907
|
-
metadata: {
|
|
908
|
-
orderUuid,
|
|
909
|
-
orderId,
|
|
910
|
-
notifyError: notifyError instanceof Error ? notifyError.message : String(notifyError)
|
|
911
|
-
}
|
|
912
|
-
});
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
const order = await dbManager.get("order", orderUuid);
|
|
916
|
-
if (order) {
|
|
917
|
-
order.payment.forEach((payment) => {
|
|
918
|
-
payment.isSynced = true;
|
|
919
|
-
});
|
|
920
|
-
await dbManager.update("order", order);
|
|
921
|
-
console.log(
|
|
922
|
-
`[PaymentModule] 订单 ${orderUuid} 业务错误,已标记为已同步`
|
|
923
|
-
);
|
|
924
|
-
}
|
|
925
|
-
return {
|
|
926
|
-
status: "completed_with_error",
|
|
927
|
-
orderUuid,
|
|
928
|
-
orderId,
|
|
929
|
-
error: error.message || "业务错误",
|
|
930
|
-
statusCode: ((_f = error.response) == null ? void 0 : _f.status) || error.status
|
|
931
|
-
};
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
907
|
/**
|
|
936
908
|
* 确保支付模块所需的数据库表已创建
|
|
937
909
|
*/
|
|
@@ -967,211 +939,77 @@ var PaymentModule = class extends import_BaseModule.BaseModule {
|
|
|
967
939
|
return [];
|
|
968
940
|
}
|
|
969
941
|
}
|
|
942
|
+
// === 新的 API 方法实现 ===
|
|
970
943
|
/**
|
|
971
|
-
*
|
|
944
|
+
* 智能金额舍入
|
|
945
|
+
*
|
|
946
|
+
* 根据指定的舍入间隔和规则对金额进行舍入处理
|
|
947
|
+
*
|
|
948
|
+
* @param originalAmount 原始金额
|
|
949
|
+
* @param interval 舍入间隔 (0.05, 0.1, 0.5, 1)
|
|
950
|
+
* @param rule 舍入规则 (standard, standard_down, always_up, always_down)
|
|
951
|
+
* @returns 舍入后的金额(保留两位小数的字符串)
|
|
972
952
|
*/
|
|
973
|
-
async
|
|
953
|
+
async roundAmountAsync(originalAmount, interval, rule) {
|
|
974
954
|
try {
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
955
|
+
const amount = new import_decimal.Decimal(originalAmount);
|
|
956
|
+
const roundingInterval = new import_decimal.Decimal(interval);
|
|
957
|
+
if (roundingInterval.lte(0)) {
|
|
958
|
+
throw new Error("舍入间隔必须大于 0");
|
|
959
|
+
}
|
|
960
|
+
const supportedIntervals = [0.05, 0.1, 0.5, 1];
|
|
961
|
+
const intervalValue = roundingInterval.toNumber();
|
|
962
|
+
if (!supportedIntervals.includes(intervalValue)) {
|
|
963
|
+
console.warn(`[PaymentModule] 不支持的舍入间隔: ${intervalValue}, 支持的间隔: ${supportedIntervals.join(", ")}`);
|
|
964
|
+
}
|
|
965
|
+
const baseValue = amount.div(roundingInterval);
|
|
966
|
+
console.log(`[PaymentModule] 舍入计算 - 原始金额: ${amount.toString()}, 间隔: ${intervalValue}, 基础值: ${baseValue.toString()}, 规则: ${rule}`);
|
|
967
|
+
let roundedValue;
|
|
968
|
+
switch (rule) {
|
|
969
|
+
case import_types.RoundingRule.Standard:
|
|
970
|
+
case "standard":
|
|
971
|
+
roundedValue = this.standardRound(baseValue, true);
|
|
972
|
+
break;
|
|
973
|
+
case import_types.RoundingRule.StandardDown:
|
|
974
|
+
case "standard_down":
|
|
975
|
+
roundedValue = this.standardRound(baseValue, false);
|
|
976
|
+
break;
|
|
977
|
+
case import_types.RoundingRule.AlwaysUp:
|
|
978
|
+
case "always_up":
|
|
979
|
+
roundedValue = baseValue.ceil();
|
|
980
|
+
break;
|
|
981
|
+
case import_types.RoundingRule.AlwaysDown:
|
|
982
|
+
case "always_down":
|
|
983
|
+
roundedValue = baseValue.floor();
|
|
984
|
+
break;
|
|
985
|
+
default:
|
|
986
|
+
throw new Error(`不支持的舍入规则: ${rule}`);
|
|
987
|
+
}
|
|
988
|
+
const finalAmount = roundedValue.mul(roundingInterval);
|
|
989
|
+
const result = finalAmount.toFixed(2);
|
|
990
|
+
console.log(`[PaymentModule] 舍入结果 - 舍入值: ${roundedValue.toString()}, 最终金额: ${result}`);
|
|
991
|
+
return result;
|
|
979
992
|
} catch (error) {
|
|
980
|
-
console.error("[PaymentModule]
|
|
981
|
-
|
|
993
|
+
console.error("[PaymentModule] 金额舍入失败:", error);
|
|
994
|
+
throw new Error(`金额舍入失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
982
995
|
}
|
|
983
996
|
}
|
|
984
997
|
/**
|
|
985
|
-
*
|
|
986
|
-
*
|
|
998
|
+
* 标准舍入处理(处理中点情况)
|
|
999
|
+
*
|
|
1000
|
+
* @param value 要舍入的值
|
|
1001
|
+
* @param midpointUp 中点是否向上舍入
|
|
1002
|
+
* @returns 舍入后的值
|
|
987
1003
|
*/
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
console.log(
|
|
998
|
-
`[PaymentModule] 清理了 ${finishedAndSyncedOrders.length} 个已完成且已同步的订单`
|
|
999
|
-
);
|
|
1000
|
-
} catch (error) {
|
|
1001
|
-
console.error("[PaymentModule] 清理已完成订单失败", error);
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
/**
|
|
1005
|
-
* 检测未同步的订单并重新加入任务队列
|
|
1006
|
-
*
|
|
1007
|
-
* 此方法专门用于处理因网络问题导致任务队列执行失败但队列被清空的情况。
|
|
1008
|
-
* 它会检查本地 IndexDB 中所有未同步的订单(isSynced: false),
|
|
1009
|
-
* 并将这些订单重新添加到任务队列中。
|
|
1010
|
-
*
|
|
1011
|
-
* 使用场景:
|
|
1012
|
-
* - 网络恢复后重新检查未同步的订单
|
|
1013
|
-
* - 应用启动时检查并重新排队未完成的支付
|
|
1014
|
-
* - 用户手动重试前的预检查
|
|
1015
|
-
*
|
|
1016
|
-
* @returns Promise<number> 返回重新加入队列的订单数量
|
|
1017
|
-
*/
|
|
1018
|
-
async recheckAndRequeueUnsyncedOrders() {
|
|
1019
|
-
this.logInfo("Starting recheckAndRequeueUnsyncedOrders");
|
|
1020
|
-
try {
|
|
1021
|
-
if (!this.app.tasksManager) {
|
|
1022
|
-
console.warn(
|
|
1023
|
-
"[PaymentModule] TasksManager 未初始化,无法重新排队未同步订单"
|
|
1024
|
-
);
|
|
1025
|
-
this.logWarning(
|
|
1026
|
-
"TasksManager not initialized, cannot requeue unsynced orders"
|
|
1027
|
-
);
|
|
1028
|
-
return 0;
|
|
1029
|
-
}
|
|
1030
|
-
const unsyncedOrders = await this.getUnsyncedOrdersAsync();
|
|
1031
|
-
if (unsyncedOrders.length === 0) {
|
|
1032
|
-
console.log("[PaymentModule] 没有发现未同步的订单");
|
|
1033
|
-
this.logInfo("No unsynced orders found");
|
|
1034
|
-
return 0;
|
|
1035
|
-
}
|
|
1036
|
-
console.log(
|
|
1037
|
-
`[PaymentModule] 发现 ${unsyncedOrders.length} 个未同步的订单,开始重新加入任务队列`
|
|
1038
|
-
);
|
|
1039
|
-
this.logInfo("Found unsynced orders, adding to sync queue", {
|
|
1040
|
-
unsyncedCount: unsyncedOrders.length,
|
|
1041
|
-
orderUuids: unsyncedOrders.map((o) => o.uuid)
|
|
1042
|
-
});
|
|
1043
|
-
let requeuedCount = 0;
|
|
1044
|
-
for (const order of unsyncedOrders) {
|
|
1045
|
-
const success = await this.reAddOrderToSyncQueue(order);
|
|
1046
|
-
if (success) {
|
|
1047
|
-
requeuedCount++;
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
console.log(
|
|
1051
|
-
`[PaymentModule] 成功重新加入 ${requeuedCount} 个订单到任务队列`
|
|
1052
|
-
);
|
|
1053
|
-
this.logInfo("Successfully requeued unsynced orders", {
|
|
1054
|
-
requeuedCount,
|
|
1055
|
-
totalFound: unsyncedOrders.length
|
|
1056
|
-
});
|
|
1057
|
-
return requeuedCount;
|
|
1058
|
-
} catch (error) {
|
|
1059
|
-
console.error("[PaymentModule] 重新排队未同步订单失败", error);
|
|
1060
|
-
this.logError("recheckAndRequeueUnsyncedOrders failed", error);
|
|
1061
|
-
return 0;
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
/**
|
|
1065
|
-
* 手动执行支付同步队列
|
|
1066
|
-
* 外部可以调用此方法来触发支付同步任务的执行
|
|
1067
|
-
*
|
|
1068
|
-
* 注意:此方法只执行现有队列中的任务,不会检查未同步的订单。
|
|
1069
|
-
* 如果需要检查未同步订单,请先调用 recheckAndRequeueUnsyncedOrders()
|
|
1070
|
-
*
|
|
1071
|
-
* 使用示例:
|
|
1072
|
-
* ```typescript
|
|
1073
|
-
* // 1. 先检查并重新排队未同步订单,然后执行队列
|
|
1074
|
-
* const requeuedCount = await paymentModule.recheckAndRequeueUnsyncedOrders();
|
|
1075
|
-
* if (requeuedCount > 0) {
|
|
1076
|
-
* await paymentModule.runPaymentSyncQueue();
|
|
1077
|
-
* }
|
|
1078
|
-
*
|
|
1079
|
-
* // 2. 或者直接执行现有队列(不检查未同步订单)
|
|
1080
|
-
* await paymentModule.runPaymentSyncQueue();
|
|
1081
|
-
* ```
|
|
1082
|
-
*/
|
|
1083
|
-
async runPaymentSyncQueue() {
|
|
1084
|
-
this.logInfo("Starting runPaymentSyncQueue");
|
|
1085
|
-
try {
|
|
1086
|
-
if (!this.app.tasksManager) {
|
|
1087
|
-
console.warn("[PaymentModule] TasksManager 未初始化,无法执行同步队列");
|
|
1088
|
-
this.logWarning("TasksManager not initialized, cannot run sync queue");
|
|
1089
|
-
return;
|
|
1090
|
-
}
|
|
1091
|
-
const queue = this.app.tasksManager.getTaskQueue({
|
|
1092
|
-
module: "payment",
|
|
1093
|
-
queueId: "payment_sync"
|
|
1094
|
-
});
|
|
1095
|
-
if (!(queue == null ? void 0 : queue.length)) {
|
|
1096
|
-
console.log("[PaymentModule] 支付同步队列无内容,不执行");
|
|
1097
|
-
return;
|
|
1098
|
-
}
|
|
1099
|
-
console.log("[PaymentModule] 开始执行支付同步队列");
|
|
1100
|
-
await this.app.tasksManager.run({
|
|
1101
|
-
module: "payment",
|
|
1102
|
-
queueId: "payment_sync",
|
|
1103
|
-
callback: () => {
|
|
1104
|
-
console.log("[PaymentModule] 支付同步队列执行完成");
|
|
1105
|
-
if (this.logger) {
|
|
1106
|
-
this.logger.addLog({
|
|
1107
|
-
type: "info",
|
|
1108
|
-
title: "[PaymentModule] Payment sync queue completed",
|
|
1109
|
-
metadata: {}
|
|
1110
|
-
});
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
});
|
|
1114
|
-
this.logInfo("runPaymentSyncQueue completed successfully");
|
|
1115
|
-
} catch (error) {
|
|
1116
|
-
console.error("[PaymentModule] 执行支付同步队列失败", error);
|
|
1117
|
-
this.logError("runPaymentSyncQueue failed", error);
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
/**
|
|
1121
|
-
* 重新将订单添加到同步队列
|
|
1122
|
-
* 用于处理因网络问题导致任务队列清空但订单未同步的情况
|
|
1123
|
-
*
|
|
1124
|
-
* @param order 要重新添加的订单
|
|
1125
|
-
* @returns Promise<boolean> 是否成功添加到队列
|
|
1126
|
-
*/
|
|
1127
|
-
async reAddOrderToSyncQueue(order) {
|
|
1128
|
-
try {
|
|
1129
|
-
const paymentData = {
|
|
1130
|
-
payments: order.payment.map((payment) => ({
|
|
1131
|
-
uuid: payment.uuid,
|
|
1132
|
-
amount: payment.amount,
|
|
1133
|
-
code: payment.code,
|
|
1134
|
-
id: payment.id,
|
|
1135
|
-
name: payment.name,
|
|
1136
|
-
type: payment.type,
|
|
1137
|
-
voucher_id: payment.voucher_id,
|
|
1138
|
-
metadata: payment.metadata,
|
|
1139
|
-
rounding_amount: payment.rounding_amount,
|
|
1140
|
-
service_charge: payment.service_charge
|
|
1141
|
-
})),
|
|
1142
|
-
payment_status: order.payment_status === import_types.PaymentStatus.Finished ? "paid" : "partially_paid"
|
|
1143
|
-
};
|
|
1144
|
-
const existingQueue = this.app.tasksManager.getTaskQueue({
|
|
1145
|
-
module: "payment",
|
|
1146
|
-
queueId: "payment_sync"
|
|
1147
|
-
});
|
|
1148
|
-
const taskId = `payment_${order.uuid}`;
|
|
1149
|
-
const taskExists = existingQueue == null ? void 0 : existingQueue.some((task) => task.id === taskId);
|
|
1150
|
-
if (taskExists) {
|
|
1151
|
-
console.log(
|
|
1152
|
-
`[PaymentModule] 任务 ${taskId} 已存在于队列中,跳过重复添加`
|
|
1153
|
-
);
|
|
1154
|
-
return false;
|
|
1155
|
-
}
|
|
1156
|
-
await this.addToSyncQueue(order, paymentData);
|
|
1157
|
-
console.log(`[PaymentModule] 订单 ${order.uuid} 已重新添加到同步队列`);
|
|
1158
|
-
this.logInfo("Order re-added to sync queue", {
|
|
1159
|
-
orderUuid: order.uuid,
|
|
1160
|
-
orderId: order.order_info.order_id,
|
|
1161
|
-
paymentStatus: order.payment_status,
|
|
1162
|
-
unsyncedPayments: order.payment.filter((p) => !p.isSynced).length
|
|
1163
|
-
});
|
|
1164
|
-
return true;
|
|
1165
|
-
} catch (error) {
|
|
1166
|
-
console.error(
|
|
1167
|
-
`[PaymentModule] 重新添加订单 ${order.uuid} 到同步队列失败`,
|
|
1168
|
-
error
|
|
1169
|
-
);
|
|
1170
|
-
this.logError("Failed to re-add order to sync queue", error, {
|
|
1171
|
-
orderUuid: order.uuid,
|
|
1172
|
-
orderId: order.order_info.order_id
|
|
1173
|
-
});
|
|
1174
|
-
return false;
|
|
1004
|
+
standardRound(value, midpointUp) {
|
|
1005
|
+
const floorValue = value.floor();
|
|
1006
|
+
const fractionalPart = value.minus(floorValue);
|
|
1007
|
+
if (fractionalPart.eq(0.5)) {
|
|
1008
|
+
return midpointUp ? floorValue.plus(1) : floorValue;
|
|
1009
|
+
} else if (fractionalPart.gt(0.5)) {
|
|
1010
|
+
return floorValue.plus(1);
|
|
1011
|
+
} else {
|
|
1012
|
+
return floorValue;
|
|
1175
1013
|
}
|
|
1176
1014
|
}
|
|
1177
1015
|
};
|