fix(worker): 验收重复提交幂等,修复卡待验收与手动验收 500
This commit is contained in:
@@ -14,10 +14,10 @@ import {
|
||||
countWorkOrderPendingSharingSubmissions,
|
||||
createWorkOrderEvent,
|
||||
listWorkOrderSharesByWorkerInOrder,
|
||||
markWorkOrderAcceptanceSubmitted,
|
||||
settleOverdueWorkOrder,
|
||||
settleOverdueWorkOrderShare,
|
||||
submitWorkOrderShareAcceptance,
|
||||
updateWorkOrder,
|
||||
updateWorkOrderAcceptanceRecord,
|
||||
updateWorkOrderDraftAcceptance,
|
||||
updateWorkOrderShareAcceptanceRecord,
|
||||
@@ -82,7 +82,7 @@ export async function submitWorkerOrderAcceptance(
|
||||
} = {},
|
||||
) {
|
||||
requireActiveWorkerSession(session)
|
||||
const workOrder = await getRequiredWorkOrder(workOrderId)
|
||||
let workOrder = await getRequiredWorkOrder(workOrderId)
|
||||
const workerId = Number(session.workerId)
|
||||
const worker = await getRequiredWorker(session.workerId)
|
||||
if (!options.asConsignmentSupplier) {
|
||||
@@ -184,28 +184,54 @@ export async function submitWorkerOrderAcceptance(
|
||||
}
|
||||
: {}),
|
||||
}
|
||||
const updated = await updateWorkOrder(workOrder.id, {
|
||||
status: WORK_ORDER_STATUS.PENDING_ACCEPTANCE,
|
||||
acceptance_json: acceptance,
|
||||
draft_acceptance_json: {},
|
||||
submitted_at: now,
|
||||
updated_at: now,
|
||||
})
|
||||
await createWorkOrderEvent({
|
||||
const transitioned = await markWorkOrderAcceptanceSubmitted({
|
||||
workOrderId: workOrder.id,
|
||||
actorType: 'worker',
|
||||
actorId: String(session.workerId),
|
||||
eventType: 'acceptance_submitted',
|
||||
fromStatus: workOrder.status,
|
||||
toStatus: WORK_ORDER_STATUS.PENDING_ACCEPTANCE,
|
||||
payloadJson: JSON.stringify({
|
||||
imageCount: imageUrls.length,
|
||||
hasVideo: Boolean(video),
|
||||
autoAccepted: canAutoAcceptWithoutEvidence,
|
||||
evidenceDueAt: acceptance.evidenceDueAt || null,
|
||||
}),
|
||||
acceptanceJson: acceptance,
|
||||
now,
|
||||
})
|
||||
let updated = transitioned
|
||||
if (transitioned) {
|
||||
await createWorkOrderEvent({
|
||||
workOrderId: workOrder.id,
|
||||
actorType: 'worker',
|
||||
actorId: String(session.workerId),
|
||||
eventType: 'acceptance_submitted',
|
||||
fromStatus: workOrder.status,
|
||||
toStatus: WORK_ORDER_STATUS.PENDING_ACCEPTANCE,
|
||||
payloadJson: JSON.stringify({
|
||||
imageCount: imageUrls.length,
|
||||
hasVideo: Boolean(video),
|
||||
autoAccepted: canAutoAcceptWithoutEvidence,
|
||||
evidenceDueAt: acceptance.evidenceDueAt || null,
|
||||
}),
|
||||
now,
|
||||
})
|
||||
} else {
|
||||
// 重复提交(双击/前端重试):第一个请求可能已经验收或正在结算。
|
||||
// 绝不能把 accepted 再写回待验收,只按当前状态幂等处理。
|
||||
const latest = await getRequiredWorkOrder(workOrder.id).catch(() => null)
|
||||
const ownerMatched =
|
||||
options.asConsignmentSupplier || Number(latest?.assigned_worker_id || 0) === workerId
|
||||
if (
|
||||
!latest ||
|
||||
!ownerMatched ||
|
||||
![WORK_ORDER_STATUS.PENDING_ACCEPTANCE, WORK_ORDER_STATUS.ACCEPTED].includes(
|
||||
latest.status as never,
|
||||
)
|
||||
) {
|
||||
throw createHttpError('当前状态不能提交验收', {
|
||||
statusCode: 409,
|
||||
errorCode: 'work_order_submit_status_invalid',
|
||||
})
|
||||
}
|
||||
if (latest.status === WORK_ORDER_STATUS.ACCEPTED) {
|
||||
publishWorkOrderRealtimeChange({ workOrderId: Number(latest.id), workerIds: [workerId] })
|
||||
return { order: mapWorkOrderForWorker(latest, resolveWorkerPermissions(worker)) }
|
||||
}
|
||||
// 上一请求已推进到待验收但结算未完成:用已有验收资料重试结算,不重复写资料。
|
||||
workOrder = latest
|
||||
updated = latest
|
||||
}
|
||||
// 好友赠送模式必须由后台人工验收赠送凭证,内部打手与 VIP 免审核直通均不适用。
|
||||
if (
|
||||
!isFriendGiftAcceptanceMode(workOrder.acceptance_mode) &&
|
||||
|
||||
Reference in New Issue
Block a user