fix:打手端/我的订单/验收:验收视频和验收图片至少上传一个就好了,其他逻辑按照上传图片走
This commit is contained in:
@@ -77,6 +77,8 @@ export async function createWorkerAcceptanceAdminNotification(input: {
|
||||
productName: string
|
||||
workerName: string
|
||||
imageCount: number
|
||||
/** 是否提交了验收视频:视频与图片至少一个,通知里要体现,避免显示成“0 张图片”。 */
|
||||
hasVideo?: boolean
|
||||
/** 拼单份额:每份提交各生成一条待办(按 shareId 去重) */
|
||||
shareId?: number | null
|
||||
}) {
|
||||
@@ -97,6 +99,7 @@ export async function createWorkerAcceptanceAdminNotification(input: {
|
||||
`打手:${input.workerName || '-'}`,
|
||||
...(shareId > 0 ? [`份额:#${shareId}`] : []),
|
||||
`验收图片:${input.imageCount} 张`,
|
||||
...(input.hasVideo ? ['验收视频:已上传'] : []),
|
||||
].join(';'),
|
||||
actionPath: `${ADMIN_WORKER_PLATFORM_PATH}?tab=orders`,
|
||||
now: new Date().toISOString(),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { hasAcceptanceEvidence } from '../../domain/work-order-acceptance-evidence.js'
|
||||
import { WORK_ORDER_STATUS } from '../../domain/work-order-status.js'
|
||||
import {
|
||||
isFriendGiftAcceptanceMode,
|
||||
@@ -155,8 +156,10 @@ export async function submitWorkerOrderAcceptance(
|
||||
workOrder.draft_acceptance_json,
|
||||
)
|
||||
const video = resolveAcceptanceVideo(payload, workOrder.draft_acceptance_json)
|
||||
if (imageUrls.length === 0 && !canAutoAcceptWithoutEvidence) {
|
||||
throw createHttpError('请上传验收图片', {
|
||||
// 验收图片与验收视频至少上传一个;有视频时视同有图片,后续口径完全一致。
|
||||
const hasEvidence = hasAcceptanceEvidence({ imageUrls, video })
|
||||
if (!hasEvidence && !canAutoAcceptWithoutEvidence) {
|
||||
throw createHttpError('请上传验收图片或验收视频', {
|
||||
statusCode: 400,
|
||||
errorCode: 'work_order_acceptance_image_required',
|
||||
})
|
||||
@@ -170,9 +173,8 @@ export async function submitWorkerOrderAcceptance(
|
||||
...(canAutoAcceptWithoutEvidence
|
||||
? {
|
||||
reviewMode: 'vip_auto',
|
||||
evidenceStatus: imageUrls.length > 0 ? 'complete' : 'pending',
|
||||
evidenceDueAt:
|
||||
imageUrls.length > 0 ? null : addHours(now, VIP_AUTO_ACCEPT_EVIDENCE_WINDOW_HOURS),
|
||||
evidenceStatus: hasEvidence ? 'complete' : 'pending',
|
||||
evidenceDueAt: hasEvidence ? null : addHours(now, VIP_AUTO_ACCEPT_EVIDENCE_WINDOW_HOURS),
|
||||
}
|
||||
: {}),
|
||||
}
|
||||
@@ -252,6 +254,7 @@ export async function submitWorkerOrderAcceptance(
|
||||
productName: workOrder.product_name,
|
||||
workerName: worker.display_name || worker.username,
|
||||
imageCount: imageUrls.length,
|
||||
hasVideo: Boolean(video),
|
||||
})
|
||||
publishWorkOrderRealtimeChange({
|
||||
workOrderId: Number(workOrder.id),
|
||||
@@ -303,6 +306,7 @@ export async function remindWorkerOrderAcceptance(
|
||||
productName: workOrder.product_name,
|
||||
workerName: worker.display_name || worker.username,
|
||||
imageCount: normalizeStringArray(safeParseJson(workOrder.acceptance_json).imageUrls).length,
|
||||
hasVideo: Boolean(safeParseJson(workOrder.acceptance_json).video),
|
||||
})
|
||||
notification = await getWorkerAcceptanceReminder(Number(workOrder.id))
|
||||
}
|
||||
@@ -396,7 +400,7 @@ export async function supplementWorkerAcceptedOrderEvidence(
|
||||
const payloadVideo = resolveAcceptanceVideoFromPayload(payload)
|
||||
const video = payloadVideo || readAcceptanceVideoLenient(previous)
|
||||
if (!mergedEvidence.changed && !payloadVideo) {
|
||||
throw createHttpError('请上传新的验收图片', {
|
||||
throw createHttpError('请上传新的验收图片或新的验收视频', {
|
||||
statusCode: 400,
|
||||
errorCode: 'work_order_evidence_supplement_image_required',
|
||||
})
|
||||
@@ -485,8 +489,10 @@ async function submitWorkerSharingAcceptance(
|
||||
sharingShare.draft_acceptance_json,
|
||||
)
|
||||
const video = resolveAcceptanceVideo(payload, sharingShare.draft_acceptance_json)
|
||||
if (imageUrls.length === 0 && !canAutoAcceptWithoutEvidence) {
|
||||
throw createHttpError('请上传验收图片', {
|
||||
// 验收图片与验收视频至少上传一个;有视频时视同有图片,后续口径完全一致。
|
||||
const hasEvidence = hasAcceptanceEvidence({ imageUrls, video })
|
||||
if (!hasEvidence && !canAutoAcceptWithoutEvidence) {
|
||||
throw createHttpError('请上传验收图片或验收视频', {
|
||||
statusCode: 400,
|
||||
errorCode: 'work_order_acceptance_image_required',
|
||||
})
|
||||
@@ -500,9 +506,8 @@ async function submitWorkerSharingAcceptance(
|
||||
...(canAutoAcceptWithoutEvidence
|
||||
? {
|
||||
reviewMode: 'vip_auto',
|
||||
evidenceStatus: imageUrls.length > 0 ? 'complete' : 'pending',
|
||||
evidenceDueAt:
|
||||
imageUrls.length > 0 ? null : addHours(now, VIP_AUTO_ACCEPT_EVIDENCE_WINDOW_HOURS),
|
||||
evidenceStatus: hasEvidence ? 'complete' : 'pending',
|
||||
evidenceDueAt: hasEvidence ? null : addHours(now, VIP_AUTO_ACCEPT_EVIDENCE_WINDOW_HOURS),
|
||||
}
|
||||
: {}),
|
||||
}
|
||||
@@ -562,6 +567,7 @@ async function submitWorkerSharingAcceptance(
|
||||
productName: workOrder.product_name,
|
||||
workerName: worker.display_name || worker.username,
|
||||
imageCount: acceptance.imageUrls.length,
|
||||
hasVideo: Boolean(acceptance.video),
|
||||
shareId: Number(sharingShare.id),
|
||||
})
|
||||
await publishWorkOrderParticipantChange(Number(workOrder.id), {
|
||||
@@ -593,7 +599,7 @@ async function supplementWorkerAcceptedSharingEvidence(
|
||||
const payloadVideo = resolveAcceptanceVideoFromPayload(payload)
|
||||
const video = payloadVideo || readAcceptanceVideoLenient(previous)
|
||||
if (!mergedEvidence.changed && !payloadVideo) {
|
||||
throw createHttpError('请上传新的验收图片', {
|
||||
throw createHttpError('请上传新的验收图片或新的验收视频', {
|
||||
statusCode: 400,
|
||||
errorCode: 'work_order_sharing_evidence_supplement_image_required',
|
||||
})
|
||||
@@ -846,15 +852,16 @@ export async function saveWorkerOrderAcceptanceDraft(
|
||||
const worker = await getRequiredWorker(session.workerId)
|
||||
|
||||
if (workOrder.status === WORK_ORDER_STATUS.PENDING_ACCEPTANCE) {
|
||||
if (imageUrls.length === 0) {
|
||||
throw createHttpError('请至少保留一张验收图片', {
|
||||
const previous = safeParseJson(workOrder.acceptance_json)
|
||||
// 已提交后只允许替换视频,不允许删除证据。
|
||||
const video = resolveAcceptanceVideo(payload, previous)
|
||||
// 验收图片与验收视频至少保留一个。
|
||||
if (!hasAcceptanceEvidence({ imageUrls, video })) {
|
||||
throw createHttpError('请至少保留一张验收图片或一段验收视频', {
|
||||
statusCode: 400,
|
||||
errorCode: 'work_order_acceptance_image_required',
|
||||
})
|
||||
}
|
||||
const previous = safeParseJson(workOrder.acceptance_json)
|
||||
// 已提交后只允许替换视频,不允许删除证据。
|
||||
const video = resolveAcceptanceVideo(payload, previous)
|
||||
const acceptance = {
|
||||
note: String(payload.note ?? previous.note ?? '').trim(),
|
||||
files,
|
||||
@@ -944,15 +951,16 @@ async function saveWorkerSharingAcceptanceDraft(
|
||||
const { files, imageUrls } = resolveAcceptanceImages(payload, {})
|
||||
|
||||
if (sharingShare.status === 'submitted') {
|
||||
if (imageUrls.length === 0) {
|
||||
throw createHttpError('请至少保留一张验收图片', {
|
||||
const previous = safeParseJson(sharingShare.acceptance_json)
|
||||
// 已提交后只允许替换视频,不允许删除证据。
|
||||
const video = resolveAcceptanceVideo(payload, previous)
|
||||
// 验收图片与验收视频至少保留一个。
|
||||
if (!hasAcceptanceEvidence({ imageUrls, video })) {
|
||||
throw createHttpError('请至少保留一张验收图片或一段验收视频', {
|
||||
statusCode: 400,
|
||||
errorCode: 'work_order_acceptance_image_required',
|
||||
})
|
||||
}
|
||||
const previous = safeParseJson(sharingShare.acceptance_json)
|
||||
// 已提交后只允许替换视频,不允许删除证据。
|
||||
const video = resolveAcceptanceVideo(payload, previous)
|
||||
const acceptance = {
|
||||
note: String(payload.note ?? previous.note ?? '').trim(),
|
||||
files,
|
||||
|
||||
@@ -267,17 +267,18 @@ export function WorkerOrderModals({
|
||||
<Form.Item
|
||||
label="验收图片"
|
||||
required={
|
||||
!editingOrder ||
|
||||
canSupplementAcceptedEvidence(editingOrder) ||
|
||||
!canAutoAcceptOrder(editingOrder, workerCanAutoAcceptWithoutEvidence)
|
||||
!acceptanceVideo &&
|
||||
(!editingOrder ||
|
||||
canSupplementAcceptedEvidence(editingOrder) ||
|
||||
!canAutoAcceptOrder(editingOrder, workerCanAutoAcceptWithoutEvidence))
|
||||
}
|
||||
extra={
|
||||
editingOrder && canSupplementAcceptedEvidence(editingOrder)
|
||||
? '仅可追加新图片,原有验收图片会保留。'
|
||||
: editingOrder &&
|
||||
canAutoAcceptOrder(editingOrder, workerCanAutoAcceptWithoutEvidence)
|
||||
? 'VIP 免审核可先提交,验收后需在 24 小时内补充图片。'
|
||||
: undefined
|
||||
? 'VIP 免审核可先提交,验收后需在 24 小时内补充图片或视频。'
|
||||
: '验收图片与验收视频至少上传一个,已上传视频时图片可不填。'
|
||||
}
|
||||
>
|
||||
<ImageUpload
|
||||
@@ -290,8 +291,8 @@ export function WorkerOrderModals({
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="验收视频(选填)"
|
||||
extra="选片后会在本机压到 720p 再上传;已提交的验收只能替换视频,不能删除。"
|
||||
label="验收视频"
|
||||
extra="与验收图片至少上传一个;选片后会在本机压到 720p 再上传;已提交的验收只能替换视频,不能删除。"
|
||||
>
|
||||
<VideoUpload value={acceptanceVideo} onChange={onAcceptanceVideoChange} />
|
||||
</Form.Item>
|
||||
|
||||
@@ -518,8 +518,10 @@ export default function WorkerOrdersPage() {
|
||||
}
|
||||
|
||||
const canAutoAccept = canAutoAcceptOrder(editingOrder, workerCanAutoAcceptWithoutEvidence)
|
||||
if (acceptanceFiles.length === 0 && !canAutoAccept) {
|
||||
message.error('请上传验收图片')
|
||||
// 验收图片与验收视频至少上传一个;有视频时视同有图片,后续口径完全一致。
|
||||
const hasEvidence = acceptanceFiles.length > 0 || Boolean(acceptanceVideo)
|
||||
if (!hasEvidence && !canAutoAccept) {
|
||||
message.error('请上传验收图片或验收视频')
|
||||
return
|
||||
}
|
||||
try {
|
||||
@@ -529,7 +531,14 @@ export default function WorkerOrdersPage() {
|
||||
video: acceptanceVideo,
|
||||
...(editingShareId ? { shareId: editingShareId } : {}),
|
||||
})
|
||||
message.success(canAutoAccept ? '已自动验收,可在 24 小时内补充图片' : '已提交验收')
|
||||
// 已有图片或视频时证据即算齐备,不再提示补图。
|
||||
message.success(
|
||||
canAutoAccept
|
||||
? hasEvidence
|
||||
? '已自动验收'
|
||||
: '已自动验收,可在 24 小时内补充图片或视频'
|
||||
: '已提交验收',
|
||||
)
|
||||
setEditingOrder(null)
|
||||
setAcceptanceFiles([])
|
||||
setAcceptanceVideo(null)
|
||||
@@ -543,8 +552,8 @@ export default function WorkerOrdersPage() {
|
||||
|
||||
async function saveAcceptanceImages(values: AcceptanceFormValues) {
|
||||
if (!editingOrder) return
|
||||
if (hasSubmittedAcceptance(editingOrder) && acceptanceFiles.length === 0) {
|
||||
message.error('请至少保留一张验收图片')
|
||||
if (hasSubmittedAcceptance(editingOrder) && acceptanceFiles.length === 0 && !acceptanceVideo) {
|
||||
message.error('请至少保留一张验收图片或一段验收视频')
|
||||
return
|
||||
}
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user