From 6ebf03d3510d7b99d952c747b822e47006e95f53 Mon Sep 17 00:00:00 2001 From: ntnt Date: Sat, 14 Mar 2026 21:57:07 +0800 Subject: [PATCH] fix: uploads --- frontend/src/pages/workspace/Workspace.tsx | 200 ++++++++++++--------- 1 file changed, 111 insertions(+), 89 deletions(-) diff --git a/frontend/src/pages/workspace/Workspace.tsx b/frontend/src/pages/workspace/Workspace.tsx index bc3a33e..3467bea 100644 --- a/frontend/src/pages/workspace/Workspace.tsx +++ b/frontend/src/pages/workspace/Workspace.tsx @@ -20,6 +20,8 @@ import { } from 'antd'; import { CloudUploadOutlined, + CameraOutlined, + PictureOutlined, ScanOutlined, MergeCellsOutlined, ApartmentOutlined, @@ -182,6 +184,95 @@ const Workspace: React.FC = () => { }, ]; + const handleBeforeUpload = (file: File) => { + if (!batchActiveRef.current) { + batchActiveRef.current = true; + batchCounterRef.current = { success: 0, failed: 0 }; + setUploadBatchItems((prev) => { + prev.forEach((item) => { + if (item.previewUrl) URL.revokeObjectURL(item.previewUrl); + }); + return []; + }); + } + + const localId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; + const previewUrl = URL.createObjectURL(file); + setUploadingCount((c) => { + const next = c + 1; + message.open({ + key: 'img-upload', + type: 'loading', + content: `正在上传截图(队列中 ${next} 张):${file.name}`, + duration: 0, + }); + return next; + }); + setUploadBatchItems((prev) => [ + ...prev, + { + localId, + fileName: file.name, + fileSize: file.size, + status: 'uploading', + previewUrl, + }, + ]); + uploadImages(id, [file]) + .then((uploaded) => { + const uploadedImage = uploaded?.[0]; + setUploadBatchItems((prev) => + prev.map((item) => + item.localId === localId + ? { + ...item, + status: 'success', + uploadedImageId: uploadedImage?.id, + } + : item, + ), + ); + batchCounterRef.current.success += 1; + }) + .then(() => { + queryClient.invalidateQueries({ queryKey: ['images', id] }); + queryClient.invalidateQueries({ queryKey: ['case', id] }); + }) + .catch(() => { + setUploadBatchItems((prev) => + prev.map((item) => + item.localId === localId + ? { ...item, status: 'error' } + : item, + ), + ); + batchCounterRef.current.failed += 1; + }) + .finally(() => { + setUploadingCount((c) => { + const next = Math.max(0, c - 1); + if (next === 0) { + batchActiveRef.current = false; + message.destroy('img-upload'); + const summary = { + success: batchCounterRef.current.success, + failed: batchCounterRef.current.failed, + }; + message.success(`本次上传完成:成功 ${summary.success} 张,失败 ${summary.failed} 张`); + } else { + message.open({ + key: 'img-upload', + type: 'loading', + content: `正在上传截图(队列中 ${next} 张)...`, + duration: 0, + }); + } + return next; + }); + }); + return false; + }; + return (
@@ -225,102 +316,33 @@ const Workspace: React.FC = () => { style={{ marginBottom: 24 }} extra={ - 支持 JPG/PNG,可批量拖拽 + 支持手机拍照/相册上传,或桌面端批量拖拽 } > + + handleBeforeUpload(file as File)} + > + + + handleBeforeUpload(file as File)} + > + + + { - if (!batchActiveRef.current) { - batchActiveRef.current = true; - batchCounterRef.current = { success: 0, failed: 0 }; - setUploadBatchItems((prev) => { - prev.forEach((item) => { - if (item.previewUrl) URL.revokeObjectURL(item.previewUrl); - }); - return []; - }); - } - - const localId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; - const previewUrl = URL.createObjectURL(file as File); - setUploadingCount((c) => { - const next = c + 1; - message.open({ - key: 'img-upload', - type: 'loading', - content: `正在上传截图(队列中 ${next} 张):${file.name}`, - duration: 0, - }); - return next; - }); - setUploadBatchItems((prev) => [ - ...prev, - { - localId, - fileName: file.name, - fileSize: file.size, - status: 'uploading', - previewUrl, - }, - ]); - uploadImages(id, [file as File]) - .then((uploaded) => { - const uploadedImage = uploaded?.[0]; - setUploadBatchItems((prev) => - prev.map((item) => - item.localId === localId - ? { - ...item, - status: 'success', - uploadedImageId: uploadedImage?.id, - } - : item, - ), - ); - batchCounterRef.current.success += 1; - }) - .then(() => { - queryClient.invalidateQueries({ queryKey: ['images', id] }); - queryClient.invalidateQueries({ queryKey: ['case', id] }); - }) - .catch(() => { - setUploadBatchItems((prev) => - prev.map((item) => - item.localId === localId - ? { ...item, status: 'error' } - : item, - ), - ); - batchCounterRef.current.failed += 1; - }) - .finally(() => { - setUploadingCount((c) => { - const next = Math.max(0, c - 1); - if (next === 0) { - batchActiveRef.current = false; - message.destroy('img-upload'); - const summary = { - success: batchCounterRef.current.success, - failed: batchCounterRef.current.failed, - }; - message.success(`本次上传完成:成功 ${summary.success} 张,失败 ${summary.failed} 张`); - } else { - message.open({ - key: 'img-upload', - type: 'loading', - content: `正在上传截图(队列中 ${next} 张)...`, - duration: 0, - }); - } - return next; - }); - }); - return false; - }} + beforeUpload={(file) => handleBeforeUpload(file as File)} style={{ padding: '20px 0' }} >