优化撤单处理方式

This commit is contained in:
yml2213
2026-08-15 17:41:01 +08:00
parent 57fda860dc
commit b9e4d007aa
5 changed files with 236 additions and 30 deletions
@@ -1295,9 +1295,106 @@ export async function unassignWorkOrder(input: {
})
}
export async function returnAssignedWorkOrderToHall(input: {
workOrderId: number
now: string
reason?: string
}): Promise<{
order: WorkOrderRow | null
failureReason: 'work_order_not_in_progress' | 'work_order_no_worker' | null
}> {
return withTransaction(async (client) => {
const currentResult = await client.query<WorkOrderRow>(
`
SELECT *
FROM work_orders
WHERE id = $1
FOR UPDATE
`,
[input.workOrderId],
)
const workOrder = currentResult.rows[0] || null
if (!workOrder || workOrder.status !== 'in_progress') {
return { order: null, failureReason: 'work_order_not_in_progress' }
}
const workerId = Number(workOrder.assigned_worker_id || 0)
if (!workerId) {
return { order: null, failureReason: 'work_order_no_worker' }
}
await ensureWorkerWalletWithClient(client, workerId, input.now)
const wallet = await getWorkerWalletWithClient(client, workerId)
const releaseAmount = Math.min(
await getOutstandingDepositAmountWithClient(client, workerId, input.workOrderId),
Number(wallet?.frozen_deposit_amount || 0),
)
await client.query(
`
UPDATE work_orders
SET
status = 'open',
assigned_worker_id = NULL,
assigned_at = NULL,
deadline_at = NULL,
published_at = $1,
updated_at = $1
WHERE id = $2
`,
[input.now, input.workOrderId],
)
if (releaseAmount > 0) {
const nextAvailable = Number(wallet?.available_amount || 0) + releaseAmount
const nextFrozen = Math.max(
0,
Number(wallet?.frozen_deposit_amount || 0) - releaseAmount,
)
await client.query(
`
UPDATE worker_wallets
SET available_amount = $1, frozen_deposit_amount = $2, updated_at = $3
WHERE worker_id = $4
`,
[nextAvailable, nextFrozen, input.now, workerId],
)
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, '后台退回大厅退还押金', '{}'::jsonb, $6)
`,
[workerId, releaseAmount, nextAvailable, nextFrozen, input.workOrderId, input.now],
)
}
await createWorkOrderEventWithClient(client, {
workOrderId: input.workOrderId,
actorType: 'admin',
actorId: '',
eventType: 'returned_to_hall_by_admin',
fromStatus: 'in_progress',
toStatus: 'open',
payloadJson: JSON.stringify({
workerId,
releaseAmount,
reason: String(input.reason || '').trim(),
}),
now: input.now,
})
return {
order: await getWorkOrderByIdWithClient(client, input.workOrderId),
failureReason: null,
}
})
}
export async function cancelAssignedWorkOrder(input: {
workOrderId: number
now: string
reason?: string
}): Promise<{
order: WorkOrderRow | null
failureReason: 'work_order_not_in_progress' | 'work_order_no_worker' | null
@@ -1375,7 +1472,11 @@ export async function cancelAssignedWorkOrder(input: {
eventType: 'cancelled_by_admin',
fromStatus: 'in_progress',
toStatus: 'cancelled',
payloadJson: JSON.stringify({ workerId, releaseAmount }),
payloadJson: JSON.stringify({
workerId,
releaseAmount,
reason: String(input.reason || '').trim(),
}),
now: input.now,
})