rwadurian/backend/mpc-system/services/service-party-app/electron/main.ts

194 lines
5.0 KiB
TypeScript

import { app, BrowserWindow, ipcMain, shell } from 'electron';
import * as path from 'path';
import express from 'express';
import { GrpcClient } from './modules/grpc-client';
import { SecureStorage } from './modules/storage';
// 内置 HTTP 服务器端口
const HTTP_PORT = 3456;
let mainWindow: BrowserWindow | null = null;
let grpcClient: GrpcClient | null = null;
let storage: SecureStorage | null = null;
let httpServer: ReturnType<typeof express.application.listen> | null = null;
// 创建主窗口
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
minWidth: 800,
minHeight: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
titleBarStyle: 'hiddenInset',
show: false,
});
// 开发模式下加载 Vite 开发服务器
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:5173');
mainWindow.webContents.openDevTools();
} else {
// 生产模式下加载打包后的文件
mainWindow.loadFile(path.join(__dirname, '../dist/index.html'));
}
mainWindow.once('ready-to-show', () => {
mainWindow?.show();
});
mainWindow.on('closed', () => {
mainWindow = null;
});
// 处理外部链接
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
shell.openExternal(url);
return { action: 'deny' };
});
}
// 启动内置 HTTP 服务器
function startHttpServer() {
const expressApp = express();
expressApp.use(express.json());
expressApp.use(express.static(path.join(__dirname, '../dist')));
// API 路由
expressApp.get('/api/status', (_req, res) => {
res.json({
connected: grpcClient?.isConnected() ?? false,
partyId: grpcClient?.getPartyId() ?? null,
});
});
// 所有其他路由返回 index.html (SPA)
expressApp.get('*', (_req, res) => {
res.sendFile(path.join(__dirname, '../dist/index.html'));
});
httpServer = expressApp.listen(HTTP_PORT, '127.0.0.1', () => {
console.log(`HTTP server running at http://127.0.0.1:${HTTP_PORT}`);
});
}
// 初始化服务
async function initServices() {
// 初始化 gRPC 客户端
grpcClient = new GrpcClient();
// 初始化安全存储
storage = new SecureStorage();
// 设置 IPC 处理器
setupIpcHandlers();
}
// 设置 IPC 通信处理器
function setupIpcHandlers() {
// gRPC 连接
ipcMain.handle('grpc:connect', async (_event, { host, port }) => {
try {
await grpcClient?.connect(host, port);
return { success: true };
} catch (error) {
return { success: false, error: (error as Error).message };
}
});
// 注册为参与方
ipcMain.handle('grpc:register', async (_event, { partyId, role }) => {
try {
await grpcClient?.registerParty(partyId, role);
return { success: true };
} catch (error) {
return { success: false, error: (error as Error).message };
}
});
// 加入会话
ipcMain.handle('grpc:joinSession', async (_event, { sessionId, partyId, joinToken }) => {
try {
const result = await grpcClient?.joinSession(sessionId, partyId, joinToken);
return { success: true, data: result };
} catch (error) {
return { success: false, error: (error as Error).message };
}
});
// 存储 - 保存 share
ipcMain.handle('storage:saveShare', async (_event, { share, password }) => {
try {
storage?.saveShare(share, password);
return { success: true };
} catch (error) {
return { success: false, error: (error as Error).message };
}
});
// 存储 - 获取 share 列表
ipcMain.handle('storage:listShares', async () => {
try {
const shares = storage?.listShares() ?? [];
return { success: true, data: shares };
} catch (error) {
return { success: false, error: (error as Error).message };
}
});
// 存储 - 导出 share
ipcMain.handle('storage:exportShare', async (_event, { id, password }) => {
try {
const data = storage?.exportShare(id, password);
return { success: true, data };
} catch (error) {
return { success: false, error: (error as Error).message };
}
});
// 存储 - 导入 share
ipcMain.handle('storage:importShare', async (_event, { data, password }) => {
try {
const share = storage?.importShare(data, password);
return { success: true, data: share };
} catch (error) {
return { success: false, error: (error as Error).message };
}
});
}
// 应用生命周期
app.whenReady().then(async () => {
await initServices();
startHttpServer();
createWindow();
// 自动打开浏览器 (可选)
if (process.env.OPEN_BROWSER !== 'false') {
shell.openExternal(`http://127.0.0.1:${HTTP_PORT}`);
}
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('before-quit', () => {
// 清理资源
grpcClient?.disconnect();
httpServer?.close();
});