@pisell/pisellos 2.2.263 → 2.2.265
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 +27 -8
- package/dist/modules/Order/index.js +736 -473
- package/dist/modules/Order/payment-utils.d.ts +26 -0
- package/dist/modules/Order/payment-utils.js +225 -0
- package/dist/modules/Order/types.d.ts +33 -1
- package/dist/modules/Order/utils/orderCollectionIdentity.js +7 -2
- package/dist/modules/Order/utils.js +8 -5
- package/dist/modules/Payment/index.d.ts +2 -0
- package/dist/modules/Payment/index.js +78 -49
- package/dist/modules/Payment/types.d.ts +26 -24
- package/dist/modules/Payment/types.js +2 -0
- package/dist/server/index.d.ts +16 -0
- package/dist/server/index.js +1940 -1043
- package/dist/server/modules/order/index.d.ts +49 -4
- package/dist/server/modules/order/index.js +1577 -698
- package/dist/server/modules/order/types.d.ts +11 -3
- package/dist/server/modules/order/types.js +1 -1
- package/dist/solution/BaseSales/index.d.ts +33 -3
- package/dist/solution/BaseSales/index.js +653 -340
- package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +2 -1
- package/dist/solution/Sales/index.d.ts +1 -0
- package/dist/solution/Sales/index.js +10 -2
- package/dist/utils/payment-number.d.ts +9 -0
- package/dist/utils/payment-number.js +69 -0
- package/lib/model/strategy/adapter/promotion/index.js +49 -0
- package/lib/modules/Order/index.d.ts +27 -8
- package/lib/modules/Order/index.js +180 -60
- package/lib/modules/Order/payment-utils.d.ts +26 -0
- package/lib/modules/Order/payment-utils.js +224 -0
- package/lib/modules/Order/types.d.ts +33 -1
- package/lib/modules/Order/utils/orderCollectionIdentity.js +3 -0
- package/lib/modules/Order/utils.js +5 -3
- package/lib/modules/Payment/index.d.ts +2 -0
- package/lib/modules/Payment/index.js +33 -12
- package/lib/modules/Payment/types.d.ts +26 -24
- package/lib/server/index.d.ts +16 -0
- package/lib/server/index.js +670 -18
- package/lib/server/modules/order/index.d.ts +49 -4
- package/lib/server/modules/order/index.js +657 -66
- package/lib/server/modules/order/types.d.ts +11 -3
- package/lib/solution/BaseSales/index.d.ts +33 -3
- package/lib/solution/BaseSales/index.js +193 -9
- package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +2 -1
- package/lib/solution/Sales/index.d.ts +1 -0
- package/lib/solution/Sales/index.js +5 -3
- package/lib/utils/payment-number.d.ts +9 -0
- package/lib/utils/payment-number.js +64 -0
- package/package.json +1 -1
package/lib/server/index.js
CHANGED
|
@@ -34,6 +34,8 @@ __export(server_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(server_exports);
|
|
36
36
|
var import_dayjs = __toESM(require("dayjs"));
|
|
37
|
+
var import_decimal = __toESM(require("decimal.js"));
|
|
38
|
+
var import_lodash_es = require("lodash-es");
|
|
37
39
|
var import_products = require("./modules/products");
|
|
38
40
|
var import_menu = require("./modules/menu");
|
|
39
41
|
var import_quotation = require("./modules/quotation");
|
|
@@ -50,6 +52,8 @@ var import_types3 = require("./modules/order/types");
|
|
|
50
52
|
var import_filterOrders = require("./modules/order/utils/filterOrders");
|
|
51
53
|
var import_filterBookings = require("./modules/order/utils/filterBookings");
|
|
52
54
|
var import_small_ticket = require("./utils/small-ticket");
|
|
55
|
+
var import_BaseSales = require("../solution/BaseSales");
|
|
56
|
+
var import_payment_utils = require("../modules/Order/payment-utils");
|
|
53
57
|
__reExport(server_exports, require("./modules"), module.exports);
|
|
54
58
|
var PRODUCT_TITLE_SNAPSHOT_KEYS = [
|
|
55
59
|
"en",
|
|
@@ -87,6 +91,7 @@ var Server = class {
|
|
|
87
91
|
this.BOOKING_REMOTE_CACHE_MAX_ENTRIES = 80;
|
|
88
92
|
this.salesSearchSubscribers = /* @__PURE__ */ new Map();
|
|
89
93
|
this.deviceTaskActionsRegistered = false;
|
|
94
|
+
this.localPaymentUpdateQueues = /* @__PURE__ */ new Map();
|
|
90
95
|
this.floorPlanQuerySubscribers = /* @__PURE__ */ new Map();
|
|
91
96
|
// 模块注册表 - 定义所有可用的模块配置
|
|
92
97
|
this.moduleRegistry = {
|
|
@@ -575,6 +580,128 @@ var Server = class {
|
|
|
575
580
|
title: "handleOrderSalesCheckout"
|
|
576
581
|
});
|
|
577
582
|
};
|
|
583
|
+
this.handleOrderSalesDraft = async ({ data }) => {
|
|
584
|
+
return this.handleOrderDraftSubmit({
|
|
585
|
+
data,
|
|
586
|
+
title: "handleOrderSalesDraft"
|
|
587
|
+
});
|
|
588
|
+
};
|
|
589
|
+
this.handleGetLocalPayment = async ({ data }) => {
|
|
590
|
+
const saleId = data == null ? void 0 : data.sale_id;
|
|
591
|
+
const paymentNumber = data == null ? void 0 : data.payment_number;
|
|
592
|
+
const operationId = this.createLocalPaymentOperationId("get");
|
|
593
|
+
const requestContext = {
|
|
594
|
+
operation_id: operationId,
|
|
595
|
+
sale_id: saleId ?? null,
|
|
596
|
+
payment_number: paymentNumber ?? null
|
|
597
|
+
};
|
|
598
|
+
this.logInfo("handleGetLocalPayment: 请求进入", requestContext);
|
|
599
|
+
if (saleId === void 0 || saleId === null || saleId === "" || paymentNumber === void 0 || paymentNumber === null || paymentNumber === "") {
|
|
600
|
+
this.logWarning("handleGetLocalPayment: 参数校验失败", {
|
|
601
|
+
...requestContext,
|
|
602
|
+
missing_fields: [
|
|
603
|
+
...saleId === void 0 || saleId === null || saleId === "" ? ["sale_id"] : [],
|
|
604
|
+
...paymentNumber === void 0 || paymentNumber === null || paymentNumber === "" ? ["payment_number"] : []
|
|
605
|
+
]
|
|
606
|
+
});
|
|
607
|
+
return {
|
|
608
|
+
code: 400,
|
|
609
|
+
status: false,
|
|
610
|
+
message: "sale_id 和 payment_number 必填",
|
|
611
|
+
data: null
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
if (!this.order) {
|
|
615
|
+
this.logError("handleGetLocalPayment: Order 模块未注册", requestContext);
|
|
616
|
+
return { code: 500, status: false, message: "Order 模块未注册", data: null };
|
|
617
|
+
}
|
|
618
|
+
const startedAt = Date.now();
|
|
619
|
+
try {
|
|
620
|
+
this.logInfo("handleGetLocalPayment: 开始查询本地支付项", requestContext);
|
|
621
|
+
const found = await this.order.getLocalPayment({
|
|
622
|
+
saleId,
|
|
623
|
+
paymentNumber,
|
|
624
|
+
operationId
|
|
625
|
+
});
|
|
626
|
+
if (!found) {
|
|
627
|
+
this.logWarning("handleGetLocalPayment: 本地支付项不存在", {
|
|
628
|
+
...requestContext,
|
|
629
|
+
duration_ms: Date.now() - startedAt
|
|
630
|
+
});
|
|
631
|
+
return { code: 404, status: false, message: "本地支付项不存在", data: null };
|
|
632
|
+
}
|
|
633
|
+
this.logInfo("handleGetLocalPayment: 查询命中", {
|
|
634
|
+
...requestContext,
|
|
635
|
+
duration_ms: Date.now() - startedAt,
|
|
636
|
+
matched_by: found.matchedBy,
|
|
637
|
+
payment_index: found.paymentIndex,
|
|
638
|
+
...this.buildLocalPaymentOrderLogContext(found.order),
|
|
639
|
+
payment: found.payment
|
|
640
|
+
});
|
|
641
|
+
return { code: 200, status: true, message: "", data: found.payment };
|
|
642
|
+
} catch (error) {
|
|
643
|
+
this.logError("handleGetLocalPayment: 查询异常", {
|
|
644
|
+
...requestContext,
|
|
645
|
+
duration_ms: Date.now() - startedAt,
|
|
646
|
+
error: error instanceof Error ? error.message : String(error),
|
|
647
|
+
error_detail: this.normalizeUnknownError(error)
|
|
648
|
+
});
|
|
649
|
+
throw error;
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
this.handleUpdateLocalPayment = async ({ data }) => {
|
|
653
|
+
const saleId = data == null ? void 0 : data.sale_id;
|
|
654
|
+
const paymentNumber = data == null ? void 0 : data.payment_number;
|
|
655
|
+
const number = data == null ? void 0 : data.number;
|
|
656
|
+
const status = data == null ? void 0 : data.status;
|
|
657
|
+
const serviceCharge = data == null ? void 0 : data.service_charge;
|
|
658
|
+
const cardReaderSurcharge = data == null ? void 0 : data.card_reader_surcharge;
|
|
659
|
+
const hasSurchargeInput = serviceCharge !== void 0 || cardReaderSurcharge !== void 0;
|
|
660
|
+
const invalidSurchargeFields = this.getInvalidLocalPaymentSurchargeFields(
|
|
661
|
+
serviceCharge,
|
|
662
|
+
cardReaderSurcharge
|
|
663
|
+
);
|
|
664
|
+
const operationId = this.createLocalPaymentOperationId("update");
|
|
665
|
+
const requestContext = {
|
|
666
|
+
operation_id: operationId,
|
|
667
|
+
sale_id: saleId ?? null,
|
|
668
|
+
payment_number: paymentNumber ?? null,
|
|
669
|
+
transaction_number: number ?? null,
|
|
670
|
+
requested_status: status ?? null,
|
|
671
|
+
service_charge: serviceCharge ?? null,
|
|
672
|
+
card_reader_surcharge: cardReaderSurcharge ?? null
|
|
673
|
+
};
|
|
674
|
+
this.logInfo("handleUpdateLocalPayment: 请求进入", requestContext);
|
|
675
|
+
if (saleId === void 0 || saleId === null || saleId === "" || paymentNumber === void 0 || paymentNumber === null || paymentNumber === "" || number === void 0 || number === null || number === "" || status !== "success" && status !== "fail" || invalidSurchargeFields.length > 0) {
|
|
676
|
+
this.logWarning("handleUpdateLocalPayment: 参数校验失败", {
|
|
677
|
+
...requestContext,
|
|
678
|
+
missing_or_invalid_fields: [
|
|
679
|
+
...saleId === void 0 || saleId === null || saleId === "" ? ["sale_id"] : [],
|
|
680
|
+
...paymentNumber === void 0 || paymentNumber === null || paymentNumber === "" ? ["payment_number"] : [],
|
|
681
|
+
...number === void 0 || number === null || number === "" ? ["number"] : [],
|
|
682
|
+
...status !== "success" && status !== "fail" ? ["status"] : [],
|
|
683
|
+
...invalidSurchargeFields
|
|
684
|
+
]
|
|
685
|
+
});
|
|
686
|
+
return {
|
|
687
|
+
code: 400,
|
|
688
|
+
status: false,
|
|
689
|
+
message: invalidSurchargeFields.length > 0 ? `手续费参数非法: ${invalidSurchargeFields.join(", ")}` : "sale_id、payment_number、number 必填,status 仅支持 success/fail",
|
|
690
|
+
data: null
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
const queueKey = `${String(saleId)}:${String(paymentNumber)}`;
|
|
694
|
+
return this.runLocalPaymentUpdateInQueue(queueKey, () => this.processLocalPaymentUpdate({
|
|
695
|
+
operationId,
|
|
696
|
+
saleId,
|
|
697
|
+
paymentNumber,
|
|
698
|
+
number: String(number),
|
|
699
|
+
status,
|
|
700
|
+
serviceCharge,
|
|
701
|
+
cardReaderSurcharge,
|
|
702
|
+
hasSurchargeInput
|
|
703
|
+
}), requestContext);
|
|
704
|
+
};
|
|
578
705
|
this.handleOrderCheckout = async ({ data }) => {
|
|
579
706
|
return this.handleOrderCheckoutSubmit({
|
|
580
707
|
backendPath: "/order/checkout",
|
|
@@ -1356,7 +1483,7 @@ var Server = class {
|
|
|
1356
1483
|
const { backendPath, title } = params;
|
|
1357
1484
|
const normalizedData = await this.normalizeCheckoutSubmitData(params.data, title);
|
|
1358
1485
|
const checkoutData = await this.ensureCheckoutOrderNumbers(normalizedData, title);
|
|
1359
|
-
const remoteCheckoutData = this.
|
|
1486
|
+
const remoteCheckoutData = this.buildRemoteCheckoutData(checkoutData, title);
|
|
1360
1487
|
if (!((_b = (_a = this.app) == null ? void 0 : _a.request) == null ? void 0 : _b.post)) {
|
|
1361
1488
|
throw new Error("app.request 不可用");
|
|
1362
1489
|
}
|
|
@@ -1372,20 +1499,20 @@ var Server = class {
|
|
|
1372
1499
|
errorResponse: response,
|
|
1373
1500
|
response,
|
|
1374
1501
|
normalizedResponse: this.normalizeCheckoutResponse(response),
|
|
1375
|
-
checkoutData
|
|
1502
|
+
checkoutData
|
|
1376
1503
|
};
|
|
1377
1504
|
}
|
|
1378
1505
|
const fresh = this.extractOrderDataFromCheckoutResponse(response);
|
|
1379
1506
|
const externalSaleNumber = this.getCheckoutExternalSaleNumber(
|
|
1380
|
-
|
|
1507
|
+
checkoutData,
|
|
1381
1508
|
{
|
|
1382
1509
|
external_sale_number: params.externalSaleNumber,
|
|
1383
|
-
data:
|
|
1510
|
+
data: checkoutData
|
|
1384
1511
|
}
|
|
1385
1512
|
);
|
|
1386
1513
|
const syncedOrder = await this.persistSyncedCheckoutOrder({
|
|
1387
1514
|
backendPath,
|
|
1388
|
-
checkoutData
|
|
1515
|
+
checkoutData,
|
|
1389
1516
|
externalSaleNumber,
|
|
1390
1517
|
fresh,
|
|
1391
1518
|
title,
|
|
@@ -1396,11 +1523,11 @@ var Server = class {
|
|
|
1396
1523
|
checkoutResponseOrder: fresh
|
|
1397
1524
|
}) : void 0;
|
|
1398
1525
|
if (printableSyncedOrder && this.shouldPrintSyncedOrder({
|
|
1399
|
-
checkoutData
|
|
1526
|
+
checkoutData,
|
|
1400
1527
|
syncedOrder: printableSyncedOrder
|
|
1401
1528
|
})) {
|
|
1402
1529
|
await this.dispatchPrintOtherReceiptTask({
|
|
1403
|
-
checkoutData
|
|
1530
|
+
checkoutData,
|
|
1404
1531
|
syncedOrder: printableSyncedOrder,
|
|
1405
1532
|
response,
|
|
1406
1533
|
deviceId: params.deviceId
|
|
@@ -1410,7 +1537,7 @@ var Server = class {
|
|
|
1410
1537
|
rejected: false,
|
|
1411
1538
|
response,
|
|
1412
1539
|
normalizedResponse: this.normalizeCheckoutResponse(response),
|
|
1413
|
-
checkoutData
|
|
1540
|
+
checkoutData,
|
|
1414
1541
|
syncedOrder,
|
|
1415
1542
|
fresh
|
|
1416
1543
|
};
|
|
@@ -1423,6 +1550,54 @@ var Server = class {
|
|
|
1423
1550
|
delete next.syncMode;
|
|
1424
1551
|
return next;
|
|
1425
1552
|
}
|
|
1553
|
+
buildRemoteCheckoutData(data, title) {
|
|
1554
|
+
const next = (0, import_lodash_es.cloneDeep)(this.omitCheckoutSyncMode(data));
|
|
1555
|
+
if (!next || typeof next !== "object")
|
|
1556
|
+
return next;
|
|
1557
|
+
const record = next;
|
|
1558
|
+
if (!Array.isArray(record.payments))
|
|
1559
|
+
return next;
|
|
1560
|
+
const originalPayments = record.payments;
|
|
1561
|
+
const filteredPayments = originalPayments.filter((payment) => !(0, import_payment_utils.isPendingOrderPayment)(payment));
|
|
1562
|
+
const removedPayments = originalPayments.filter((payment) => (0, import_payment_utils.isPendingOrderPayment)(payment));
|
|
1563
|
+
record.payments = filteredPayments;
|
|
1564
|
+
this.logInfo(`${title}: checkout 云端支付项已过滤`, {
|
|
1565
|
+
external_sale_number: record.external_sale_number,
|
|
1566
|
+
original_payment_count: originalPayments.length,
|
|
1567
|
+
remote_payment_count: filteredPayments.length,
|
|
1568
|
+
filtered_pending_count: removedPayments.length,
|
|
1569
|
+
filtered_payment_identities: removedPayments.map((payment) => (0, import_payment_utils.getOrderPaymentIdentityKeys)(payment))
|
|
1570
|
+
});
|
|
1571
|
+
return next;
|
|
1572
|
+
}
|
|
1573
|
+
mergeCheckoutSyncPayments(checkoutData, fresh, title) {
|
|
1574
|
+
const localPayments = Array.isArray(checkoutData == null ? void 0 : checkoutData.payments) ? checkoutData.payments : [];
|
|
1575
|
+
const freshRecord = fresh;
|
|
1576
|
+
if (!Array.isArray(freshRecord.payments)) {
|
|
1577
|
+
return localPayments.length > 0 ? { ...freshRecord, payments: (0, import_lodash_es.cloneDeep)(localPayments) } : freshRecord;
|
|
1578
|
+
}
|
|
1579
|
+
const freshPayments = freshRecord.payments;
|
|
1580
|
+
const mergedPayments = (0, import_payment_utils.mergeOrderPaymentListsByIdentity)(
|
|
1581
|
+
localPayments,
|
|
1582
|
+
freshPayments,
|
|
1583
|
+
{ preserveUnmatchedExistingWhen: import_payment_utils.isIdentifiedPendingOrderPayment }
|
|
1584
|
+
);
|
|
1585
|
+
const remoteIdentityKeys = new Set(
|
|
1586
|
+
freshPayments.flatMap((payment) => (0, import_payment_utils.getOrderPaymentIdentityKeys)(payment))
|
|
1587
|
+
);
|
|
1588
|
+
const preservedPending = localPayments.filter((payment) => (0, import_payment_utils.isIdentifiedPendingOrderPayment)(payment) && !(0, import_payment_utils.getOrderPaymentIdentityKeys)(payment).some((key) => remoteIdentityKeys.has(key)));
|
|
1589
|
+
if (preservedPending.length > 0) {
|
|
1590
|
+
this.logInfo(`${title}: checkout 响应合并保留本地 pending 支付项`, {
|
|
1591
|
+
external_sale_number: checkoutData == null ? void 0 : checkoutData.external_sale_number,
|
|
1592
|
+
preserved_pending_count: preservedPending.length,
|
|
1593
|
+
preserved_payment_identities: preservedPending.map((payment) => (0, import_payment_utils.getOrderPaymentIdentityKeys)(payment))
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
return {
|
|
1597
|
+
...freshRecord,
|
|
1598
|
+
payments: mergedPayments
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1426
1601
|
async persistSyncedCheckoutOrder(params) {
|
|
1427
1602
|
const {
|
|
1428
1603
|
backendPath,
|
|
@@ -1437,15 +1612,17 @@ var Server = class {
|
|
|
1437
1612
|
if (this.order && fresh && (shouldMergeRemoteOrder || persistCheckoutDataWithResponse)) {
|
|
1438
1613
|
syncedOrder = persistCheckoutDataWithResponse ? {
|
|
1439
1614
|
...checkoutData,
|
|
1440
|
-
...fresh,
|
|
1615
|
+
...this.mergeCheckoutSyncPayments(checkoutData, fresh, title),
|
|
1441
1616
|
external_sale_number: fresh.external_sale_number ?? externalSaleNumber,
|
|
1442
|
-
need_sync: 0
|
|
1617
|
+
need_sync: 0,
|
|
1618
|
+
is_draft_order: 0
|
|
1443
1619
|
} : {
|
|
1444
|
-
...fresh,
|
|
1620
|
+
...this.mergeCheckoutSyncPayments(checkoutData, fresh, title),
|
|
1445
1621
|
external_sale_number: fresh.external_sale_number ?? externalSaleNumber,
|
|
1446
|
-
need_sync: 0
|
|
1622
|
+
need_sync: 0,
|
|
1623
|
+
is_draft_order: 0
|
|
1447
1624
|
};
|
|
1448
|
-
await this.order.upsertOrdersFromRemote([syncedOrder]);
|
|
1625
|
+
await this.order.upsertOrdersFromRemote([syncedOrder], "checkoutSync");
|
|
1449
1626
|
this.logInfo(`${title}: sync_sales 完整订单已同步到本地`, {
|
|
1450
1627
|
order_id: fresh.order_id,
|
|
1451
1628
|
external_sale_number: syncedOrder.external_sale_number,
|
|
@@ -1463,7 +1640,8 @@ var Server = class {
|
|
|
1463
1640
|
...checkoutData,
|
|
1464
1641
|
...patch,
|
|
1465
1642
|
external_sale_number: externalSaleNumber,
|
|
1466
|
-
need_sync: 0
|
|
1643
|
+
need_sync: 0,
|
|
1644
|
+
is_draft_order: 0
|
|
1467
1645
|
};
|
|
1468
1646
|
this.logInfo(`${title}: sync_sales 已按 external_sale_number 标记本地订单`, {
|
|
1469
1647
|
order_id: (syncedOrder == null ? void 0 : syncedOrder.order_id) ?? null,
|
|
@@ -1843,6 +2021,11 @@ var Server = class {
|
|
|
1843
2021
|
path: "/shop/order/sales/checkout",
|
|
1844
2022
|
handler: this.handleOrderSalesCheckout.bind(this)
|
|
1845
2023
|
},
|
|
2024
|
+
{
|
|
2025
|
+
method: "post",
|
|
2026
|
+
path: "/shop/order/sales/draft",
|
|
2027
|
+
handler: this.handleOrderSalesDraft.bind(this)
|
|
2028
|
+
},
|
|
1846
2029
|
{
|
|
1847
2030
|
method: "post",
|
|
1848
2031
|
path: "/order/checkout",
|
|
@@ -1853,6 +2036,16 @@ var Server = class {
|
|
|
1853
2036
|
path: "/shop/local/print-order",
|
|
1854
2037
|
handler: this.handleLocalPrintOrder.bind(this)
|
|
1855
2038
|
},
|
|
2039
|
+
{
|
|
2040
|
+
method: "post",
|
|
2041
|
+
path: "/shop/local/getLocalPayment",
|
|
2042
|
+
handler: this.handleGetLocalPayment.bind(this)
|
|
2043
|
+
},
|
|
2044
|
+
{
|
|
2045
|
+
method: "post",
|
|
2046
|
+
path: "/shop/local/updateLocalPayment",
|
|
2047
|
+
handler: this.handleUpdateLocalPayment.bind(this)
|
|
2048
|
+
},
|
|
1856
2049
|
{
|
|
1857
2050
|
method: "post",
|
|
1858
2051
|
path: "/shop/machinecode/batch",
|
|
@@ -2694,6 +2887,405 @@ var Server = class {
|
|
|
2694
2887
|
};
|
|
2695
2888
|
}
|
|
2696
2889
|
}
|
|
2890
|
+
createLocalPaymentOperationId(action) {
|
|
2891
|
+
return `local_payment_${action}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
2892
|
+
}
|
|
2893
|
+
buildLocalPaymentOrderLogContext(order) {
|
|
2894
|
+
if (!order)
|
|
2895
|
+
return {};
|
|
2896
|
+
return {
|
|
2897
|
+
order_id: order.order_id ?? null,
|
|
2898
|
+
external_sale_number: order.external_sale_number ?? null,
|
|
2899
|
+
order_number: order.order_number ?? null,
|
|
2900
|
+
shop_order_number: order.shop_order_number ?? null,
|
|
2901
|
+
shop_full_order_number: order.shop_full_order_number ?? null,
|
|
2902
|
+
order_status: order.status ?? null,
|
|
2903
|
+
payment_status: order.payment_status ?? null,
|
|
2904
|
+
is_draft_order: Number(order.is_draft_order || 0),
|
|
2905
|
+
need_sync: Number(order.need_sync || 0),
|
|
2906
|
+
platform: order.platform ?? null,
|
|
2907
|
+
business_code: order.business_code ?? null,
|
|
2908
|
+
order_sales_channel: order.order_sales_channel ?? null,
|
|
2909
|
+
sales_channel: order.sales_channel ?? null,
|
|
2910
|
+
order_type: order.type ?? null,
|
|
2911
|
+
payments_count: Array.isArray(order.payments) ? order.payments.length : 0
|
|
2912
|
+
};
|
|
2913
|
+
}
|
|
2914
|
+
isValidLocalPaymentDecimal(value) {
|
|
2915
|
+
if (typeof value !== "string" && typeof value !== "number")
|
|
2916
|
+
return false;
|
|
2917
|
+
if (typeof value === "string" && value.trim() === "")
|
|
2918
|
+
return false;
|
|
2919
|
+
try {
|
|
2920
|
+
return new import_decimal.default(value).isFinite();
|
|
2921
|
+
} catch {
|
|
2922
|
+
return false;
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
getInvalidLocalPaymentSurchargeFields(serviceCharge, cardReaderSurcharge) {
|
|
2926
|
+
const invalidFields = [];
|
|
2927
|
+
if (serviceCharge !== void 0) {
|
|
2928
|
+
if (serviceCharge === null || typeof serviceCharge !== "object" || Array.isArray(serviceCharge)) {
|
|
2929
|
+
invalidFields.push("service_charge");
|
|
2930
|
+
} else {
|
|
2931
|
+
const input = serviceCharge;
|
|
2932
|
+
if (input.fixed !== void 0 && !this.isValidLocalPaymentDecimal(input.fixed)) {
|
|
2933
|
+
invalidFields.push("service_charge.fixed");
|
|
2934
|
+
}
|
|
2935
|
+
if (input.percentage !== void 0 && !this.isValidLocalPaymentDecimal(input.percentage)) {
|
|
2936
|
+
invalidFields.push("service_charge.percentage");
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
if (cardReaderSurcharge !== void 0 && !this.isValidLocalPaymentDecimal(cardReaderSurcharge)) {
|
|
2941
|
+
invalidFields.push("card_reader_surcharge");
|
|
2942
|
+
}
|
|
2943
|
+
return invalidFields;
|
|
2944
|
+
}
|
|
2945
|
+
buildLocalPaymentSurchargeUpdate(params) {
|
|
2946
|
+
var _a, _b, _c;
|
|
2947
|
+
const amount = new import_decimal.default(((_a = params.serviceCharge) == null ? void 0 : _a.fixed) || 0).plus(params.cardReaderSurcharge || 0).toFixed(2);
|
|
2948
|
+
const serviceFee = new import_decimal.default(params.paymentAmount || 0).times(((_b = params.serviceCharge) == null ? void 0 : _b.percentage) || 0).plus(amount).toDecimalPlaces(2).toFixed(2);
|
|
2949
|
+
return {
|
|
2950
|
+
service_charge: {
|
|
2951
|
+
amount,
|
|
2952
|
+
...((_c = params.serviceCharge) == null ? void 0 : _c.percentage) !== void 0 ? { percentage: params.serviceCharge.percentage } : {}
|
|
2953
|
+
},
|
|
2954
|
+
service_fee: serviceFee
|
|
2955
|
+
};
|
|
2956
|
+
}
|
|
2957
|
+
async runLocalPaymentUpdateInQueue(key, task, context) {
|
|
2958
|
+
var _a;
|
|
2959
|
+
const queuedAt = Date.now();
|
|
2960
|
+
const hasPreviousTask = this.localPaymentUpdateQueues.has(key);
|
|
2961
|
+
const previous = this.localPaymentUpdateQueues.get(key) || Promise.resolve();
|
|
2962
|
+
this.logInfo("handleUpdateLocalPayment: 串行队列入队", {
|
|
2963
|
+
...context,
|
|
2964
|
+
queue_key: key,
|
|
2965
|
+
waiting_for_previous: hasPreviousTask,
|
|
2966
|
+
active_queue_count: this.localPaymentUpdateQueues.size
|
|
2967
|
+
});
|
|
2968
|
+
const current = previous.catch(() => void 0).then(async () => {
|
|
2969
|
+
this.logInfo("handleUpdateLocalPayment: 串行队列开始执行", {
|
|
2970
|
+
...context,
|
|
2971
|
+
queue_key: key,
|
|
2972
|
+
queue_wait_ms: Date.now() - queuedAt
|
|
2973
|
+
});
|
|
2974
|
+
return task();
|
|
2975
|
+
});
|
|
2976
|
+
const tail = current.then(() => void 0, () => void 0);
|
|
2977
|
+
this.localPaymentUpdateQueues.set(key, tail);
|
|
2978
|
+
try {
|
|
2979
|
+
const result = await current;
|
|
2980
|
+
this.logInfo("handleUpdateLocalPayment: 串行队列执行完成", {
|
|
2981
|
+
...context,
|
|
2982
|
+
queue_key: key,
|
|
2983
|
+
total_duration_ms: Date.now() - queuedAt,
|
|
2984
|
+
result_code: result == null ? void 0 : result.code,
|
|
2985
|
+
result_status: result == null ? void 0 : result.status,
|
|
2986
|
+
payment: (_a = result == null ? void 0 : result.data) == null ? void 0 : _a.payment
|
|
2987
|
+
});
|
|
2988
|
+
return result;
|
|
2989
|
+
} catch (error) {
|
|
2990
|
+
this.logError("handleUpdateLocalPayment: 串行队列执行失败", {
|
|
2991
|
+
...context,
|
|
2992
|
+
queue_key: key,
|
|
2993
|
+
total_duration_ms: Date.now() - queuedAt,
|
|
2994
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2995
|
+
error_detail: this.normalizeUnknownError(error)
|
|
2996
|
+
});
|
|
2997
|
+
throw error;
|
|
2998
|
+
} finally {
|
|
2999
|
+
let released = false;
|
|
3000
|
+
if (this.localPaymentUpdateQueues.get(key) === tail) {
|
|
3001
|
+
this.localPaymentUpdateQueues.delete(key);
|
|
3002
|
+
released = true;
|
|
3003
|
+
}
|
|
3004
|
+
this.logInfo("handleUpdateLocalPayment: 串行队列释放", {
|
|
3005
|
+
...context,
|
|
3006
|
+
queue_key: key,
|
|
3007
|
+
released,
|
|
3008
|
+
active_queue_count: this.localPaymentUpdateQueues.size
|
|
3009
|
+
});
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
async processLocalPaymentUpdate(params) {
|
|
3013
|
+
var _a, _b, _c;
|
|
3014
|
+
const requestContext = {
|
|
3015
|
+
operation_id: params.operationId,
|
|
3016
|
+
sale_id: params.saleId,
|
|
3017
|
+
payment_number: params.paymentNumber,
|
|
3018
|
+
transaction_number: params.number,
|
|
3019
|
+
requested_status: params.status,
|
|
3020
|
+
service_charge: params.serviceCharge ?? null,
|
|
3021
|
+
card_reader_surcharge: params.cardReaderSurcharge ?? null
|
|
3022
|
+
};
|
|
3023
|
+
this.logInfo("processLocalPaymentUpdate: 开始处理", requestContext);
|
|
3024
|
+
if (!this.order) {
|
|
3025
|
+
this.logError("processLocalPaymentUpdate: Order 模块未注册", requestContext);
|
|
3026
|
+
return { code: 500, status: false, message: "Order 模块未注册", data: null };
|
|
3027
|
+
}
|
|
3028
|
+
this.logInfo("processLocalPaymentUpdate: 开始查询本地支付项", requestContext);
|
|
3029
|
+
const found = await this.order.getLocalPayment({
|
|
3030
|
+
saleId: params.saleId,
|
|
3031
|
+
paymentNumber: params.paymentNumber,
|
|
3032
|
+
operationId: params.operationId
|
|
3033
|
+
});
|
|
3034
|
+
if (!found) {
|
|
3035
|
+
this.logWarning("processLocalPaymentUpdate: 本地支付项不存在", requestContext);
|
|
3036
|
+
return { code: 404, status: false, message: "本地支付项不存在", data: null };
|
|
3037
|
+
}
|
|
3038
|
+
const surchargeUpdate = params.status === "success" && params.hasSurchargeInput ? this.buildLocalPaymentSurchargeUpdate({
|
|
3039
|
+
paymentAmount: (_a = found.payment) == null ? void 0 : _a.amount,
|
|
3040
|
+
serviceCharge: params.serviceCharge,
|
|
3041
|
+
cardReaderSurcharge: params.cardReaderSurcharge
|
|
3042
|
+
}) : void 0;
|
|
3043
|
+
const incomingPaymentUpdate = params.status === "success" ? {
|
|
3044
|
+
status: "paid",
|
|
3045
|
+
...surchargeUpdate || {},
|
|
3046
|
+
metadata: {
|
|
3047
|
+
unique_payment_number: params.number,
|
|
3048
|
+
transactions: [{ number: params.number, status: "success" }]
|
|
3049
|
+
}
|
|
3050
|
+
} : {
|
|
3051
|
+
metadata: {
|
|
3052
|
+
transactions: [{ number: params.number, status: "fail" }]
|
|
3053
|
+
}
|
|
3054
|
+
};
|
|
3055
|
+
const transactions = Array.isArray((_c = (_b = found.payment) == null ? void 0 : _b.metadata) == null ? void 0 : _c.transactions) ? found.payment.metadata.transactions : [];
|
|
3056
|
+
const existingTransaction = transactions.find((item) => String((item == null ? void 0 : item.number) || "") === params.number);
|
|
3057
|
+
const hasRecordedSuccess = transactions.some((item) => (item == null ? void 0 : item.status) === "success");
|
|
3058
|
+
const orderIsDraft = Number(found.order.is_draft_order || 0) === 1;
|
|
3059
|
+
const foundContext = {
|
|
3060
|
+
...requestContext,
|
|
3061
|
+
matched_by: found.matchedBy,
|
|
3062
|
+
payment_index: found.paymentIndex,
|
|
3063
|
+
...this.buildLocalPaymentOrderLogContext(found.order),
|
|
3064
|
+
payment: found.payment,
|
|
3065
|
+
incoming_payment_update: incomingPaymentUpdate,
|
|
3066
|
+
existing_transaction: existingTransaction || null,
|
|
3067
|
+
has_recorded_success: hasRecordedSuccess
|
|
3068
|
+
};
|
|
3069
|
+
this.logInfo("processLocalPaymentUpdate: 查询命中", foundContext);
|
|
3070
|
+
if (params.status === "fail" && (found.payment.status === "paid" || hasRecordedSuccess)) {
|
|
3071
|
+
this.logInfo("processLocalPaymentUpdate: 幂等返回", {
|
|
3072
|
+
...foundContext,
|
|
3073
|
+
idempotent_reason: "ignore_failure_after_success"
|
|
3074
|
+
});
|
|
3075
|
+
return {
|
|
3076
|
+
code: 200,
|
|
3077
|
+
status: true,
|
|
3078
|
+
message: "",
|
|
3079
|
+
data: { payment: found.payment, order: found.order, idempotent: true }
|
|
3080
|
+
};
|
|
3081
|
+
}
|
|
3082
|
+
const alreadyRecordedFailure = params.status === "fail" && (existingTransaction == null ? void 0 : existingTransaction.status) === "fail";
|
|
3083
|
+
if (alreadyRecordedFailure) {
|
|
3084
|
+
this.logInfo("processLocalPaymentUpdate: 幂等返回", {
|
|
3085
|
+
...foundContext,
|
|
3086
|
+
idempotent_reason: "failure_already_recorded"
|
|
3087
|
+
});
|
|
3088
|
+
return {
|
|
3089
|
+
code: 200,
|
|
3090
|
+
status: true,
|
|
3091
|
+
message: "",
|
|
3092
|
+
data: { payment: found.payment, order: found.order, idempotent: true }
|
|
3093
|
+
};
|
|
3094
|
+
}
|
|
3095
|
+
if (params.status === "success" && (existingTransaction == null ? void 0 : existingTransaction.status) === "success" && found.payment.status === "paid" && !orderIsDraft) {
|
|
3096
|
+
this.logInfo("processLocalPaymentUpdate: 幂等返回", {
|
|
3097
|
+
...foundContext,
|
|
3098
|
+
idempotent_reason: "success_already_committed"
|
|
3099
|
+
});
|
|
3100
|
+
return {
|
|
3101
|
+
code: 200,
|
|
3102
|
+
status: true,
|
|
3103
|
+
message: "",
|
|
3104
|
+
data: { payment: found.payment, order: found.order, idempotent: true }
|
|
3105
|
+
};
|
|
3106
|
+
}
|
|
3107
|
+
if (params.status === "success") {
|
|
3108
|
+
this.logInfo("processLocalPaymentUpdate: 进入 success 恢复分支", {
|
|
3109
|
+
...foundContext,
|
|
3110
|
+
force_submit_if_paid: found.payment.status === "paid" && orderIsDraft
|
|
3111
|
+
});
|
|
3112
|
+
return this.processSuccessfulLocalPayment({
|
|
3113
|
+
...params,
|
|
3114
|
+
order: found.order,
|
|
3115
|
+
payment: found.payment,
|
|
3116
|
+
matchBy: found.matchedBy === "payment_number" ? "payment_number" : "compat",
|
|
3117
|
+
forceSubmitIfPaid: found.payment.status === "paid" && orderIsDraft,
|
|
3118
|
+
paymentUpdate: incomingPaymentUpdate
|
|
3119
|
+
});
|
|
3120
|
+
}
|
|
3121
|
+
this.logInfo("processLocalPaymentUpdate: 进入 fail 本地更新分支", {
|
|
3122
|
+
...foundContext,
|
|
3123
|
+
incoming_payment_update: incomingPaymentUpdate
|
|
3124
|
+
});
|
|
3125
|
+
let updated;
|
|
3126
|
+
try {
|
|
3127
|
+
updated = await this.order.updateLocalPayment({
|
|
3128
|
+
saleId: params.saleId,
|
|
3129
|
+
paymentNumber: params.paymentNumber,
|
|
3130
|
+
operationId: params.operationId,
|
|
3131
|
+
updates: incomingPaymentUpdate
|
|
3132
|
+
});
|
|
3133
|
+
} catch (error) {
|
|
3134
|
+
this.logError("processLocalPaymentUpdate: fail 本地更新失败", {
|
|
3135
|
+
...foundContext,
|
|
3136
|
+
incoming_payment_update: incomingPaymentUpdate,
|
|
3137
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3138
|
+
error_detail: this.normalizeUnknownError(error)
|
|
3139
|
+
});
|
|
3140
|
+
throw error;
|
|
3141
|
+
}
|
|
3142
|
+
if (!updated) {
|
|
3143
|
+
this.logWarning("processLocalPaymentUpdate: fail 本地更新未命中", foundContext);
|
|
3144
|
+
return { code: 404, status: false, message: "本地支付项不存在", data: null };
|
|
3145
|
+
}
|
|
3146
|
+
this.logInfo("processLocalPaymentUpdate: fail 本地更新完成", {
|
|
3147
|
+
...requestContext,
|
|
3148
|
+
...this.buildLocalPaymentOrderLogContext(updated.order),
|
|
3149
|
+
previous_payment: updated.previousPayment,
|
|
3150
|
+
payment: updated.payment
|
|
3151
|
+
});
|
|
3152
|
+
return {
|
|
3153
|
+
code: 200,
|
|
3154
|
+
status: true,
|
|
3155
|
+
message: "",
|
|
3156
|
+
data: {
|
|
3157
|
+
local_only: true,
|
|
3158
|
+
payment: updated.payment,
|
|
3159
|
+
order: updated.order
|
|
3160
|
+
}
|
|
3161
|
+
};
|
|
3162
|
+
}
|
|
3163
|
+
async processSuccessfulLocalPayment(params) {
|
|
3164
|
+
var _a, _b, _c, _d, _e;
|
|
3165
|
+
const moduleName = `local_payment_recovery_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
3166
|
+
const baseSales = new import_BaseSales.BaseSalesImpl(moduleName);
|
|
3167
|
+
const startedAt = Date.now();
|
|
3168
|
+
const recoveryContext = {
|
|
3169
|
+
operation_id: params.operationId,
|
|
3170
|
+
sale_id: params.saleId,
|
|
3171
|
+
payment_number: params.paymentNumber,
|
|
3172
|
+
transaction_number: params.number,
|
|
3173
|
+
requested_status: "success",
|
|
3174
|
+
match_by: params.matchBy,
|
|
3175
|
+
force_submit_if_paid: params.forceSubmitIfPaid,
|
|
3176
|
+
incoming_payment_update: params.paymentUpdate,
|
|
3177
|
+
base_sales_module_name: moduleName,
|
|
3178
|
+
...this.buildLocalPaymentOrderLogContext(params.order),
|
|
3179
|
+
payment: params.payment
|
|
3180
|
+
};
|
|
3181
|
+
this.logInfo("processSuccessfulLocalPayment: 创建临时 BaseSales", recoveryContext);
|
|
3182
|
+
try {
|
|
3183
|
+
const order = this.sanitizeLocalRecoveryOrder(params.order);
|
|
3184
|
+
this.logInfo("processSuccessfulLocalPayment: 本地订单清洗完成", {
|
|
3185
|
+
...recoveryContext,
|
|
3186
|
+
sanitized_order_id: order.order_id ?? null,
|
|
3187
|
+
removed_synthetic_order_id: params.order.order_id != null && order.order_id == null
|
|
3188
|
+
});
|
|
3189
|
+
await baseSales.initialize(this.core, {
|
|
3190
|
+
otherParams: {
|
|
3191
|
+
platform: order.platform,
|
|
3192
|
+
businessCode: order.business_code,
|
|
3193
|
+
business_code: order.business_code,
|
|
3194
|
+
channel: order.order_sales_channel || order.sales_channel,
|
|
3195
|
+
type: order.type,
|
|
3196
|
+
enableTempOrderPersist: false
|
|
3197
|
+
}
|
|
3198
|
+
});
|
|
3199
|
+
this.logInfo("processSuccessfulLocalPayment: BaseSales 初始化完成", recoveryContext);
|
|
3200
|
+
await baseSales.replaceTempOrder(order);
|
|
3201
|
+
this.logInfo("processSuccessfulLocalPayment: 本地订单 tempOrder 恢复完成", recoveryContext);
|
|
3202
|
+
this.logInfo("processSuccessfulLocalPayment: 开始更新支付项并提交", {
|
|
3203
|
+
...recoveryContext,
|
|
3204
|
+
incoming_payment_update: params.paymentUpdate
|
|
3205
|
+
});
|
|
3206
|
+
const result = await baseSales.updateOrderPayment(
|
|
3207
|
+
params.paymentNumber,
|
|
3208
|
+
params.paymentUpdate,
|
|
3209
|
+
{
|
|
3210
|
+
submitWhenPaid: true,
|
|
3211
|
+
matchBy: params.matchBy,
|
|
3212
|
+
forceSubmitIfPaid: params.forceSubmitIfPaid,
|
|
3213
|
+
applyUpdatesWhenPaid: params.forceSubmitIfPaid,
|
|
3214
|
+
smallTicketDataFlag: 1
|
|
3215
|
+
}
|
|
3216
|
+
);
|
|
3217
|
+
this.logInfo("processSuccessfulLocalPayment: 支付恢复完成", {
|
|
3218
|
+
...recoveryContext,
|
|
3219
|
+
duration_ms: Date.now() - startedAt,
|
|
3220
|
+
payment: result.payment,
|
|
3221
|
+
payments_count: ((_a = result.payments) == null ? void 0 : _a.length) || 0,
|
|
3222
|
+
summary: result.summary,
|
|
3223
|
+
sync_result: result.syncResult ? {
|
|
3224
|
+
is_fully_paid: result.syncResult.isFullyPaid,
|
|
3225
|
+
is_order_fully_paid: result.syncResult.isOrderFullyPaid,
|
|
3226
|
+
is_deposit_fully_paid: result.syncResult.isDepositFullyPaid,
|
|
3227
|
+
payment_stage: result.syncResult.paymentStage,
|
|
3228
|
+
deposit_amount: result.syncResult.depositAmount,
|
|
3229
|
+
order_expected_amount: result.syncResult.orderExpectedAmount,
|
|
3230
|
+
submit_result_code: (_b = result.syncResult.submitResult) == null ? void 0 : _b.code,
|
|
3231
|
+
submit_result_status: (_c = result.syncResult.submitResult) == null ? void 0 : _c.status
|
|
3232
|
+
} : null,
|
|
3233
|
+
draft_result: result.draftResult ? {
|
|
3234
|
+
code: (_d = result.draftResult) == null ? void 0 : _d.code,
|
|
3235
|
+
status: (_e = result.draftResult) == null ? void 0 : _e.status
|
|
3236
|
+
} : null,
|
|
3237
|
+
draft_error: result.draftError instanceof Error ? result.draftError.message : result.draftError
|
|
3238
|
+
});
|
|
3239
|
+
return {
|
|
3240
|
+
code: 200,
|
|
3241
|
+
status: true,
|
|
3242
|
+
message: "",
|
|
3243
|
+
data: {
|
|
3244
|
+
payment: result.payment,
|
|
3245
|
+
payments: result.payments,
|
|
3246
|
+
summary: result.summary,
|
|
3247
|
+
sync_result: result.syncResult
|
|
3248
|
+
}
|
|
3249
|
+
};
|
|
3250
|
+
} catch (error) {
|
|
3251
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3252
|
+
this.logError("processSuccessfulLocalPayment: 支付恢复失败", {
|
|
3253
|
+
...recoveryContext,
|
|
3254
|
+
duration_ms: Date.now() - startedAt,
|
|
3255
|
+
error: message,
|
|
3256
|
+
error_detail: this.normalizeUnknownError(error)
|
|
3257
|
+
});
|
|
3258
|
+
return { code: 500, status: false, message, data: null };
|
|
3259
|
+
} finally {
|
|
3260
|
+
try {
|
|
3261
|
+
await baseSales.destroy();
|
|
3262
|
+
this.logInfo("processSuccessfulLocalPayment: 临时 BaseSales 销毁完成", {
|
|
3263
|
+
...recoveryContext,
|
|
3264
|
+
duration_ms: Date.now() - startedAt
|
|
3265
|
+
});
|
|
3266
|
+
} catch (error) {
|
|
3267
|
+
this.logError("processSuccessfulLocalPayment: 临时 BaseSales 销毁失败", {
|
|
3268
|
+
...recoveryContext,
|
|
3269
|
+
duration_ms: Date.now() - startedAt,
|
|
3270
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3271
|
+
error_detail: this.normalizeUnknownError(error)
|
|
3272
|
+
});
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
}
|
|
3276
|
+
sanitizeLocalRecoveryOrder(order) {
|
|
3277
|
+
const next = {
|
|
3278
|
+
...order,
|
|
3279
|
+
country_calling_code: String(order.country_calling_code ?? ""),
|
|
3280
|
+
phone: String(order.phone ?? ""),
|
|
3281
|
+
email: String(order.email ?? "")
|
|
3282
|
+
};
|
|
3283
|
+
const externalSaleNumber = next.external_sale_number;
|
|
3284
|
+
if (Number(next.is_draft_order || 0) === 1 && next.order_id !== void 0 && externalSaleNumber !== void 0 && String(next.order_id) === String(externalSaleNumber)) {
|
|
3285
|
+
delete next.order_id;
|
|
3286
|
+
}
|
|
3287
|
+
return next;
|
|
3288
|
+
}
|
|
2697
3289
|
getDeviceTaskPlugin() {
|
|
2698
3290
|
var _a, _b;
|
|
2699
3291
|
return ((_b = (_a = this.app) == null ? void 0 : _a.getPlugin) == null ? void 0 : _b.call(_a, "deviceTask")) || null;
|
|
@@ -3216,6 +3808,59 @@ var Server = class {
|
|
|
3216
3808
|
};
|
|
3217
3809
|
}
|
|
3218
3810
|
}
|
|
3811
|
+
async handleOrderDraftSubmit(params) {
|
|
3812
|
+
var _a, _b, _c;
|
|
3813
|
+
const { data, title } = params;
|
|
3814
|
+
this.logInfo(`${title}: 开始处理`, {
|
|
3815
|
+
order_id: data == null ? void 0 : data.order_id,
|
|
3816
|
+
external_sale_number: data == null ? void 0 : data.external_sale_number,
|
|
3817
|
+
order_number: data == null ? void 0 : data.order_number
|
|
3818
|
+
});
|
|
3819
|
+
const normalizedData = await this.normalizeCheckoutSubmitData(data, title);
|
|
3820
|
+
const createdAt = normalizedData.created_at || normalizedData.create_date || (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
3821
|
+
const draftOrder = {
|
|
3822
|
+
...normalizedData,
|
|
3823
|
+
external_sale_number: normalizedData.external_sale_number || `LOCAL_DRAFT_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`,
|
|
3824
|
+
created_at: createdAt,
|
|
3825
|
+
schedule_date: normalizedData.schedule_date || createdAt,
|
|
3826
|
+
need_sync: 0,
|
|
3827
|
+
is_draft_order: 1
|
|
3828
|
+
};
|
|
3829
|
+
if (!this.order || typeof this.order.upsertLocalDraftOrders !== "function") {
|
|
3830
|
+
this.logError(`${title}: Order 模块不支持本地草稿写入`);
|
|
3831
|
+
return {
|
|
3832
|
+
code: 500,
|
|
3833
|
+
status: false,
|
|
3834
|
+
message: "Order 模块不支持本地草稿写入",
|
|
3835
|
+
data: null
|
|
3836
|
+
};
|
|
3837
|
+
}
|
|
3838
|
+
try {
|
|
3839
|
+
await this.order.upsertLocalDraftOrders([draftOrder]);
|
|
3840
|
+
this.logInfo(`${title}: 草稿订单已写入本地`, {
|
|
3841
|
+
order_id: draftOrder.order_id,
|
|
3842
|
+
external_sale_number: draftOrder.external_sale_number
|
|
3843
|
+
});
|
|
3844
|
+
return {
|
|
3845
|
+
code: 200,
|
|
3846
|
+
status: true,
|
|
3847
|
+
message: "",
|
|
3848
|
+
data: {
|
|
3849
|
+
...draftOrder,
|
|
3850
|
+
amount_gap: (_a = draftOrder == null ? void 0 : draftOrder.summary) == null ? void 0 : _a.amount_gap,
|
|
3851
|
+
expect_amount: (_b = draftOrder == null ? void 0 : draftOrder.summary) == null ? void 0 : _b.expect_amount,
|
|
3852
|
+
total_amount: (_c = draftOrder == null ? void 0 : draftOrder.summary) == null ? void 0 : _c.total_amount,
|
|
3853
|
+
payment_status: draftOrder == null ? void 0 : draftOrder.payment_status
|
|
3854
|
+
}
|
|
3855
|
+
};
|
|
3856
|
+
} catch (error) {
|
|
3857
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3858
|
+
this.logError(`${title}: 写入本地草稿订单失败`, {
|
|
3859
|
+
error: errorMessage
|
|
3860
|
+
});
|
|
3861
|
+
return { code: 500, status: false, message: errorMessage, data: null };
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3219
3864
|
async handlePendingSyncCheckoutOrder(params) {
|
|
3220
3865
|
var _a, _b, _c, _d;
|
|
3221
3866
|
const { backendPath, data, title, reason } = params;
|
|
@@ -3291,7 +3936,8 @@ var Server = class {
|
|
|
3291
3936
|
return null;
|
|
3292
3937
|
const pendingOrder = {
|
|
3293
3938
|
...data,
|
|
3294
|
-
need_sync: 1
|
|
3939
|
+
need_sync: 1,
|
|
3940
|
+
is_draft_order: 0
|
|
3295
3941
|
};
|
|
3296
3942
|
const productMap = await this.buildSmallTicketProductMap(pendingOrder);
|
|
3297
3943
|
const orderWithProductTitles = this.withPendingSyncProductTitles(
|
|
@@ -3344,7 +3990,7 @@ var Server = class {
|
|
|
3344
3990
|
return 0;
|
|
3345
3991
|
return payments.reduce((sum, payment) => {
|
|
3346
3992
|
const status = String((payment == null ? void 0 : payment.status) || "").toLowerCase();
|
|
3347
|
-
if (status
|
|
3993
|
+
if (status !== "paid")
|
|
3348
3994
|
return sum;
|
|
3349
3995
|
return sum + this.toAmountNumber((payment == null ? void 0 : payment.amount) ?? (payment == null ? void 0 : payment.origin_amount));
|
|
3350
3996
|
}, 0);
|
|
@@ -3911,9 +4557,11 @@ var Server = class {
|
|
|
3911
4557
|
return value === void 0 ? void 0 : String(value);
|
|
3912
4558
|
}
|
|
3913
4559
|
buildCheckoutSyncSuccessPatch(fresh) {
|
|
4560
|
+
const patch = {
|
|
4561
|
+
is_draft_order: 0
|
|
4562
|
+
};
|
|
3914
4563
|
if (!fresh)
|
|
3915
|
-
return
|
|
3916
|
-
const patch = {};
|
|
4564
|
+
return patch;
|
|
3917
4565
|
if (fresh.order_id !== void 0 && fresh.order_id !== null)
|
|
3918
4566
|
patch.order_id = fresh.order_id;
|
|
3919
4567
|
if (fresh.order_number !== void 0 && fresh.order_number !== null) {
|
|
@@ -4194,6 +4842,10 @@ var Server = class {
|
|
|
4194
4842
|
const rawList = this.order.getOrders();
|
|
4195
4843
|
this.logInfo("computeOrderQueryResult: 本地订单数量", { rawCount: rawList.length });
|
|
4196
4844
|
const result = (0, import_filterOrders.filterOrders)(rawList, data);
|
|
4845
|
+
result.list.forEach((order) => {
|
|
4846
|
+
var _a;
|
|
4847
|
+
order.payments = (_a = order.payments) == null ? void 0 : _a.filter((payment) => !(0, import_payment_utils.isPendingOrderPayment)(payment));
|
|
4848
|
+
});
|
|
4197
4849
|
this.logInfo("computeOrderQueryResult: 过滤结果", {
|
|
4198
4850
|
rawCount: rawList.length,
|
|
4199
4851
|
filteredCount: result.count,
|