feat: 这个commit有build阶段的bug,下一个commit解决
This commit is contained in:
parent
1add66a3ab
commit
832e104be6
|
@ -6,13 +6,21 @@ import axios from "axios";
|
||||||
|
|
||||||
export const ALGServerRoot = "http://127.0.0.1:5000/root";
|
export const ALGServerRoot = "http://127.0.0.1:5000/root";
|
||||||
|
|
||||||
export const getEntryPath = () => {
|
export const getAlgPath = (
|
||||||
// 区分操作系统
|
platform: "macos" | "windows",
|
||||||
return path.join(process.env.VITE_PUBLIC!, "main.exe");
|
isDevelopment: boolean
|
||||||
|
): string => {
|
||||||
|
const algExecFile = {
|
||||||
|
macos: "",
|
||||||
|
windows: "main.exe",
|
||||||
|
};
|
||||||
|
const basePath = isDevelopment
|
||||||
|
? path.join(process.env.VITE_PUBLIC)
|
||||||
|
: path.join(process.resourcesPath, "lib", "alg");
|
||||||
|
return path.join(basePath, algExecFile[platform]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const startALGServer = () => {
|
export const startALGServer = (entryPath: string) => {
|
||||||
const entryPath = getEntryPath();
|
|
||||||
const child_process = spawn(entryPath);
|
const child_process = spawn(entryPath);
|
||||||
child_process.on("message", (data) => console.log(data));
|
child_process.on("message", (data) => console.log(data));
|
||||||
child_process.stdout.on("data", (data) => log.info(data.toString()));
|
child_process.stdout.on("data", (data) => log.info(data.toString()));
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { JSONFilePreset } from "lowdb/node";
|
import { JSONFilePreset } from "lowdb/node";
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
import { Low } from "node_modules/lowdb/lib/core/Low";
|
|
||||||
import { StructuredMetadata } from "./dicom";
|
import { StructuredMetadata } from "./dicom";
|
||||||
import { merge } from "lodash";
|
import { merge } from "lodash";
|
||||||
|
|
||||||
|
@ -40,7 +39,7 @@ const defaultTable: DbTable = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export let db: Low<DbTable>;
|
export let db: any;
|
||||||
|
|
||||||
export const createDatabase = async (config: ICreateDatabase) => {
|
export const createDatabase = async (config: ICreateDatabase) => {
|
||||||
const { name } = config;
|
const { name } = config;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// @ts-nocheck
|
||||||
import { downloadSeriesDicomFiles, getTotalScanLength } from "../../core/pacs";
|
import { downloadSeriesDicomFiles, getTotalScanLength } from "../../core/pacs";
|
||||||
import { executeInferTask } from "../../core/alg";
|
import { executeInferTask } from "../../core/alg";
|
||||||
import { InferDeviceEnum, InferStructuralEnum } from "../../core/alg.type";
|
import { InferDeviceEnum, InferStructuralEnum } from "../../core/alg.type";
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { ipcMain } from "electron";
|
||||||
import { registerDicomHandler } from "./dicom/handler";
|
import { registerDicomHandler } from "./dicom/handler";
|
||||||
import { registerCommonHandler } from "./common";
|
import { registerCommonHandler } from "./common";
|
||||||
import { registerAlgHandler } from "./alg";
|
import { registerAlgHandler } from "./alg";
|
||||||
import { registerOllama } from "./llm";
|
|
||||||
|
|
||||||
export const registerIpcMainHandlers = (mainWindow: Electron.BrowserWindow) => {
|
export const registerIpcMainHandlers = (mainWindow: Electron.BrowserWindow) => {
|
||||||
ipcMain.removeAllListeners();
|
ipcMain.removeAllListeners();
|
||||||
|
@ -15,5 +14,4 @@ export const registerIpcMainHandlers = (mainWindow: Electron.BrowserWindow) => {
|
||||||
registerCommonHandler();
|
registerCommonHandler();
|
||||||
registerDicomHandler();
|
registerDicomHandler();
|
||||||
registerAlgHandler();
|
registerAlgHandler();
|
||||||
registerOllama();
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { ipcMain } from "electron";
|
|
||||||
// import { ollama, run } from "../../core/ollama";
|
|
||||||
export const registerOllama = async () => {
|
|
||||||
// const list = await ollama.list();
|
|
||||||
// console.log(list);
|
|
||||||
// ipcMain.handle("chat", async (_event, input: string) => {
|
|
||||||
// const answer = await run("qwen2.5:3B", input);
|
|
||||||
// return answer;
|
|
||||||
// });
|
|
||||||
};
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// @ts-nocheck
|
||||||
import { app, dialog, ipcMain, shell } from "electron";
|
import { app, dialog, ipcMain, shell } from "electron";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { createDatabase } from "./core/db";
|
||||||
import { getMachineId } from "./core/auth";
|
import { getMachineId } from "./core/auth";
|
||||||
import { getPacsPath, runOrthancServer } from "./core/pacs";
|
import { getPacsPath, runOrthancServer } from "./core/pacs";
|
||||||
import { registerIpcMainHandlers } from "./ipcEvent";
|
import { registerIpcMainHandlers } from "./ipcEvent";
|
||||||
import { startALGServer } from "./core/alg";
|
import { getAlgPath, startALGServer } from "./core/alg";
|
||||||
|
|
||||||
// const require = createRequire(import.meta.url);
|
// const require = createRequire(import.meta.url);
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
@ -74,7 +74,7 @@ function createWindow() {
|
||||||
win.loadURL(VITE_DEV_SERVER_URL);
|
win.loadURL(VITE_DEV_SERVER_URL);
|
||||||
registerIpcMainHandlers(win);
|
registerIpcMainHandlers(win);
|
||||||
runOrthancServer(getPacsPath(platform, true));
|
runOrthancServer(getPacsPath(platform, true));
|
||||||
if (platform !== "macos") startALGServer();
|
startALGServer(getAlgPath(platform, true));
|
||||||
} else {
|
} else {
|
||||||
// if (platform !== "macos") {
|
// if (platform !== "macos") {
|
||||||
// python_process = spawn(path.join(process.env.VITE_PUBLIC!, "main.exe"));
|
// python_process = spawn(path.join(process.env.VITE_PUBLIC!, "main.exe"));
|
||||||
|
@ -83,7 +83,7 @@ function createWindow() {
|
||||||
win.loadFile(path.join(RENDERER_DIST, "index.html")).then(() => {
|
win.loadFile(path.join(RENDERER_DIST, "index.html")).then(() => {
|
||||||
registerIpcMainHandlers(win!);
|
registerIpcMainHandlers(win!);
|
||||||
runOrthancServer(getPacsPath(platform, false));
|
runOrthancServer(getPacsPath(platform, false));
|
||||||
|
startALGServer(getAlgPath(platform, false))
|
||||||
// windows右键打开的目录路径
|
// windows右键打开的目录路径
|
||||||
if (process.argv.length >= 2) {
|
if (process.argv.length >= 2) {
|
||||||
const folderPath = process.argv[2];
|
const folderPath = process.argv[2];
|
||||||
|
|
BIN
apps/desktop/extraResources/alg/main.exe
Normal file
BIN
apps/desktop/extraResources/alg/main.exe
Normal file
Binary file not shown.
|
@ -1,11 +1,5 @@
|
||||||
import { MenuItem } from "./type";
|
import { MenuItem } from "./type";
|
||||||
import {
|
import { BrainCircuit, Package, HardDrive, Wrench } from "lucide-react";
|
||||||
BrainCircuit,
|
|
||||||
Package,
|
|
||||||
HardDrive,
|
|
||||||
Wrench,
|
|
||||||
Rotate3DIcon,
|
|
||||||
} from "lucide-react";
|
|
||||||
|
|
||||||
export const menuItems: MenuItem[] = [
|
export const menuItems: MenuItem[] = [
|
||||||
{ to: "/", name: "自动分析", icon: <BrainCircuit /> },
|
{ to: "/", name: "自动分析", icon: <BrainCircuit /> },
|
||||||
|
|
|
@ -2,15 +2,12 @@ import { Button } from "@/components/ui/button";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { SparkleIcon, Trash2 } from "lucide-react";
|
import { SparkleIcon } from "lucide-react";
|
||||||
import {
|
import {
|
||||||
ResizableHandle,
|
ResizableHandle,
|
||||||
ResizablePanel,
|
ResizablePanel,
|
||||||
ResizablePanelGroup,
|
ResizablePanelGroup,
|
||||||
} from "@/components/ui/resizable";
|
} from "@/components/ui/resizable";
|
||||||
|
|
||||||
import { Card } from "@/components/ui/card";
|
|
||||||
import { Series } from "../Datasource/SeriesTable";
|
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
import { LLM } from "./llm";
|
import { LLM } from "./llm";
|
||||||
|
|
||||||
|
@ -33,7 +30,7 @@ const Boot = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const receiveInfer = (_event: any, data: string) => {
|
const receiveInfer = (_event: unknown, data: string) => {
|
||||||
setMessageText(data);
|
setMessageText(data);
|
||||||
};
|
};
|
||||||
window.ipcRenderer.on("infer:progress", receiveInfer);
|
window.ipcRenderer.on("infer:progress", receiveInfer);
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { useEffect, useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
interface LLmProps {
|
export const LLM = () => {
|
||||||
children?: JSX.Element;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const LLM = (props: LLmProps) => {
|
|
||||||
const [inputValue, setInputValue] = useState("");
|
const [inputValue, setInputValue] = useState("");
|
||||||
const [data, setData] = useState<string>();
|
const [data, setData] = useState<string>();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { TrackballControls } from "three/examples/jsm/controls/TrackballControls";
|
import { TrackballControls } from "three/addons/controls/TrackballControls.js";
|
||||||
import { useCallback, useEffect, useRef } from "react";
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import useMultiResizeObserver from "../useMultiResizeObserver";
|
import useMultiResizeObserver from "../useMultiResizeObserver";
|
||||||
|
@ -9,7 +9,7 @@ import { valveMapping } from "./aorta.config";
|
||||||
interface AortaViewerProps {
|
interface AortaViewerProps {
|
||||||
SeriesInstanceUID: string;
|
SeriesInstanceUID: string;
|
||||||
stlFiles: { fileName: string; data: ArrayBuffer }[];
|
stlFiles: { fileName: string; data: ArrayBuffer }[];
|
||||||
measurement: Record<string, unknown>;
|
measurement: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AortaViewer = (props: AortaViewerProps) => {
|
export const AortaViewer = (props: AortaViewerProps) => {
|
||||||
|
@ -61,12 +61,12 @@ export const AortaViewer = (props: AortaViewerProps) => {
|
||||||
}, [stlFiles]);
|
}, [stlFiles]);
|
||||||
|
|
||||||
const initMeasurement = useCallback(() => {
|
const initMeasurement = useCallback(() => {
|
||||||
console.log(measurement)
|
console.log(measurement);
|
||||||
for (const prop in measurement) {
|
for (const prop in measurement) {
|
||||||
if (prop in valveMapping) {
|
if (prop in valveMapping) {
|
||||||
const pointArray = measurement[prop].less_points;
|
const pointArray = measurement[prop].less_points;
|
||||||
const curve = new THREE.CatmullRomCurve3(
|
const curve = new THREE.CatmullRomCurve3(
|
||||||
pointArray.map((p) => new THREE.Vector3(p[0], p[1], p[2]))
|
pointArray.map((p: any) => new THREE.Vector3(p[0], p[1], p[2]))
|
||||||
);
|
);
|
||||||
curve.curveType = "centripetal"; // 曲线类型
|
curve.curveType = "centripetal"; // 曲线类型
|
||||||
curve.closed = true; // 曲线是否闭合
|
curve.closed = true; // 曲线是否闭合
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { TrackballControls } from "three/examples/jsm/controls/TrackballControls";
|
import { TrackballControls } from "three/examples/jsm/controls/TrackballControls.js";
|
||||||
import { useCallback, useEffect, useRef } from "react";
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import useMultiResizeObserver from "../useMultiResizeObserver";
|
import useMultiResizeObserver from "../useMultiResizeObserver";
|
||||||
|
|
|
@ -95,7 +95,7 @@ export const Segments = [
|
||||||
/**
|
/**
|
||||||
* 瓣环配置映射
|
* 瓣环配置映射
|
||||||
*/
|
*/
|
||||||
export const valveMapping = {
|
export const valveMapping: Record<string, any> = {
|
||||||
annulus_plane: {
|
annulus_plane: {
|
||||||
color: [143 / 255, 6 / 255, 3 / 255],
|
color: [143 / 255, 6 / 255, 3 / 255],
|
||||||
name: "瓣环平面",
|
name: "瓣环平面",
|
||||||
|
|
|
@ -6,9 +6,7 @@ import { PeripheralViewer } from "./PeripheralViewer";
|
||||||
import { SparkleIcon } from "lucide-react";
|
import { SparkleIcon } from "lucide-react";
|
||||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||||
|
|
||||||
interface Model3DViewerProps {}
|
export const Model3DViewer = () => {
|
||||||
|
|
||||||
export const Model3DViewer = (props: Model3DViewerProps) => {
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const queryParams = new URLSearchParams(location.search);
|
const queryParams = new URLSearchParams(location.search);
|
||||||
const SeriesInstanceUID = queryParams.get("SeriesInstanceUID");
|
const SeriesInstanceUID = queryParams.get("SeriesInstanceUID");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { STLLoader } from "three/examples/jsm/loaders/STLLoader";
|
import { STLLoader } from "three/examples/jsm/loaders/STLLoader.js";
|
||||||
import { SegmentsPeripheral } from "./peri.config";
|
import { SegmentsPeripheral } from "./peri.config";
|
||||||
import { InferStructuralEnum } from "./type";
|
import { InferStructuralEnum } from "./type";
|
||||||
import { Segments } from "./aorta.config";
|
import { Segments } from "./aorta.config";
|
||||||
|
@ -29,7 +29,7 @@ const loadSTLFile = (
|
||||||
url,
|
url,
|
||||||
(geometry: THREE.BufferGeometry) => resolve({ geometry, fileName }),
|
(geometry: THREE.BufferGeometry) => resolve({ geometry, fileName }),
|
||||||
undefined,
|
undefined,
|
||||||
(error) => {
|
(error: any) => {
|
||||||
console.error(`Error loading STL file ${fileName}:`, error);
|
console.error(`Error loading STL file ${fileName}:`, error);
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { metaData } from "@cornerstonejs/core";
|
import { metaData } from "@cornerstonejs/core";
|
||||||
|
// @ts-ignore
|
||||||
import cornerstoneDICOMImageLoader from "@cornerstonejs/dicom-image-loader";
|
import cornerstoneDICOMImageLoader from "@cornerstonejs/dicom-image-loader";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// @ts-nocheck
|
||||||
import { api } from "dicomweb-client";
|
import { api } from "dicomweb-client";
|
||||||
import dcmjs from "dcmjs";
|
import dcmjs from "dcmjs";
|
||||||
import { utilities } from "@cornerstonejs/core";
|
import { utilities } from "@cornerstonejs/core";
|
||||||
|
@ -22,7 +23,7 @@ interface CreateImageIdsAndCacheMetaDataOptions {
|
||||||
SOPInstanceUID?: string | null;
|
SOPInstanceUID?: string | null;
|
||||||
wadoRsRoot: string;
|
wadoRsRoot: string;
|
||||||
client?: api.DICOMwebClient | null;
|
client?: api.DICOMwebClient | null;
|
||||||
convertMultiframe?: boolean,
|
convertMultiframe?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,7 +84,8 @@ export const createImageIdsAndCacheMetaData = async (
|
||||||
if (instanceMetaData) {
|
if (instanceMetaData) {
|
||||||
const metadata =
|
const metadata =
|
||||||
DicomMetaDictionary.naturalizeDataset(instanceMetaData);
|
DicomMetaDictionary.naturalizeDataset(instanceMetaData);
|
||||||
const pixelSpacing = getPixelSpacingInformation(metadata) as Number[];
|
|
||||||
|
const pixelSpacing = getPixelSpacingInformation(metadata);
|
||||||
|
|
||||||
if (pixelSpacing) {
|
if (pixelSpacing) {
|
||||||
calibratedPixelSpacingMetadataProvider.add(imageId, {
|
calibratedPixelSpacingMetadataProvider.add(imageId, {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// @ts-nocheck
|
||||||
import { metaData } from "@cornerstonejs/core";
|
import { metaData } from "@cornerstonejs/core";
|
||||||
import type { InstanceMetadata } from "@cornerstonejs/calculate-suv";
|
import type { InstanceMetadata } from "@cornerstonejs/calculate-suv";
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// @ts-nocheck
|
||||||
import dicomParser from "dicom-parser";
|
import dicomParser from "dicom-parser";
|
||||||
import * as cornerstone from "@cornerstonejs/core";
|
import * as cornerstone from "@cornerstonejs/core";
|
||||||
import cornerstoneDICOMImageLoader from "@cornerstonejs/dicom-image-loader";
|
import cornerstoneDICOMImageLoader from "@cornerstonejs/dicom-image-loader";
|
||||||
|
@ -22,7 +23,7 @@ export const initCornerstoneDICOMImageLoader = () => {
|
||||||
cornerstoneDICOMImageLoader.external.cornerstone = cornerstone;
|
cornerstoneDICOMImageLoader.external.cornerstone = cornerstone;
|
||||||
cornerstoneDICOMImageLoader.external.dicomParser = dicomParser;
|
cornerstoneDICOMImageLoader.external.dicomParser = dicomParser;
|
||||||
cornerstoneDICOMImageLoader.configure({
|
cornerstoneDICOMImageLoader.configure({
|
||||||
useWebWorkers: true,
|
useWebWorkers: false,
|
||||||
decodeConfig: {
|
decodeConfig: {
|
||||||
convertFloatPixelDataToInt: false,
|
convertFloatPixelDataToInt: false,
|
||||||
// use16BitDataType: false,
|
// use16BitDataType: false,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// @ts-nocheck
|
||||||
import { volumeLoader } from "@cornerstonejs/core";
|
import { volumeLoader } from "@cornerstonejs/core";
|
||||||
import {
|
import {
|
||||||
cornerstoneStreamingImageVolumeLoader,
|
cornerstoneStreamingImageVolumeLoader,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// @ts-nocheck
|
||||||
import { utilities as csUtils } from "@cornerstonejs/core";
|
import { utilities as csUtils } from "@cornerstonejs/core";
|
||||||
|
|
||||||
const scalingPerImageId = {};
|
const scalingPerImageId = {};
|
||||||
|
|
|
@ -29,11 +29,17 @@ export default defineConfig({
|
||||||
: {},
|
: {},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
assetsInclude: ["**/*.wasm"],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.resolve(__dirname, "./src"),
|
"@": path.resolve(__dirname, "./src"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
external: ["zlib"],
|
||||||
|
},
|
||||||
|
},
|
||||||
server: {
|
server: {
|
||||||
cors: true,
|
cors: true,
|
||||||
headers: {
|
headers: {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user