feat(order-service): 优化客户订单状态与验收展示
This commit is contained in:
@@ -4,6 +4,7 @@ import test from 'node:test'
|
||||
import { WORK_ORDER_STATUS } from '../../domain/work-order-status.js'
|
||||
import {
|
||||
resolveOrderServiceAcceptanceImageUrls,
|
||||
resolveOrderServiceAcceptanceVideo,
|
||||
resolveOrderServiceStatusLabel,
|
||||
resolveOrderServiceStatusMessage,
|
||||
} from './order-service-public-service.js'
|
||||
@@ -42,6 +43,43 @@ test('客户页验收图片:仅交付相关状态展示图片,并按文件
|
||||
)
|
||||
})
|
||||
|
||||
test('客户页验收视频:交付相关状态返回视频地址,未交付状态不返回', () => {
|
||||
const acceptanceJson = {
|
||||
video: {
|
||||
url: '/api/v1/files/object?key=worker-acceptance-video%2Fdemo.webm',
|
||||
thumbnailUrl: '',
|
||||
filename: 'acceptance.webm',
|
||||
contentType: 'video/webm',
|
||||
durationSeconds: 8.8,
|
||||
width: 808,
|
||||
height: 720,
|
||||
objectKey: 'worker-acceptance-video/demo.webm',
|
||||
},
|
||||
}
|
||||
assert.deepEqual(
|
||||
resolveOrderServiceAcceptanceVideo({
|
||||
status: WORK_ORDER_STATUS.ACCEPTED,
|
||||
acceptanceJson,
|
||||
}),
|
||||
{
|
||||
url: '/api/v1/files/object?key=worker-acceptance-video%2Fdemo.webm',
|
||||
thumbnailUrl: '',
|
||||
filename: 'acceptance.webm',
|
||||
contentType: 'video/webm',
|
||||
durationSeconds: 8.8,
|
||||
width: 808,
|
||||
height: 720,
|
||||
},
|
||||
)
|
||||
assert.equal(
|
||||
resolveOrderServiceAcceptanceVideo({
|
||||
status: WORK_ORDER_STATUS.IN_PROGRESS,
|
||||
acceptanceJson,
|
||||
}),
|
||||
null,
|
||||
)
|
||||
})
|
||||
|
||||
test('订单服务状态文案:待抢单提示高峰期等待', () => {
|
||||
const message = resolveOrderServiceStatusMessage({
|
||||
status: WORK_ORDER_STATUS.OPEN,
|
||||
|
||||
@@ -94,6 +94,7 @@ export type OrderServicePublicItem = {
|
||||
screenshotsRule?: OrderServiceProfileConfig['screenshots']
|
||||
guideImage?: Record<string, unknown>
|
||||
acceptanceImageUrls?: string[]
|
||||
acceptanceVideo?: OrderServiceAcceptanceVideo
|
||||
submittedAt?: string
|
||||
acceptanceSubmittedAt?: string
|
||||
acceptedAt?: string
|
||||
@@ -163,6 +164,55 @@ export function resolveOrderServiceAcceptanceImageUrls(input: {
|
||||
return urls
|
||||
}
|
||||
|
||||
export type OrderServiceAcceptanceVideo = {
|
||||
url: string
|
||||
thumbnailUrl: string
|
||||
filename: string
|
||||
contentType: string
|
||||
durationSeconds: number | null
|
||||
width: number | null
|
||||
height: number | null
|
||||
}
|
||||
|
||||
export function resolveOrderServiceAcceptanceVideo(input: {
|
||||
status: string
|
||||
acceptanceJson: unknown
|
||||
}): OrderServiceAcceptanceVideo | null {
|
||||
if (!PUBLIC_ACCEPTANCE_IMAGE_STATUSES.has(String(input.status || '').trim())) return null
|
||||
|
||||
const rawAcceptance = safeParseJson(input.acceptanceJson)
|
||||
const acceptance = mapAcceptanceForResponse(input.acceptanceJson)
|
||||
const candidates = [
|
||||
rawAcceptance.video,
|
||||
...(Array.isArray(acceptance.files) ? acceptance.files : []),
|
||||
]
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) continue
|
||||
const source = candidate as Record<string, unknown>
|
||||
const contentType = String(source.contentType || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
const objectKey = String(
|
||||
source.objectKey || extractObjectKeyFromFileUrl(String(source.url || '')) || '',
|
||||
).trim()
|
||||
const videoLike = contentType.startsWith('video/') || /\.(?:mp4|webm|mov|m4v)$/i.test(objectKey)
|
||||
if (!videoLike) continue
|
||||
const url = refreshStoredFileUrl(String(source.url || '').trim())
|
||||
if (!url) continue
|
||||
return {
|
||||
url,
|
||||
thumbnailUrl: refreshStoredFileUrl(String(source.thumbnailUrl || '').trim()),
|
||||
filename: String(source.filename || '').trim(),
|
||||
contentType,
|
||||
durationSeconds: normalizeFiniteNumber(source.durationSeconds),
|
||||
width: normalizeFiniteNumber(source.width),
|
||||
height: normalizeFiniteNumber(source.height),
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export async function getOrderServiceByPlatformOrderId(platformOrderIdInput: unknown) {
|
||||
const platformOrderId = normalizeOrderNo(platformOrderIdInput)
|
||||
const orders = await listWorkOrdersByPlatformOrderId(platformOrderId)
|
||||
@@ -428,6 +478,10 @@ async function mapPublicOrderItem(order: WorkOrderRow): Promise<OrderServicePubl
|
||||
status: order.status,
|
||||
acceptanceJson: order.acceptance_json,
|
||||
})
|
||||
const acceptanceVideo = resolveOrderServiceAcceptanceVideo({
|
||||
status: order.status,
|
||||
acceptanceJson: order.acceptance_json,
|
||||
})
|
||||
const screenshots = normalizeUploadedFiles(collect.screenshots || [])
|
||||
.map(refreshUploadedFileUrls)
|
||||
.filter(Boolean)
|
||||
@@ -457,21 +511,11 @@ async function mapPublicOrderItem(order: WorkOrderRow): Promise<OrderServicePubl
|
||||
...(acceptanceSubmittedAt ? { acceptanceSubmittedAt } : {}),
|
||||
...(order.accepted_at ? { acceptedAt: String(order.accepted_at) } : {}),
|
||||
...(acceptanceImageUrls.length > 0 ? { acceptanceImageUrls } : {}),
|
||||
...(acceptanceVideo ? { acceptanceVideo } : {}),
|
||||
...(profile?.materialConfirmation
|
||||
? { materialConfirmation: profile.materialConfirmation }
|
||||
: {}),
|
||||
statusSteps:
|
||||
currentPresentationProfile?.config.statusSteps ||
|
||||
profile?.statusSteps ||
|
||||
DEFAULT_ORDER_SERVICE_STATUS_STEPS,
|
||||
}
|
||||
|
||||
if (!state.canSubmit) return base
|
||||
|
||||
const fields = profile?.fields || []
|
||||
return {
|
||||
...base,
|
||||
fields,
|
||||
fields: profile?.fields || [],
|
||||
values,
|
||||
screenshots,
|
||||
screenshotsRule: profile?.screenshots || {
|
||||
@@ -482,6 +526,16 @@ async function mapPublicOrderItem(order: WorkOrderRow): Promise<OrderServicePubl
|
||||
label: '买家主页截图',
|
||||
helpText: '',
|
||||
},
|
||||
statusSteps:
|
||||
currentPresentationProfile?.config.statusSteps ||
|
||||
profile?.statusSteps ||
|
||||
DEFAULT_ORDER_SERVICE_STATUS_STEPS,
|
||||
}
|
||||
|
||||
if (!state.canSubmit) return base
|
||||
|
||||
return {
|
||||
...base,
|
||||
guideImage: profile?.guideImage || {},
|
||||
}
|
||||
}
|
||||
@@ -585,6 +639,11 @@ function normalizeOrderNo(value: unknown) {
|
||||
return normalized
|
||||
}
|
||||
|
||||
function normalizeFiniteNumber(value: unknown): number | null {
|
||||
const parsed = Number(value)
|
||||
return Number.isFinite(parsed) && parsed >= 0 ? parsed : null
|
||||
}
|
||||
|
||||
function notFound() {
|
||||
return createHttpError('订单号无效,请确认订单号是否正确', {
|
||||
statusCode: 404,
|
||||
|
||||
Reference in New Issue
Block a user