修复订单发布与核销并发状态覆盖
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { query } from '../../db/client.js'
|
||||
import { query, withTransaction } from '../../db/client.js'
|
||||
import { toJsonString, toPositiveInteger } from './shared.js'
|
||||
import { getWorkOrderById } from './work-order-query-repo.js'
|
||||
import { getWorkOrderById, getWorkOrderByIdWithClient } from './work-order-query-repo.js'
|
||||
import { createWorkOrderEventWithClient } from './work-order-event-repo.js'
|
||||
import {
|
||||
normalizeWorkOrderAcceptanceMode,
|
||||
normalizeWorkOrderGiftCooldownHours,
|
||||
@@ -125,6 +126,64 @@ export async function updateWorkOrder(
|
||||
return getWorkOrderById(workOrderId)
|
||||
}
|
||||
|
||||
/** 将未分配工单原子发布到大厅,并在事务内记录发布事件。 */
|
||||
export async function publishUnassignedWorkOrder(input: {
|
||||
workOrderId: number | string
|
||||
now: string
|
||||
actorName?: string
|
||||
}): Promise<{
|
||||
order: WorkOrderRow | null
|
||||
failureReason: 'work_order_not_publishable' | null
|
||||
}> {
|
||||
return withTransaction(async (client) => {
|
||||
const currentResult = await client.query<WorkOrderRow>(
|
||||
`
|
||||
SELECT *
|
||||
FROM work_orders
|
||||
WHERE id = $1
|
||||
FOR UPDATE
|
||||
`,
|
||||
[Number(input.workOrderId)],
|
||||
)
|
||||
const current = currentResult.rows[0] || null
|
||||
if (!current || current.status !== 'unassigned' || current.assigned_worker_id) {
|
||||
return { order: null, failureReason: 'work_order_not_publishable' }
|
||||
}
|
||||
|
||||
const updatedResult = await client.query<{ id: number }>(
|
||||
`
|
||||
UPDATE work_orders
|
||||
SET status = 'open', published_at = $1, hall_queued_at = $1, updated_at = $1
|
||||
WHERE id = $2
|
||||
AND status = 'unassigned'
|
||||
AND assigned_worker_id IS NULL
|
||||
AND reward_amount > 0
|
||||
RETURNING id
|
||||
`,
|
||||
[input.now, Number(input.workOrderId)],
|
||||
)
|
||||
if (!updatedResult.rows[0]) {
|
||||
return { order: null, failureReason: 'work_order_not_publishable' }
|
||||
}
|
||||
|
||||
await createWorkOrderEventWithClient(client, {
|
||||
workOrderId: Number(input.workOrderId),
|
||||
actorType: 'admin',
|
||||
actorId: input.actorName || '',
|
||||
eventType: 'published',
|
||||
fromStatus: current.status,
|
||||
toStatus: 'open',
|
||||
payloadJson: JSON.stringify({ voucherConsumeDeferred: true }),
|
||||
now: input.now,
|
||||
})
|
||||
|
||||
return {
|
||||
order: await getWorkOrderByIdWithClient(client, input.workOrderId),
|
||||
failureReason: null,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function updateWorkOrderBasic(
|
||||
workOrderId: number | string,
|
||||
patch: {
|
||||
|
||||
Reference in New Issue
Block a user