新增验收报酬待解冻配置并修复待解冻结算漏入队与重复释放流水

This commit is contained in:
yml2213
2026-08-22 13:38:17 +08:00
parent 7b2a5321b9
commit 7f6a291628
17 changed files with 173 additions and 115 deletions
@@ -18,6 +18,7 @@ import type { WorkOrderRow, WorkOrderShareRow } from './types.js'
export async function acceptWorkOrderAndSettle(input: {
workOrderId: number
unfreezeDays: number
rewardUnfreezeEnabled: boolean
now: string
/** 操作人类型:admin / worker / system */
actorType?: string
@@ -94,11 +95,13 @@ export async function acceptWorkOrderAndSettle(input: {
now: input.now,
})
const debtOffsetAmount = debtOffsets.reduce((total, item) => total + item.amount, 0)
const shouldDelayUnfreeze = input.unfreezeDays > 0
const shouldDelayUnfreeze = input.rewardUnfreezeEnabled && input.unfreezeDays > 0
const pendingUnfreezeAmount =
(shouldDelayUnfreeze ? shareReward : 0) + (input.unfreezeDays > 0 ? releaseAmount : 0)
const nextAvailable =
Number(wallet?.available_amount || 0) +
shareReward +
(shouldDelayUnfreeze ? 0 : releaseAmount) -
(shouldDelayUnfreeze ? 0 : shareReward) +
(input.unfreezeDays > 0 ? 0 : releaseAmount) -
debtOffsetAmount
const nextFrozen = Math.max(0, Number(wallet?.frozen_deposit_amount || 0) - releaseAmount)
@@ -113,86 +116,87 @@ export async function acceptWorkOrderAndSettle(input: {
updated_at = $5
WHERE worker_id = $6
`,
[
nextAvailable,
nextFrozen,
shouldDelayUnfreeze ? releaseAmount : 0,
shareReward,
input.now,
shareWorkerId,
],
[nextAvailable, nextFrozen, pendingUnfreezeAmount, shareReward, input.now, shareWorkerId],
)
if (releaseAmount > 0) {
if (shouldDelayUnfreeze) {
await enqueueDepositUnfreezeWithClient(client, {
workerId: shareWorkerId,
workOrderId: input.workOrderId,
amount: releaseAmount,
unfreezeDays: input.unfreezeDays,
now: input.now,
})
await client.query(
`
if (pendingUnfreezeAmount > 0) {
await enqueueDepositUnfreezeWithClient(client, {
workerId: shareWorkerId,
workOrderId: input.workOrderId,
amount: pendingUnfreezeAmount,
unfreezeDays: input.unfreezeDays,
now: input.now,
})
}
if (releaseAmount > 0 && input.unfreezeDays > 0) {
await client.query(
`
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_pending_unfreeze', $2, $3, $4, $5, '拼单验收押金待解冻', $6::jsonb, $7)
`,
[
shareWorkerId,
releaseAmount,
nextAvailable,
nextFrozen,
input.workOrderId,
JSON.stringify({
workOrderId: input.workOrderId,
shareId: Number(share.id),
unfreezeDays: input.unfreezeDays,
}),
input.now,
],
)
} else {
await client.query(
`
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_release', $2, $3, $4, $5, '拼单验收释放押金', $6::jsonb, $7)
`,
[
shareWorkerId,
releaseAmount,
nextAvailable,
nextFrozen,
input.workOrderId,
JSON.stringify({ workOrderId: input.workOrderId, shareId: Number(share.id) }),
input.now,
],
)
}
[
shareWorkerId,
releaseAmount,
nextAvailable,
nextFrozen,
input.workOrderId,
JSON.stringify({
workOrderId: input.workOrderId,
shareId: Number(share.id),
unfreezeDays: input.unfreezeDays,
}),
input.now,
],
)
}
if (shareReward > 0) {
if (releaseAmount > 0 && input.unfreezeDays === 0) {
await client.query(
`
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, 'sharing_reward', $2, $3, $4, $5, $6, $7::jsonb, $8)
) VALUES ($1, 'deposit_release', $2, $3, $4, $5, '拼单验收释放押金', $6::jsonb, $7)
`,
[
shareWorkerId,
releaseAmount,
nextAvailable,
nextFrozen,
input.workOrderId,
JSON.stringify({ workOrderId: input.workOrderId, shareId: Number(share.id) }),
input.now,
],
)
}
if (shareReward > 0) {
const rewardLedgerType = shouldDelayUnfreeze
? 'deposit_pending_unfreeze'
: 'reward_settlement'
await client.query(
`
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, $2, $3, $4, $5, $6, $7, $8::jsonb, $9)
`,
[
shareWorkerId,
rewardLedgerType,
shareReward,
nextAvailable,
nextFrozen,
input.workOrderId,
`拼单结算报酬 ${share.quantity} 份`,
shouldDelayUnfreeze
? '拼单份额验收报酬待解冻'
: `拼单份额验收结算报酬 ${share.quantity} 份`,
JSON.stringify({
workOrderId: input.workOrderId,
shareId: Number(share.id),
quantity: share.quantity,
...(shouldDelayUnfreeze ? { unfreezeDays: input.unfreezeDays } : {}),
}),
input.now,
],
@@ -250,11 +254,13 @@ export async function acceptWorkOrderAndSettle(input: {
now: input.now,
})
const debtOffsetAmount = debtOffsets.reduce((total, item) => total + item.amount, 0)
const shouldDelayUnfreeze = input.unfreezeDays > 0
const shouldDelayUnfreeze = input.rewardUnfreezeEnabled && input.unfreezeDays > 0
const pendingUnfreezeAmount =
(shouldDelayUnfreeze ? rewardAmount : 0) + (input.unfreezeDays > 0 ? releaseAmount : 0)
const nextAvailable =
Number(wallet?.available_amount || 0) +
rewardAmount +
(shouldDelayUnfreeze ? 0 : releaseAmount) -
(shouldDelayUnfreeze ? 0 : rewardAmount) +
(input.unfreezeDays > 0 ? 0 : releaseAmount) -
debtOffsetAmount
const nextFrozen = Math.max(0, Number(wallet?.frozen_deposit_amount || 0) - releaseAmount)
@@ -269,25 +275,21 @@ export async function acceptWorkOrderAndSettle(input: {
updated_at = $5
WHERE worker_id = $6
`,
[
nextAvailable,
nextFrozen,
shouldDelayUnfreeze ? releaseAmount : 0,
rewardAmount,
input.now,
workerId,
],
[nextAvailable, nextFrozen, pendingUnfreezeAmount, rewardAmount, input.now, workerId],
)
if (pendingUnfreezeAmount > 0) {
await enqueueDepositUnfreezeWithClient(client, {
workerId,
workOrderId: input.workOrderId,
amount: pendingUnfreezeAmount,
unfreezeDays: input.unfreezeDays,
now: input.now,
})
}
if (releaseAmount > 0) {
if (shouldDelayUnfreeze) {
await enqueueDepositUnfreezeWithClient(client, {
workerId,
workOrderId: input.workOrderId,
amount: releaseAmount,
unfreezeDays: input.unfreezeDays,
now: input.now,
})
if (input.unfreezeDays > 0) {
await client.query(
`
INSERT INTO worker_wallet_ledgers (
@@ -322,14 +324,31 @@ export async function acceptWorkOrderAndSettle(input: {
}
if (rewardAmount > 0) {
const rewardLedgerType = shouldDelayUnfreeze
? 'deposit_pending_unfreeze'
: 'reward_settlement'
await client.query(
`
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, 'reward_settlement', $2, $3, $4, $5, '验收通过结算报酬', '{}'::jsonb, $6)
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9)
`,
[workerId, rewardAmount, nextAvailable, nextFrozen, input.workOrderId, input.now],
[
workerId,
rewardLedgerType,
rewardAmount,
nextAvailable,
nextFrozen,
input.workOrderId,
shouldDelayUnfreeze ? '验收通过报酬待解冻' : '验收通过结算报酬',
JSON.stringify(
shouldDelayUnfreeze
? { workOrderId: input.workOrderId, unfreezeDays: input.unfreezeDays }
: {},
),
input.now,
],
)
}
for (const debtOffset of debtOffsets) {
@@ -383,6 +402,7 @@ export async function acceptWorkOrderShareAndSettle(input: {
workOrderId: number
shareId: number
unfreezeDays: number
rewardUnfreezeEnabled: boolean
now: string
actorType?: string
actorName?: string
@@ -428,11 +448,13 @@ export async function acceptWorkOrderShareAndSettle(input: {
now: input.now,
})
const debtOffsetAmount = debtOffsets.reduce((total, item) => total + item.amount, 0)
const shouldDelayUnfreeze = input.unfreezeDays > 0
const shouldDelayUnfreeze = input.rewardUnfreezeEnabled && input.unfreezeDays > 0
const pendingUnfreezeAmount =
(shouldDelayUnfreeze ? shareReward : 0) + (input.unfreezeDays > 0 ? releaseAmount : 0)
const nextAvailable =
Number(wallet?.available_amount || 0) +
shareReward +
(shouldDelayUnfreeze ? 0 : releaseAmount) -
(shouldDelayUnfreeze ? 0 : shareReward) +
(input.unfreezeDays > 0 ? 0 : releaseAmount) -
debtOffsetAmount
const nextFrozen = Math.max(0, Number(wallet?.frozen_deposit_amount || 0) - releaseAmount)
await client.query(
@@ -441,21 +463,14 @@ export async function acceptWorkOrderShareAndSettle(input: {
pending_unfreeze_amount = pending_unfreeze_amount + $3,
total_settled_amount = total_settled_amount + $4, updated_at = $5
WHERE worker_id = $6`,
[
nextAvailable,
nextFrozen,
shouldDelayUnfreeze ? releaseAmount : 0,
shareReward,
input.now,
workerId,
],
[nextAvailable, nextFrozen, pendingUnfreezeAmount, shareReward, input.now, workerId],
)
if (releaseAmount > 0 && shouldDelayUnfreeze) {
if (pendingUnfreezeAmount > 0) {
await enqueueDepositUnfreezeWithClient(client, {
workerId,
workOrderId: input.workOrderId,
amount: releaseAmount,
amount: pendingUnfreezeAmount,
unfreezeDays: input.unfreezeDays,
now: input.now,
})
@@ -468,31 +483,43 @@ export async function acceptWorkOrderShareAndSettle(input: {
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9)`,
[
workerId,
shouldDelayUnfreeze ? 'deposit_pending_unfreeze' : 'deposit_release',
input.unfreezeDays > 0 ? 'deposit_pending_unfreeze' : 'deposit_release',
releaseAmount,
nextAvailable,
nextFrozen,
input.workOrderId,
shouldDelayUnfreeze ? '拼单份额验收押金待解冻' : '拼单份额验收释放押金',
input.unfreezeDays > 0 ? '拼单份额验收押金待解冻' : '拼单份额验收释放押金',
JSON.stringify({ workOrderId: input.workOrderId, shareId: input.shareId }),
input.now,
],
)
}
if (shareReward > 0) {
const rewardLedgerType = shouldDelayUnfreeze ? 'deposit_pending_unfreeze' : 'sharing_reward'
await client.query(
`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, 'sharing_reward', $2, $3, $4, $5, $6, $7::jsonb, $8)`,
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9)`,
[
workerId,
rewardLedgerType,
shareReward,
nextAvailable,
nextFrozen,
input.workOrderId,
`拼单份额验收结算报酬 ${share.quantity} 份`,
JSON.stringify({ workOrderId: input.workOrderId, shareId: input.shareId }),
shouldDelayUnfreeze
? '拼单份额验收报酬待解冻'
: `拼单份额验收结算报酬 ${share.quantity} 份`,
JSON.stringify(
shouldDelayUnfreeze
? {
workOrderId: input.workOrderId,
shareId: input.shareId,
unfreezeDays: input.unfreezeDays,
}
: { workOrderId: input.workOrderId, shareId: input.shareId },
),
input.now,
],
)
@@ -483,9 +483,7 @@ function buildWorkerFinanceRequestWhere({
if (createdFrom) {
params.push(createdFrom)
// 纯日期字符串 cast 后即当天 00:00:00;带时间则精确到秒
filters.push(
`wfr.created_at >= ($${params.length}::timestamp) AT TIME ZONE 'Asia/Shanghai'`,
)
filters.push(`wfr.created_at >= ($${params.length}::timestamp) AT TIME ZONE 'Asia/Shanghai'`)
}
if (createdTo) {
params.push(createdTo)