修复押金与待解冻资金处理
This commit is contained in:
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user