From 676ef251063c396e7101569cb1582a4d87cb5709 Mon Sep 17 00:00:00 2001 From: admin <572701190@qq.com> Date: Sat, 2 May 2026 23:34:33 +0800 Subject: [PATCH] add DICOM slice previews to image library --- WebSite/src/App.tsx | 94 ++++++++++++++++++++++++++++++++++----------- web_backend.py | 59 ++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 22 deletions(-) diff --git a/WebSite/src/App.tsx b/WebSite/src/App.tsx index 4364098..17a06f7 100644 --- a/WebSite/src/App.tsx +++ b/WebSite/src/App.tsx @@ -70,6 +70,77 @@ const API_BASE = typeof window === 'undefined' ? 'http://127.0.0.1:8787' : `${window.location.protocol}//${window.location.hostname}:8787`; +function LibraryDicomPreview({ item }: { item: LibraryItem }) { + const [sliceIndex, setSliceIndex] = useState(Math.max(0, Math.floor((item.fileCount || 1) / 2))); + const [previewImage, setPreviewImage] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(''); + const count = Math.max(1, item.fileCount || 1); + + useEffect(() => { + setSliceIndex(Math.max(0, Math.floor((item.fileCount || 1) / 2))); + }, [item.id, item.fileCount]); + + useEffect(() => { + const controller = new AbortController(); + setIsLoading(true); + setError(''); + fetch(`${API_BASE}/api/library/preview?id=${encodeURIComponent(item.id)}&index=${sliceIndex}`, { + signal: controller.signal + }) + .then(async response => { + const data = await response.json(); + if (!response.ok) throw new Error(data.error || '预览生成失败'); + setPreviewImage(data.image); + }) + .catch(error => { + if ((error as Error).name !== 'AbortError') setError((error as Error).message); + }) + .finally(() => { + if (!controller.signal.aborted) setIsLoading(false); + }); + return () => controller.abort(); + }, [item.id, sliceIndex]); + + return ( +
{error || (isLoading ? '正在生成预览...' : '等待预览')}
+