fix(worker): 售后追缴自动驳回提现并扣冻结资金,修复欠款抵扣 500

- 修复欠款抵扣 SQL 参数类型冲突(debt_amount = $1 与 $1 = 0 推断不一致),
  此前手动偿还、验收报酬抵扣、充值/押金解冻/寄卖自动抵扣都会 500
- 追缴顺序改为 待解冻押金 → 提现冻结 → 可用余额 → 欠款:
  驳回待审核提现并直接扣走冻结资金,扣不完的部分退回可用余额
- 迁移 109:售后单记录 withdraw_deduction_amount,补 pending 提现部分索引
- 新增流水类型 after_sales_withdraw_deduction,前后端展示与标签同步
- 提现驳回退回余额后补调欠款自动抵扣,与充值/结算/解冻/寄卖路径对齐
- 补追缴分配单测与 SQL 参数类型静态门禁
This commit is contained in:
yml2213
2026-10-29 19:05:37 +08:00
parent fba0a13d44
commit c7d650b482
18 changed files with 372 additions and 10 deletions
@@ -84,7 +84,7 @@ const FINANCE_EVENTS_CTE = `
FROM worker_wallet_ledgers wl
WHERE wl.ledger_type IN (
'reward_settlement', 'sharing_reward', 'after_sales_deposit_deduction',
'after_sales_balance_deduction', 'after_sales_debt_offset'
'after_sales_withdraw_deduction', 'after_sales_balance_deduction', 'after_sales_debt_offset'
)
AND wl.amount <> 0
@@ -209,6 +209,7 @@ export function mapWorkerAfterSalesCase(afterSalesCase: {
resolution_note: string
recovery_amount: number
pending_deposit_deduction_amount: number
withdraw_deduction_amount: number
available_deduction_amount: number
debt_amount: number
refunded_amount?: number
@@ -259,6 +260,7 @@ export function mapWorkerAfterSalesCase(afterSalesCase: {
resolutionNote: String(afterSalesCase.resolution_note || ''),
recoveryAmount: Number(afterSalesCase.recovery_amount || 0),
pendingDepositDeductionAmount: Number(afterSalesCase.pending_deposit_deduction_amount || 0),
withdrawDeductionAmount: Number(afterSalesCase.withdraw_deduction_amount || 0),
availableDeductionAmount: Number(afterSalesCase.available_deduction_amount || 0),
debtAmount: Number(afterSalesCase.debt_amount || 0),
refundedAmount: Number(afterSalesCase.refunded_amount || 0),
@@ -80,6 +80,7 @@ export function normalizeWalletLedgerType(value: unknown) {
'reward_settlement',
'sharing_reward',
'after_sales_deposit_deduction',
'after_sales_withdraw_deduction',
'after_sales_balance_deduction',
'after_sales_debt_offset',
'after_sales_refund',
@@ -623,10 +623,12 @@ test('售后追缴优先扣减待解冻押金', () => {
resolveAfterSalesRecoveryAllocation({
recoveryAmount: 10_000,
pendingDepositAmount: 12_000,
frozenWithdrawAmount: 0,
availableAmount: 8_000,
}),
{
pendingDepositDeductionAmount: 10_000,
withdrawDeductionAmount: 0,
availableDeductionAmount: 0,
debtAmount: 0,
},
@@ -638,10 +640,12 @@ test('售后追缴在押金不足时继续扣减可用余额', () => {
resolveAfterSalesRecoveryAllocation({
recoveryAmount: 10_000,
pendingDepositAmount: 3_000,
frozenWithdrawAmount: 0,
availableAmount: 8_000,
}),
{
pendingDepositDeductionAmount: 3_000,
withdrawDeductionAmount: 0,
availableDeductionAmount: 7_000,
debtAmount: 0,
},
@@ -653,16 +657,35 @@ test('售后追缴在余额不足时形成欠款', () => {
resolveAfterSalesRecoveryAllocation({
recoveryAmount: 10_000,
pendingDepositAmount: 3_000,
frozenWithdrawAmount: 0,
availableAmount: 2_000,
}),
{
pendingDepositDeductionAmount: 3_000,
withdrawDeductionAmount: 0,
availableDeductionAmount: 2_000,
debtAmount: 5_000,
},
)
})
test('售后追缴先扣待解冻押金、再扣提现冻结、最后扣可用余额', () => {
assert.deepEqual(
resolveAfterSalesRecoveryAllocation({
recoveryAmount: 10_000,
pendingDepositAmount: 3_000,
frozenWithdrawAmount: 5_000,
availableAmount: 8_000,
}),
{
pendingDepositDeductionAmount: 3_000,
withdrawDeductionAmount: 5_000,
availableDeductionAmount: 2_000,
debtAmount: 0,
},
)
})
function buildOrderItemRow(): OrderItemRow {
return {
id: 1,