From 64e04cc667d625cd3c73ae36266f2dbb8c5bd443 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sun, 1 Nov 2026 16:24:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(finance):=20=E5=8E=86=E5=8F=B2=E5=BD=92?= =?UTF-8?q?=E6=A1=A3=E8=AE=A2=E5=8D=95=E9=80=80=E6=AC=BE=E8=B7=B3=E8=BF=87?= =?UTF-8?q?=E6=9C=9F=E9=97=B4=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 归档订单退款不进入财务口径,不应被历史月份/退款月份的关账状态阻断; 非归档订单退款仍严格校验期间。 --- .../services/finance/order-refund-service.ts | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/apps/backend/src/services/finance/order-refund-service.ts b/apps/backend/src/services/finance/order-refund-service.ts index 20bbceb0..13ed3ad4 100644 --- a/apps/backend/src/services/finance/order-refund-service.ts +++ b/apps/backend/src/services/finance/order-refund-service.ts @@ -143,8 +143,16 @@ export async function createManualRefund( errorCode: 'order_refund_order_not_found', }) } - await assertBasisPeriodOpen(client, order.basis_at, '退款') - await assertRefundMonthOpen(client, '退款', toChinaDate(refundedAt || now)) + const activeItems = await client.query<{ total: number }>( + `SELECT COUNT(*)::int AS total FROM order_items + WHERE order_id = $1 AND fulfillment_status <> 'archived'`, + [orderId], + ) + if (Number(activeItems.rows[0]?.total || 0) > 0) { + // 只有断代后订单才影响财务;历史归档订单退款不校验期间。 + await assertBasisPeriodOpen(client, order.basis_at, '退款') + await assertRefundMonthOpen(client, '退款', toChinaDate(refundedAt || now)) + } const itemsResult = await client.query<{ id: number @@ -398,8 +406,15 @@ export async function voidOrderRefund( errorCode: 'order_refund_already_voided', }) } - await assertBasisPeriodOpen(client, row.basis_at, '撤销退款') - await assertRefundMonthOpen(client, '撤销退款') + const activeItems = await client.query<{ total: number }>( + `SELECT COUNT(*)::int AS total FROM order_items + WHERE order_id = $1 AND fulfillment_status <> 'archived'`, + [row.order_id], + ) + if (Number(activeItems.rows[0]?.total || 0) > 0) { + await assertBasisPeriodOpen(client, row.basis_at, '撤销退款') + await assertRefundMonthOpen(client, '撤销退款') + } await client.query( ` UPDATE order_refunds @@ -666,8 +681,8 @@ export async function approveAndRecordKuaishouRefund( }) } - const existingItem = await query<{ id: number }>( - `SELECT id FROM order_items WHERE id = $1 AND order_id = $2 LIMIT 1`, + const existingItem = await query<{ id: number; fulfillment_status: string }>( + `SELECT id, fulfillment_status FROM order_items WHERE id = $1 AND order_id = $2 LIMIT 1`, [orderItemId, orderId], ) if (!existingItem.rows[0]) { @@ -682,7 +697,8 @@ export async function approveAndRecordKuaishouRefund( `SELECT COALESCE(paid_at, created_at) AS basis_at FROM orders WHERE id = $1 LIMIT 1`, [orderId], ) - if (basis.rows[0]?.basis_at) { + const platformItemArchived = existingItem.rows[0]?.fulfillment_status === 'archived' + if (!platformItemArchived && basis.rows[0]?.basis_at) { const basisDate = toChinaDate(String(basis.rows[0].basis_at)) const periodKey = basisDate.slice(0, 7) const period = await query<{ status: string }>( @@ -697,12 +713,14 @@ export async function approveAndRecordKuaishouRefund( } } - // 退款当天所属期间也必须开着,否则退款冲减会静默丢失。 + // 退款当天所属期间也必须开着,否则退款冲减会静默丢失(历史归档订单除外)。 const refundPeriodKey = CHINA_DATE_FORMATTER.format(new Date()).slice(0, 7) - const refundPeriod = await query<{ status: string }>( - `SELECT status FROM finance_periods WHERE period_key = $1 LIMIT 1`, - [refundPeriodKey], - ) + const refundPeriod = platformItemArchived + ? { rows: [] as Array<{ status: string }> } + : await query<{ status: string }>( + `SELECT status FROM finance_periods WHERE period_key = $1 LIMIT 1`, + [refundPeriodKey], + ) if (refundPeriod.rows[0]?.status === 'closed') { throw createHttpError(`退款所属期间 ${refundPeriodKey} 已关账,请先反关账后再退款`, { statusCode: 409,