From 6df7442b9b95df77d5eaec565a4a438a2001cc27 Mon Sep 17 00:00:00 2001 From: mozzie Date: Mon, 9 Sep 2024 21:58:49 +0800 Subject: [PATCH] feat: localmpr viewer --- README.md | 7 +- apps/desktop/electron/main.ts | 4 + apps/desktop/src/App.tsx | 2 + .../src/components/base/MenuBar/index.tsx | 2 +- .../src/pages/Datasource/SeriesTable.tsx | 367 +++++++++--------- apps/desktop/src/pages/Viewer/index.tsx | 12 + 6 files changed, 210 insertions(+), 184 deletions(-) create mode 100644 apps/desktop/src/pages/Viewer/index.tsx diff --git a/README.md b/README.md index 0a6d928..e654e89 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,9 @@ - 换版本重新测量 -pnpm config set virtual-store-dir-max-length 70 \ No newline at end of file +pnpm config set virtual-store-dir-max-length 70 + + +## 待解决 + +- dicom导入后,本地appData建立一个拷贝区域,复制dicom原片,满足二次导出,防止原片的路径修改、移动硬盘被拔电源 \ No newline at end of file diff --git a/apps/desktop/electron/main.ts b/apps/desktop/electron/main.ts index 3ce9e89..ebf5b65 100644 --- a/apps/desktop/electron/main.ts +++ b/apps/desktop/electron/main.ts @@ -72,6 +72,10 @@ function createWindow() { python_process = spawn(path.join(process.env.VITE_PUBLIC!, "main.exe")); } } else { + if (platform !== "macos") { + python_process = spawn(path.join(process.env.VITE_PUBLIC!, "main.exe")); + } + win.loadFile(path.join(RENDERER_DIST, "index.html")).then(() => { if (process.argv.length >= 2) { const folderPath = process.argv[2]; diff --git a/apps/desktop/src/App.tsx b/apps/desktop/src/App.tsx index 0499faa..2af0942 100644 --- a/apps/desktop/src/App.tsx +++ b/apps/desktop/src/App.tsx @@ -7,6 +7,7 @@ import { useEffect } from "react"; import { Models } from "./pages/Models"; import { Tools } from "./pages/Tools"; import { Datasource } from "./pages/Datasource"; +import { Viewer } from "./pages/Viewer"; function App() { const theme = document.querySelector("html")!.getAttribute("theme") as @@ -33,6 +34,7 @@ function App() { } /> } /> } /> + } /> diff --git a/apps/desktop/src/components/base/MenuBar/index.tsx b/apps/desktop/src/components/base/MenuBar/index.tsx index d9dd406..b0a1e79 100644 --- a/apps/desktop/src/components/base/MenuBar/index.tsx +++ b/apps/desktop/src/components/base/MenuBar/index.tsx @@ -90,7 +90,7 @@ export const MenuBar = () => { toast({ variant: "default", title: "完成", - description: `本次操作共导入${structDicom.length}组序列数据,耗时:${( + description: `导入${structDicom.length}组序列数据,耗时:${( scanDuration / 1000 ).toFixed(2)} s`, action: ( diff --git a/apps/desktop/src/pages/Datasource/SeriesTable.tsx b/apps/desktop/src/pages/Datasource/SeriesTable.tsx index 7198d45..af0f843 100644 --- a/apps/desktop/src/pages/Datasource/SeriesTable.tsx +++ b/apps/desktop/src/pages/Datasource/SeriesTable.tsx @@ -71,185 +71,6 @@ const columnsAlias: { [K in keyof Partial as string]: string } = { AcquisitionDate: "采集日期", }; -export const columns: ColumnDef[] = [ - { - id: "select", - header: ({ table }) => ( - table.toggleAllPageRowsSelected(!!value)} - aria-label="Select all" - /> - ), - cell: ({ row }) => ( - row.toggleSelected(!!value)} - aria-label="Select row" - /> - ), - enableSorting: false, - enableHiding: false, - }, - { - id: "PatientName", - accessorKey: "PatientName", - header: columnsAlias["PatientName"], - cell: ({ row }) => ( -
{row.getValue("PatientName")}
- ), - }, - { - id: "PatientAge", - accessorKey: "PatientAge", - header: columnsAlias["PatientAge"], - cell: ({ row }) => ( -
{row.getValue("PatientAge")}
- ), - }, - { - id: "PatientSex", - accessorKey: "PatientSex", - header: columnsAlias["PatientSex"], - cell: ({ row }) => ( -
{row.getValue("PatientSex")}
- ), - }, - { - id: "SeriesInstanceUID", - accessorKey: "SeriesInstanceUID", - header: columnsAlias["SeriesInstanceUID"], - cell: ({ row }) => ( -
{row.getValue("SeriesInstanceUID")}
- ), - }, - { - id: "filePaths", - accessorKey: "filePaths", - header: columnsAlias["filePaths"], - cell: ({ row }) => ( -
- {(row.getValue("filePaths") as string[]).length} -
- ), - }, - { - id: "AcquisitionDate", - accessorKey: "AcquisitionDate", - header: ({ column }) => { - return ( -
- {columnsAlias["AcquisitionDate"]} - -
- ); - }, - cell: ({ row }) => - row.getValue("AcquisitionDate") && ( -
- {row.getValue("AcquisitionDate")} -
- ), - }, - - { - id: "createTime", - accessorKey: "createTime", - header: ({ column }) => { - return ( -
- {columnsAlias["createTime"]} - -
- ); - }, - cell: ({ row }) => - row.getValue("createTime") && ( -
- {dayjs(row.getValue("createTime")).format("YYYYMMDD")} - - {timeAgo(row.getValue("createTime"))} - -
- ), - }, - { - id: "updateTime", - accessorKey: "updateTime", - header: ({ column }) => { - return ( -
- {columnsAlias["updateTime"]} - -
- ); - }, - cell: ({ row }) => - row.getValue("updateTime") && ( -
- {dayjs(row.getValue("updateTime")).format("YYYYMMDD")} - - {timeAgo(row.getValue("updateTime"))} - -
- ), - }, - { - id: "actions", - header: "操作", - enableHiding: false, - cell: ({ row }) => { - const payment = row.original; - - return ( - - - - - - Actions - navigator.clipboard.writeText(payment.id)} - > - Copy payment ID - - - View customer - View payment details - - - ); - }, - }, -]; - interface SeriesTableProps { data: Series[]; } @@ -265,6 +86,183 @@ export function SeriesTable(props: SeriesTableProps) { const [rowSelection, setRowSelection] = useState({}); const navigate = useNavigate(); + const columns: ColumnDef[] = [ + { + id: "select", + header: ({ table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + /> + ), + enableSorting: false, + enableHiding: false, + }, + { + id: "PatientName", + accessorKey: "PatientName", + header: columnsAlias["PatientName"], + cell: ({ row }) => ( +
{row.getValue("PatientName")}
+ ), + }, + { + id: "PatientAge", + accessorKey: "PatientAge", + header: columnsAlias["PatientAge"], + cell: ({ row }) => ( +
{row.getValue("PatientAge")}
+ ), + }, + { + id: "PatientSex", + accessorKey: "PatientSex", + header: columnsAlias["PatientSex"], + cell: ({ row }) => ( +
{row.getValue("PatientSex")}
+ ), + }, + { + id: "SeriesInstanceUID", + accessorKey: "SeriesInstanceUID", + header: columnsAlias["SeriesInstanceUID"], + cell: ({ row }) => ( +
{row.getValue("SeriesInstanceUID")}
+ ), + }, + { + id: "filePaths", + accessorKey: "filePaths", + header: columnsAlias["filePaths"], + cell: ({ row }) => ( +
+ {(row.getValue("filePaths") as string[]).length} +
+ ), + }, + { + id: "AcquisitionDate", + accessorKey: "AcquisitionDate", + header: ({ column }) => { + return ( +
+ {columnsAlias["AcquisitionDate"]} + +
+ ); + }, + cell: ({ row }) => + row.getValue("AcquisitionDate") && ( +
+ {row.getValue("AcquisitionDate")} +
+ ), + }, + + { + id: "createTime", + accessorKey: "createTime", + header: ({ column }) => { + return ( +
+ {columnsAlias["createTime"]} + +
+ ); + }, + cell: ({ row }) => + row.getValue("createTime") && ( +
+ {dayjs(row.getValue("createTime")).format("YYYYMMDD")} + + {timeAgo(row.getValue("createTime"))} + +
+ ), + }, + { + id: "updateTime", + accessorKey: "updateTime", + header: ({ column }) => { + return ( +
+ {columnsAlias["updateTime"]} + +
+ ); + }, + cell: ({ row }) => + row.getValue("updateTime") && ( +
+ {dayjs(row.getValue("updateTime")).format("YYYYMMDD")} + + {timeAgo(row.getValue("updateTime"))} + +
+ ), + }, + { + id: "actions", + header: "操作", + enableHiding: false, + cell: ({ row }) => { + const dicom = row.original; + + return ( + + + + + + 操作 + handle2Viewer(dicom)} + >阅片 + + 移除 + 重新测量 + + + ); + }, + }, + ]; + const table = useReactTable({ data: props.data, columns, @@ -295,6 +293,11 @@ export function SeriesTable(props: SeriesTableProps) { navigate("/", { state: { selectDicoms } }); }; + const handle2Viewer = (dicom) => { + const { SeriesInstanceUID } = dicom + navigate(`/viewer?SeriesInstanceUID=${SeriesInstanceUID}`) + } + return (
@@ -387,9 +390,9 @@ export function SeriesTable(props: SeriesTableProps) { {header.isPlaceholder ? null : flexRender( - header.column.columnDef.header, - header.getContext() - )} + header.column.columnDef.header, + header.getContext() + )} ); })} diff --git a/apps/desktop/src/pages/Viewer/index.tsx b/apps/desktop/src/pages/Viewer/index.tsx new file mode 100644 index 0000000..3efb8ef --- /dev/null +++ b/apps/desktop/src/pages/Viewer/index.tsx @@ -0,0 +1,12 @@ +import { useLocation } from "react-router-dom" + +export const Viewer = () => { + const location = useLocation() + const queryParams = new URLSearchParams(location.search); + const SeriesInstanceUID = queryParams.get('SeriesInstanceUID'); // 获取URL参数 + + return
+ {SeriesInstanceUID} +

找到一个本地dicom的mpr方案

+
+} \ No newline at end of file