From d4a43e211aae854cbc59bbeb939c43f1b37cc1e6 Mon Sep 17 00:00:00 2001 From: mozzie Date: Mon, 2 Sep 2024 11:18:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AF=BC=E5=85=A5dicom=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/desktop/electron/ipcMainHandlers.ts | 9 +- apps/desktop/src/pages/Datasource/index.tsx | 94 ++++++++++++++++++--- apps/desktop/src/pages/MenuBar.tsx | 8 +- 3 files changed, 91 insertions(+), 20 deletions(-) diff --git a/apps/desktop/electron/ipcMainHandlers.ts b/apps/desktop/electron/ipcMainHandlers.ts index 9500061..0af9433 100644 --- a/apps/desktop/electron/ipcMainHandlers.ts +++ b/apps/desktop/electron/ipcMainHandlers.ts @@ -47,19 +47,20 @@ const registerIpcMainHandlers = ( running ? pythonManager.startFlask() : pythonManager.stopFlask(); }); - ipcMain.on("scan-dicom", async (event) => { + ipcMain.on("import-dicom-dialog-visible", async (event) => { const result = await dialog.showOpenDialog({ properties: ["openDirectory"], }); if (result.canceled) return null; const filePaths = result.filePaths[0]; - const dcmPaths = await findDcmFiles(filePaths) + event.reply("scan-start"); + const dcmPaths = await findDcmFiles(filePaths); const batchSize = os.cpus().length * 1 || 10; const items = await processFilesInBatches(dcmPaths, batchSize); const structDicom = await structureMetadata(items, (progress) => { - event.reply('scan-progress', progress) + event.reply("scan-progress", progress); }); - event.reply('scan-progress-done', structDicom) + event.reply("scan-progress-done", structDicom); }); }; diff --git a/apps/desktop/src/pages/Datasource/index.tsx b/apps/desktop/src/pages/Datasource/index.tsx index efeeaa9..5b438d9 100644 --- a/apps/desktop/src/pages/Datasource/index.tsx +++ b/apps/desktop/src/pages/Datasource/index.tsx @@ -1,15 +1,31 @@ -import { Button } from "@/components/ui/button"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; import { Progress } from "@/components/ui/progress"; +import { ToastAction } from "@/components/ui/toast"; +import { useToast } from "@/components/ui/use-toast"; +import { RocketIcon } from "@radix-ui/react-icons"; import { useEffect, useState } from "react"; - interface ScanProgress { percentage: number; } +const defaultProgress = { + percentage: 0, +}; + export const Datasource = () => { - const [progress, setProgress] = useState(); - const [result, setResult] = useState(); + const [progress, setProgress] = useState(defaultProgress); + const { toast } = useToast(); + const [result, setResult] = useState<[]>([]); + const [importDialogVisible, setImportDialogVisible] = useState(false); + const [startTime, setStartTime] = useState(Date.now()); useEffect(() => { const handleScanProgress = (event, data) => { @@ -23,23 +39,73 @@ export const Datasource = () => { }, []); useEffect(() => { - console.log(1111); + window.ipcRenderer.once("scan-start", () => { + setImportDialogVisible(true); + setStartTime(Date.now()); + }); + }, [progress?.percentage, toast]); + + useEffect(() => { const handleScanFinished = (event, data) => { + const timeDuration = ((Date.now() - startTime) / 1000).toFixed(2); console.log(data); setResult(data); - if (data.error) return; + setImportDialogVisible(false); + + if (data.error) { + return toast({ + variant: "destructive", + title: "Uh oh! Something went wrong.", + description: "There was a problem with your request.", + action: 重试, + }); + } else { + toast({ + variant: "default", + title: "完成", + description: `本次操作共导入${data.length}组序列数据,耗时:${timeDuration } s`, + action: 启动AI测量, + }); + } }; - window.ipcRenderer.once("scan-progress-done", handleScanFinished); - }, []); + window.ipcRenderer.on("scan-progress-done", handleScanFinished); + return () => { + window.ipcRenderer.off("scan-progress-done", handleScanFinished); + }; + }, [startTime, toast]); + + const handleCancelImport = () => { + setImportDialogVisible(false); + }; + + useEffect(() => { + if (!importDialogVisible) { + setProgress(defaultProgress); + setStartTime(Date.now()); + } + }, [importDialogVisible]); return (
-
- - -
+ + + + 导入数据 + + 如果扫描速度很慢,请取消本次扫描,并缩小导入数据的体量 + + +
+ + + 扫描进度 + + + + +
+
+
); }; diff --git a/apps/desktop/src/pages/MenuBar.tsx b/apps/desktop/src/pages/MenuBar.tsx index afa4573..e60ac28 100644 --- a/apps/desktop/src/pages/MenuBar.tsx +++ b/apps/desktop/src/pages/MenuBar.tsx @@ -15,8 +15,11 @@ import { } from "@/components/ui/menubar"; import { EVENT_PARSE_DICOM } from "../../electron/ipcEvent"; import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; export const MenuBar = () => { + const navigate = useNavigate(); + useEffect(() => { window.ipcRenderer.on(EVENT_PARSE_DICOM + ":RES", (event, data) => { console.log(data); @@ -24,12 +27,13 @@ export const MenuBar = () => { }); return () => { - window.ipcRenderer.off(EVENT_PARSE_DICOM + ":RES", () => { }); + window.ipcRenderer.off(EVENT_PARSE_DICOM + ":RES", () => {}); }; }, []); const handleImportDicom = () => { - window.ipcRenderer.send(EVENT_PARSE_DICOM); + navigate("/datasource"); + window.ipcRenderer.send("import-dicom-dialog-visible"); }; return (