接单工单新增流转记录(订单详情时间线)
- 后端:新增工单事件查询接口(管理端 + 打手端),事件带操作人显示名(管理员用户名 / 打手昵称 / 系统) - 补齐关键节点事件:抢单接手(grabbed)、验收通过(accepted 带操作人) - 管理端/打手端事件写入操作人(admin session username 贯通至事件) - 前端:订单详情新增「流转记录」时间线,按订单生命周期节点展示(创建/发单/接手/资料/验收/问题/取消),时间+操作人+状态流转
This commit is contained in:
@@ -1056,6 +1056,8 @@ export async function assignWorkOrderToWorker(input: {
|
||||
maxActiveOrders: number
|
||||
deadlineAt: string | null
|
||||
now: string
|
||||
/** 操作人显示名(管理员用户名等) */
|
||||
actorName?: string
|
||||
}): Promise<{
|
||||
order: WorkOrderRow | null
|
||||
failureReason:
|
||||
@@ -1143,7 +1145,7 @@ export async function assignWorkOrderToWorker(input: {
|
||||
await createWorkOrderEventWithClient(client, {
|
||||
workOrderId: input.workOrderId,
|
||||
actorType: 'admin',
|
||||
actorId: '',
|
||||
actorId: input.actorName || '',
|
||||
eventType: 'assigned_by_admin',
|
||||
fromStatus,
|
||||
toStatus: 'in_progress',
|
||||
@@ -1245,7 +1247,11 @@ export async function cancelWorkerWorkOrder(input: {
|
||||
})
|
||||
}
|
||||
|
||||
export async function unassignWorkOrder(input: { workOrderId: number; now: string }): Promise<{
|
||||
export async function unassignWorkOrder(input: {
|
||||
workOrderId: number
|
||||
now: string
|
||||
actorName?: string
|
||||
}): Promise<{
|
||||
order: WorkOrderRow | null
|
||||
failureReason: 'work_order_not_in_progress' | 'work_order_no_worker' | null
|
||||
}> {
|
||||
@@ -1314,7 +1320,7 @@ export async function unassignWorkOrder(input: { workOrderId: number; now: strin
|
||||
await createWorkOrderEventWithClient(client, {
|
||||
workOrderId: input.workOrderId,
|
||||
actorType: 'admin',
|
||||
actorId: '',
|
||||
actorId: input.actorName || '',
|
||||
eventType: 'unassigned_by_admin',
|
||||
fromStatus: 'in_progress',
|
||||
toStatus: 'unassigned',
|
||||
@@ -1333,6 +1339,7 @@ export async function returnAssignedWorkOrderToHall(input: {
|
||||
workOrderId: number
|
||||
now: string
|
||||
reason?: string
|
||||
actorName?: string
|
||||
}): Promise<{
|
||||
order: WorkOrderRow | null
|
||||
failureReason: 'work_order_not_in_progress' | 'work_order_no_worker' | null
|
||||
@@ -1403,7 +1410,7 @@ export async function returnAssignedWorkOrderToHall(input: {
|
||||
await createWorkOrderEventWithClient(client, {
|
||||
workOrderId: input.workOrderId,
|
||||
actorType: 'admin',
|
||||
actorId: '',
|
||||
actorId: input.actorName || '',
|
||||
eventType: 'returned_to_hall_by_admin',
|
||||
fromStatus: 'in_progress',
|
||||
toStatus: 'open',
|
||||
@@ -1426,6 +1433,7 @@ export async function cancelAssignedWorkOrder(input: {
|
||||
workOrderId: number
|
||||
now: string
|
||||
reason?: string
|
||||
actorName?: string
|
||||
}): Promise<{
|
||||
order: WorkOrderRow | null
|
||||
failureReason: 'work_order_not_in_progress' | 'work_order_no_worker' | null
|
||||
@@ -1496,7 +1504,7 @@ export async function cancelAssignedWorkOrder(input: {
|
||||
await createWorkOrderEventWithClient(client, {
|
||||
workOrderId: input.workOrderId,
|
||||
actorType: 'admin',
|
||||
actorId: '',
|
||||
actorId: input.actorName || '',
|
||||
eventType: 'cancelled_by_admin',
|
||||
fromStatus: 'in_progress',
|
||||
toStatus: 'cancelled',
|
||||
@@ -1537,6 +1545,10 @@ export async function acceptWorkOrderAndSettle(input: {
|
||||
workOrderId: number
|
||||
unfreezeDays: number
|
||||
now: string
|
||||
/** 操作人类型:admin / worker / system */
|
||||
actorType?: string
|
||||
/** 操作人显示名 */
|
||||
actorName?: string
|
||||
}): Promise<{
|
||||
order: WorkOrderRow | null
|
||||
failureReason: 'sharing_pending_submissions' | null
|
||||
@@ -1809,8 +1821,8 @@ export async function acceptWorkOrderAndSettle(input: {
|
||||
|
||||
await createWorkOrderEventWithClient(client, {
|
||||
workOrderId: input.workOrderId,
|
||||
actorType: 'admin',
|
||||
actorId: '',
|
||||
actorType: input.actorType || 'admin',
|
||||
actorId: input.actorName || '',
|
||||
eventType: 'accepted',
|
||||
fromStatus: 'pending_acceptance',
|
||||
toStatus: 'accepted',
|
||||
@@ -1834,6 +1846,7 @@ export async function resolveProblemWorkOrder(input: {
|
||||
action: ProblemWorkOrderResolutionAction
|
||||
note: string
|
||||
now: string
|
||||
actorName?: string
|
||||
}): Promise<WorkOrderRow | null> {
|
||||
return withTransaction(async (client) => {
|
||||
const currentResult = await client.query<WorkOrderRow>(
|
||||
@@ -1937,7 +1950,7 @@ export async function resolveProblemWorkOrder(input: {
|
||||
await createWorkOrderEventWithClient(client, {
|
||||
workOrderId: input.workOrderId,
|
||||
actorType: 'admin',
|
||||
actorId: '',
|
||||
actorId: input.actorName || '',
|
||||
eventType: `problem_${input.action}`,
|
||||
fromStatus: 'problem',
|
||||
toStatus: targetStatus,
|
||||
@@ -2409,6 +2422,33 @@ export async function countWorkerTimeoutEvents(workerId: number | string): Promi
|
||||
return counts.get(Number(workerId)) || 0
|
||||
}
|
||||
|
||||
export type WorkOrderEventRow = {
|
||||
id: number
|
||||
work_order_id: number
|
||||
actor_type: string
|
||||
actor_id: string
|
||||
event_type: string
|
||||
from_status: string
|
||||
to_status: string
|
||||
payload_json: string | Record<string, unknown>
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export async function listWorkOrderEventsByOrderId(
|
||||
workOrderId: number | string,
|
||||
): Promise<WorkOrderEventRow[]> {
|
||||
const result = await query<WorkOrderEventRow>(
|
||||
`
|
||||
SELECT *
|
||||
FROM work_order_events
|
||||
WHERE work_order_id = $1
|
||||
ORDER BY id ASC
|
||||
`,
|
||||
[Number(workOrderId)],
|
||||
)
|
||||
return result.rows
|
||||
}
|
||||
|
||||
export async function createWorkOrderEvent(input: {
|
||||
workOrderId: number
|
||||
actorType: string
|
||||
|
||||
Reference in New Issue
Block a user