cvpilot-tool/apps/desktop/electron/ipcMainHandlers.ts
2024-09-10 14:09:34 +08:00

264 lines
8.4 KiB
TypeScript

import { app, dialog, ipcMain, shell } from "electron";
import os from "os";
import {
findDcmFiles,
keyProp,
processFilesInBatches,
structureMetadata,
} from "./core/dicom";
import { db } from "./core/db";
import axios from "axios";
import path from "node:path";
import { mkdir, stat } from "fs/promises";
import { readFileSync } from "node:fs";
/**
* 渲染进程和主进程的事件调度
*/
const registerIpcMainHandlers = (mainWindow: Electron.BrowserWindow | null) => {
if (!mainWindow) return;
ipcMain.removeAllListeners();
/**
* 等待渲染完成再显示窗口
*/
ipcMain.on("ipc-loaded", () => mainWindow.show());
ipcMain.on("ai:task", (_, data) => {
const { selectDicoms } = data;
const promises = selectDicoms.reduce(
(
promiseChain: Promise<any>,
dicom: { filePaths: any; PatientName: any; SeriesInstanceUID: any }
) => {
return promiseChain.then(() => {
const { filePaths, PatientName, SeriesInstanceUID } = dicom;
const img_path = path.dirname(filePaths[0]);
const save_path = path.join(
app.getPath("userData"),
"output",
PatientName,
SeriesInstanceUID
);
const params = {
img_path,
save_path,
pu: "GPU",
module: "root",
turbo: true,
};
const startTime = Date.now(); // 记录请求开始时间
console.log(
`Request for ${PatientName} started at ${new Date(
startTime
).toISOString()}`
);
console.log(params);
return axios
.post("http://127.0.0.1:5000/root", { ...params })
.then((response) => {
const endTime = Date.now(); // 记录请求结束时间
const duration = (endTime - startTime) / 1000; // 计算耗时,单位为秒
console.log(
`Response for ${PatientName} received at ${new Date(
endTime
).toISOString()} (Duration: ${duration} seconds)`
);
console.log(response.data);
})
.catch((error) => {
const endTime = Date.now(); // 即使失败也记录结束时间
const duration = (endTime - startTime) / 1000;
console.error(
`Error for ${PatientName} at ${new Date(
endTime
).toISOString()} (Duration: ${duration} seconds)`
);
console.error(error);
});
});
},
Promise.resolve()
); // 从 resolve() 开始,依次链接每个 Promise
const overallStartTime = Date.now(); // 记录总的开始时间
promises.then(() => {
const overallEndTime = Date.now(); // 记录总的结束时间
const overallDuration = (overallEndTime - overallStartTime) / 1000; // 总耗时
console.log(`All dicoms processed in ${overallDuration} seconds.`);
});
});
/**
* 显示选择文件夹的dialog
*/
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];
event.reply("scan-start");
const scanTimeStart = Date.now();
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);
});
// 存数据库
const changeTime = Date.now();
for (const item of structDicom) {
const existSeries = db.data.series.find(
(i) => i[keyProp] === item[keyProp]
);
existSeries
? Object.assign(existSeries, item, { updateTime: changeTime })
: db.data.series.push({
...item,
createTime: changeTime,
updateTime: changeTime,
});
await db.write();
}
event.reply("scan-progress-done", {
structDicom,
scanDuration: Date.now() - scanTimeStart,
});
});
ipcMain.on("one-step", async (event, dir) => {
const directory = path.resolve(dir);
const dcmPaths = await findDcmFiles(directory);
const batchSize = os.cpus().length * 1 || 10;
const items = await processFilesInBatches(dcmPaths, batchSize);
const structDicom = await structureMetadata(items);
// 存数据库
const changeTime = Date.now();
for (const item of structDicom) {
const existSeries = db.data.series.find(
(i) => i[keyProp] === item[keyProp]
);
existSeries
? Object.assign(existSeries, item, { updateTime: changeTime })
: db.data.series.push({
...item,
createTime: changeTime,
updateTime: changeTime,
});
await db.write();
}
// 启动分析
const promises = structDicom.reduce((promiseChain, dicom) => {
return promiseChain.then(() => {
const { filePaths, PatientName = "", SeriesInstanceUID = "" } = dicom;
const img_path = path.dirname(filePaths[0]);
const save_path = path.join(
app.getPath("userData"),
"output",
PatientName,
SeriesInstanceUID
);
const params = {
img_path,
save_path,
pu: "GPU",
module: "root",
turbo: true,
};
const startTime = Date.now(); // 记录请求开始时间
return axios
.post("http://127.0.0.1:5000/root", { ...params })
.then((response) => {
const endTime = Date.now(); // 记录请求结束时间
const duration = (endTime - startTime) / 1000; // 计算耗时,单位为秒
event.reply(
"taskFinished",
`Response for ${PatientName} received at ${new Date(
endTime
).toISOString()} (Duration: ${duration} seconds)`
);
console.log(response);
})
.catch((error) => {
const endTime = Date.now(); // 即使失败也记录结束时间
const duration = (endTime - startTime) / 1000;
console.error(
`Error for ${PatientName} at ${new Date(
endTime
).toISOString()} (Duration: ${duration} seconds)`
);
console.error(error);
});
});
}, Promise.resolve()); // 从 resolve() 开始,依次链接每个 Promise
const overallStartTime = Date.now(); // 记录总的开始时间
promises.then(() => {
const overallEndTime = Date.now(); // 记录总的结束时间
const overallDuration = (overallEndTime - overallStartTime) / 1000; // 总耗时
event.reply("tasksFinished", overallDuration);
});
});
/**
* api 获取 列表的中数据
*/
ipcMain.on("db:series:select", async (event) => {
await db.read();
const seriesList = db.data.series;
event.reply("db:series:select:response", seriesList);
});
/**
* 用户配置保存
*/
ipcMain.on("setInferDevice", async (event, device) => {
await db.update(({ setting }) => ({ ...setting, inferDevice: device }));
event.reply("setInferDevice:response", `推理硬件修改为${device}`);
});
/**
* 打开输出文件夹目录
*/
ipcMain.on("openOutputPath", async () => {
await db.read();
const optPath = db.data.setting.outputPath;
const resolvedPath = path.resolve(optPath);
try {
// 检查路径是否存在
const stats = await stat(resolvedPath);
if (stats.isDirectory()) shell.openPath(resolvedPath);
} catch (error: any) {
await mkdir(resolvedPath, { recursive: true });
shell.openPath(resolvedPath);
}
});
ipcMain.on("request-dicom", async (event, data) => {
console.log(data);
const SeriesInstanceUID = data;
await db.read();
const series = await db.data.series.find(
(s) => s.SeriesInstanceUID === SeriesInstanceUID
);
console.log(series);
if (series) {
const { filePaths } = series;
const buffers = filePaths.map((filePath) => {
const dicomFileBuffer = readFileSync(filePath);
return dicomFileBuffer;
});
event.reply("request-dicom:response", series);
} else {
console.log("没找到series");
}
});
};
export default registerIpcMainHandlers;