diff --git a/apps/frontend/src/components/files/ImagePreviewList.tsx b/apps/frontend/src/components/files/ImagePreviewList.tsx index 76638a59..72ccacda 100644 --- a/apps/frontend/src/components/files/ImagePreviewList.tsx +++ b/apps/frontend/src/components/files/ImagePreviewList.tsx @@ -44,10 +44,15 @@ function normalizePreviewItems(files: UploadedFile[], imageUrls: string[]) { mediumUrl: file.mediumUrl || file.url, })) .filter((item) => Boolean(item.url)) - const fileUrlSet = new Set(normalizedFiles.map((item) => item.url)) + const fileUrlSet = new Set(normalizedFiles.map((item) => getImageIdentity(item.url))) const normalizedUrls = imageUrls .map((url) => String(url || '').trim()) - .filter((url) => url && !fileUrlSet.has(url)) + .filter((url) => url && !fileUrlSet.has(getImageIdentity(url))) .map((url) => ({ url, thumbnailUrl: url, mediumUrl: url })) return [...normalizedFiles, ...normalizedUrls] } + +/** 忽略临时签名参数,避免同一存储对象重复显示。 */ +function getImageIdentity(value: string) { + return String(value || '').trim().split(/[?#]/, 1)[0] +} diff --git a/apps/frontend/src/pages/worker/WorkerOrdersPage.tsx b/apps/frontend/src/pages/worker/WorkerOrdersPage.tsx index fc35c2d4..fb45a88d 100644 --- a/apps/frontend/src/pages/worker/WorkerOrdersPage.tsx +++ b/apps/frontend/src/pages/worker/WorkerOrdersPage.tsx @@ -22,6 +22,7 @@ import { Table, Tabs, Tag, + Tooltip, Typography, } from 'antd' import type { TableColumnsType } from 'antd' @@ -167,20 +168,7 @@ export default function WorkerOrdersPage() { const source = hasSubmittedAcceptance(order) ? getWorkerAcceptance(order) : getWorkerDraft(order) - setAcceptanceFiles([ - ...getAcceptanceFilesFromSource(source), - ...(Array.isArray(source.imageUrls) ? source.imageUrls : []).map( - (url): UploadedFile => ({ - objectKey: '', - url: String(url || ''), - thumbnailUrl: String(url || ''), - mediumUrl: String(url || ''), - filename: '图片', - contentType: '', - size: 0, - }), - ), - ]) + setAcceptanceFiles(getUniqueAcceptanceFiles(source)) form.setFieldsValue({ note: String(source.note || '') }) setDetailOrder(null) } @@ -438,27 +426,33 @@ export default function WorkerOrdersPage() { }, { title: '操作', - width: 260, + width: 190, render: (_, row) => ( - - - {canEditAcceptanceImages(row) ? ( - - ) : null} +
+ + + + ) : null} + {canCancelOrder(row) ? ( - ) : null} - +
), }, ] @@ -740,7 +734,7 @@ export default function WorkerOrdersPage() { editingOrder ? hasSubmittedAcceptance(editingOrder) ? '补充验收图片' - : '提交验收' + : '验收图片' : '验收图片' } open={Boolean(editingOrder)} @@ -762,10 +756,7 @@ export default function WorkerOrdersPage() { > 取消 - {canSubmitAcceptance(editingOrder) ? ( @@ -778,15 +769,7 @@ export default function WorkerOrdersPage() { } >
- + ({ + objectKey: '', + url: String(url || ''), + thumbnailUrl: String(url || ''), + mediumUrl: String(url || ''), + filename: '图片', + contentType: '', + size: 0, + }), + ), + ] + const identities = new Set() + return files.filter((file) => { + const identity = getImageIdentity(file.url || file.mediumUrl || file.thumbnailUrl || file.objectKey) + if (!identity || identities.has(identity)) return false + identities.add(identity) + return true + }) +} + +/** 去除临时签名参数,确保同一个对象的不同访问链接能匹配。 */ +function getImageIdentity(value: string): string { + const url = String(value || '').trim() + if (!url) return '' + return url.split(/[?#]/, 1)[0] +} + function getAcceptanceFiles(row: WorkOrder): UploadedFile[] { return getAcceptanceFilesFromSource(getWorkerAcceptance(row)) } diff --git a/apps/frontend/src/styles/main.css b/apps/frontend/src/styles/main.css index 026be470..57140f55 100644 --- a/apps/frontend/src/styles/main.css +++ b/apps/frontend/src/styles/main.css @@ -1519,6 +1519,17 @@ select { gap: 16px; } +.worker-order-actions { + display: grid; + justify-items: start; + gap: 4px; +} + +.worker-order-actions .ant-btn-link { + height: auto; + padding: 0; +} + .worker-order-detail-value { white-space: pre-wrap; overflow-wrap: anywhere;