From cee759b90eabd0965bdbdecb866953b3fcd2200f Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sat, 22 Aug 2026 11:53:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=8E=E5=8F=B0=E5=94=AE?= =?UTF-8?q?=E5=90=8E=E9=97=AE=E9=A2=98=E5=8D=95=E5=9B=BA=E5=8C=96=E9=AA=8C?= =?UTF-8?q?=E6=94=B6=E5=9B=BE=E5=90=8C=E4=B8=80=E5=9B=BE=E7=89=87=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/admin/panels/AfterSalesPanel.tsx | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/apps/frontend/src/pages/admin/panels/AfterSalesPanel.tsx b/apps/frontend/src/pages/admin/panels/AfterSalesPanel.tsx index 13486555..492fb3a5 100644 --- a/apps/frontend/src/pages/admin/panels/AfterSalesPanel.tsx +++ b/apps/frontend/src/pages/admin/panels/AfterSalesPanel.tsx @@ -28,6 +28,7 @@ import { import type { UploadedFile, WorkerAfterSalesCase, WorkOrder } from '@/types/worker-platform' import { ADMIN_DEFAULT_PAGE_SIZE, buildAdminTablePagination } from '@/utils/admin-pagination' import { formatAdminDateTime } from '@/utils/admin-time' +import { uniqueUploadedFiles } from '@/utils/image-identity' import { asRecord, formatMoney } from './shared' type AfterSalesCreateFormValues = { @@ -447,24 +448,28 @@ function getAfterSalesSnapshotFiles(item: WorkerAfterSalesCase): UploadedFile[] const acceptance = asRecord(snapshot.acceptance) const files = Array.isArray(acceptance.files) ? acceptance.files : [] const imageUrls = Array.isArray(acceptance.imageUrls) ? acceptance.imageUrls : [] - return [ - ...files.map((value) => asRecord(value)), - ...imageUrls.map((url) => asRecord({ url: String(url || '') })), - ] - .map((file) => { - const url = String(file.url || '').trim() - if (!url) return null - return { - objectKey: String(file.objectKey || file.object_key || ''), - url, - thumbnailUrl: String(file.thumbnailUrl || file.thumbnail_url || url), - mediumUrl: String(file.mediumUrl || file.medium_url || url), - filename: String(file.filename || '验收图片'), - contentType: String(file.contentType || ''), - size: Number(file.size || 0), - } satisfies UploadedFile - }) - .filter((file): file is UploadedFile => file !== null) + // 验收资料里同一张图会同时存在于 files 与 imageUrls(历史冗余表示), + // 必须按图片身份去重,否则固化验收图会把同一张图重复渲染多次。 + return uniqueUploadedFiles( + [ + ...files.map((value) => asRecord(value)), + ...imageUrls.map((url) => asRecord({ url: String(url || '') })), + ] + .map((file) => { + const url = String(file.url || '').trim() + if (!url) return null + return { + objectKey: String(file.objectKey || file.object_key || ''), + url, + thumbnailUrl: String(file.thumbnailUrl || file.thumbnail_url || url), + mediumUrl: String(file.mediumUrl || file.medium_url || url), + filename: String(file.filename || '验收图片'), + contentType: String(file.contentType || ''), + size: Number(file.size || 0), + } satisfies UploadedFile + }) + .filter((file): file is UploadedFile => file !== null), + ) } export default AfterSalesPanel