修复押金与待解冻资金处理

This commit is contained in:
yml2213
2026-08-28 22:22:26 +08:00
parent f20ff3018f
commit 04dc363320
16 changed files with 97 additions and 23 deletions
@@ -0,0 +1,9 @@
-- 066_worker_unfreeze_fund_type.sql —— 区分待解冻押金与待解冻报酬,防止后台扣押金误扣报酬。
ALTER TABLE worker_deposit_unfreezes
ADD COLUMN IF NOT EXISTS fund_type TEXT NOT NULL DEFAULT 'legacy_combined';
CREATE INDEX IF NOT EXISTS idx_worker_deposit_unfreezes_order_fund_status
ON worker_deposit_unfreezes(work_order_id, fund_type, status);
COMMENT ON COLUMN worker_deposit_unfreezes.fund_type IS '待解冻资金类型:deposit 押金 / reward 报酬 / legacy_combined 历史合并记录';
@@ -120,6 +120,7 @@ export type WorkerDepositUnfreezeRow = {
worker_id: number
work_order_id: number
amount: number
fund_type: 'deposit' | 'reward' | 'legacy_combined' | string
unfreeze_at: string
status: string
released_at: string | null
@@ -1,7 +1,7 @@
import { query } from '../../db/client.js'
import type { WorkerDepositUnfreezeRow } from './types.js'
/** 汇总仍在等待解冻的押金,供订单详情和实时通知展示。 */
/** 汇总仍在等待解冻的押金,供后台订单扣押金操作展示。 */
export async function sumPendingUnfreezeByOrderIds(
workOrderIds: number[],
): Promise<Map<number, number>> {
@@ -14,6 +14,7 @@ export async function sumPendingUnfreezeByOrderIds(
FROM worker_deposit_unfreezes
WHERE work_order_id = ANY($1::bigint[])
AND status = 'pending'
AND fund_type = 'deposit'
GROUP BY work_order_id
`,
[uniqueIds],
@@ -50,6 +50,7 @@ export async function enqueueDepositUnfreezeWithClient(
workerId: number
workOrderId: number
amount: number
fundType: 'deposit' | 'reward'
unfreezeDays: number
now: string
},
@@ -61,10 +62,10 @@ export async function enqueueDepositUnfreezeWithClient(
await client.query(
`
INSERT INTO worker_deposit_unfreezes (
worker_id, work_order_id, amount, unfreeze_at, status, created_at, updated_at
) VALUES ($1, $2, $3, $4, 'pending', $5, $5)
worker_id, work_order_id, amount, fund_type, unfreeze_at, status, created_at, updated_at
) VALUES ($1, $2, $3, $4, $5, 'pending', $6, $6)
`,
[input.workerId, input.workOrderId, input.amount, unfreezeAt, input.now],
[input.workerId, input.workOrderId, input.amount, input.fundType, unfreezeAt, input.now],
)
}
@@ -82,7 +83,7 @@ export async function deductPendingDepositUnfreeze(input: {
`
SELECT *
FROM worker_deposit_unfreezes
WHERE work_order_id = $1 AND status = 'pending'
WHERE work_order_id = $1 AND status = 'pending' AND fund_type = 'deposit'
ORDER BY unfreeze_at ASC
FOR UPDATE
`,
@@ -217,15 +218,17 @@ export async function releaseDepositUnfreeze({
INSERT INTO worker_wallet_ledgers (
worker_id, ledger_type, amount, balance_after, frozen_after,
related_work_order_id, note, payload_json, created_at
) VALUES ($1, 'deposit_unfreeze', $2, $3, $4, $5, '押金已解冻到账', $6::jsonb, $7)
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9)
`,
[
unfreeze.worker_id,
unfreeze.fund_type === 'reward' ? 'reward_unfreeze' : 'deposit_unfreeze',
amount,
nextAvailable,
Number(wallet?.frozen_deposit_amount || 0),
unfreeze.work_order_id,
JSON.stringify({ unfreezeId: unfreeze.id }),
unfreeze.fund_type === 'reward' ? '报酬已解冻到账' : '押金已解冻到账',
JSON.stringify({ unfreezeId: unfreeze.id, fundType: unfreeze.fund_type }),
now,
],
)
@@ -120,11 +120,22 @@ export async function acceptWorkOrderAndSettle(input: {
[nextAvailable, nextFrozen, pendingUnfreezeAmount, shareReward, input.now, shareWorkerId],
)
if (pendingUnfreezeAmount > 0) {
if (releaseAmount > 0 && input.unfreezeDays > 0) {
await enqueueDepositUnfreezeWithClient(client, {
workerId: shareWorkerId,
workOrderId: input.workOrderId,
amount: pendingUnfreezeAmount,
amount: releaseAmount,
fundType: 'deposit',
unfreezeDays: input.unfreezeDays,
now: input.now,
})
}
if (shareReward > 0 && shouldDelayUnfreeze) {
await enqueueDepositUnfreezeWithClient(client, {
workerId: shareWorkerId,
workOrderId: input.workOrderId,
amount: shareReward,
fundType: 'reward',
unfreezeDays: input.unfreezeDays,
now: input.now,
})
@@ -174,7 +185,7 @@ export async function acceptWorkOrderAndSettle(input: {
if (shareReward > 0) {
const rewardLedgerType = shouldDelayUnfreeze
? 'deposit_pending_unfreeze'
? 'reward_pending_unfreeze'
: 'reward_settlement'
await client.query(
`
@@ -279,11 +290,22 @@ export async function acceptWorkOrderAndSettle(input: {
[nextAvailable, nextFrozen, pendingUnfreezeAmount, rewardAmount, input.now, workerId],
)
if (pendingUnfreezeAmount > 0) {
if (releaseAmount > 0 && input.unfreezeDays > 0) {
await enqueueDepositUnfreezeWithClient(client, {
workerId,
workOrderId: input.workOrderId,
amount: pendingUnfreezeAmount,
amount: releaseAmount,
fundType: 'deposit',
unfreezeDays: input.unfreezeDays,
now: input.now,
})
}
if (rewardAmount > 0 && shouldDelayUnfreeze) {
await enqueueDepositUnfreezeWithClient(client, {
workerId,
workOrderId: input.workOrderId,
amount: rewardAmount,
fundType: 'reward',
unfreezeDays: input.unfreezeDays,
now: input.now,
})
@@ -326,7 +348,7 @@ export async function acceptWorkOrderAndSettle(input: {
if (rewardAmount > 0) {
const rewardLedgerType = shouldDelayUnfreeze
? 'deposit_pending_unfreeze'
? 'reward_pending_unfreeze'
: 'reward_settlement'
await client.query(
`
@@ -467,11 +489,22 @@ export async function acceptWorkOrderShareAndSettle(input: {
[nextAvailable, nextFrozen, pendingUnfreezeAmount, shareReward, input.now, workerId],
)
if (pendingUnfreezeAmount > 0) {
if (releaseAmount > 0 && input.unfreezeDays > 0) {
await enqueueDepositUnfreezeWithClient(client, {
workerId,
workOrderId: input.workOrderId,
amount: pendingUnfreezeAmount,
amount: releaseAmount,
fundType: 'deposit',
unfreezeDays: input.unfreezeDays,
now: input.now,
})
}
if (shareReward > 0 && shouldDelayUnfreeze) {
await enqueueDepositUnfreezeWithClient(client, {
workerId,
workOrderId: input.workOrderId,
amount: shareReward,
fundType: 'reward',
unfreezeDays: input.unfreezeDays,
now: input.now,
})
@@ -496,7 +529,7 @@ export async function acceptWorkOrderShareAndSettle(input: {
)
}
if (shareReward > 0) {
const rewardLedgerType = shouldDelayUnfreeze ? 'deposit_pending_unfreeze' : 'sharing_reward'
const rewardLedgerType = shouldDelayUnfreeze ? 'reward_pending_unfreeze' : 'sharing_reward'
await client.query(
`INSERT INTO worker_wallet_ledgers (
worker_id, ledger_type, amount, balance_after, frozen_after,
@@ -291,7 +291,7 @@ export async function joinWorkOrderShare(input: {
`,
[
input.workerId,
depositToFreeze,
-depositToFreeze,
nextAvailable,
nextFrozen,
input.workOrderId,
@@ -72,6 +72,7 @@ function mapDepositUnfreeze(row: WorkerDepositUnfreezeRow) {
workerId: Number(row.worker_id),
workOrderId: Number(row.work_order_id),
amount: Number(row.amount || 0),
fundType: row.fund_type || 'legacy_combined',
status: row.status,
unfreezeAt: row.unfreeze_at,
releasedAt: row.released_at || null,
@@ -74,6 +74,7 @@ export function normalizeWalletLedgerType(value: unknown) {
'deposit_freeze',
'deposit_release',
'deposit_pending_unfreeze',
'reward_pending_unfreeze',
'deposit_unfreeze',
'deposit_deduction',
'reward_settlement',