236 lines
6.5 KiB
JavaScript
236 lines
6.5 KiB
JavaScript
const { app, BrowserWindow, Menu, shell, ipcMain } = require('electron');
|
|
const path = require('path');
|
|
const { spawn } = require('child_process');
|
|
|
|
// 全局变量
|
|
let mainWindow = null;
|
|
let backendProcess = null;
|
|
|
|
// 开发环境检测
|
|
const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged;
|
|
|
|
// 启动后端服务
|
|
function startBackendServer() {
|
|
if (backendProcess) {
|
|
console.log('Backend server already running');
|
|
return;
|
|
}
|
|
|
|
// 在打包环境中,后端文件在 resources/app/dist/backend/backend/ 目录下
|
|
const backendPath = isDev
|
|
? path.join(__dirname, '../dist/backend/starter.js')
|
|
: path.join(process.resourcesPath, 'app', 'dist', 'backend', 'backend', 'starter.js');
|
|
|
|
console.log('Starting backend server from:', backendPath);
|
|
console.log('Working directory:', process.cwd());
|
|
|
|
// 设置环境变量
|
|
const env = {
|
|
...process.env,
|
|
NODE_ENV: 'production',
|
|
DATA_PATH: app.getPath('userData'),
|
|
DB_PATH: path.join(app.getPath('userData'), 'database.db'),
|
|
VERSION: app.getVersion()
|
|
};
|
|
|
|
// 检查文件是否存在
|
|
const fs = require('fs');
|
|
if (!fs.existsSync(backendPath)) {
|
|
console.error('Backend file not found at:', backendPath);
|
|
return;
|
|
}
|
|
|
|
console.log('Backend file exists, starting process...');
|
|
console.log('Environment variables:', env);
|
|
|
|
backendProcess = spawn('node', [backendPath], {
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
detached: false,
|
|
cwd: isDev ? path.join(__dirname, '..') : process.resourcesPath,
|
|
env: env
|
|
});
|
|
|
|
backendProcess.stdout.on('data', (data) => {
|
|
console.log('Backend stdout:', data.toString());
|
|
});
|
|
|
|
backendProcess.stderr.on('data', (data) => {
|
|
console.error('Backend stderr:', data.toString());
|
|
});
|
|
|
|
backendProcess.on('close', (code) => {
|
|
console.log(`Backend process exited with code ${code}`);
|
|
backendProcess = null;
|
|
});
|
|
|
|
backendProcess.on('error', (error) => {
|
|
console.error('Failed to start backend process:', error);
|
|
console.error('Error details:', error.message);
|
|
console.error('Error code:', error.code);
|
|
backendProcess = null;
|
|
});
|
|
|
|
// 等待一下看看进程是否启动成功
|
|
setTimeout(() => {
|
|
if (backendProcess && !backendProcess.killed) {
|
|
console.log('Backend process appears to be running');
|
|
} else {
|
|
console.error('Backend process failed to start or died immediately');
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
// 停止后端服务
|
|
function stopBackendServer() {
|
|
if (backendProcess) {
|
|
console.log('Stopping backend server...');
|
|
backendProcess.kill();
|
|
backendProcess = null;
|
|
}
|
|
}
|
|
|
|
// 防止多开
|
|
const gotTheLock = app.requestSingleInstanceLock();
|
|
|
|
if (!gotTheLock) {
|
|
app.quit();
|
|
} else {
|
|
app.on('second-instance', () => {
|
|
if (mainWindow) {
|
|
if (mainWindow.isMinimized()) mainWindow.restore();
|
|
mainWindow.focus();
|
|
}
|
|
});
|
|
}
|
|
|
|
// 创建主窗口
|
|
function createWindow() {
|
|
mainWindow = new BrowserWindow({
|
|
width: 1200,
|
|
height: 800,
|
|
minWidth: 800,
|
|
minHeight: 600,
|
|
title: 'Termix',
|
|
icon: path.join(__dirname, '..', 'public', 'icon.png'),
|
|
webPreferences: {
|
|
nodeIntegration: false,
|
|
contextIsolation: true,
|
|
preload: path.join(__dirname, 'preload-simple.cjs'),
|
|
webSecurity: !isDev
|
|
},
|
|
show: false,
|
|
});
|
|
|
|
// 创建应用菜单(包含开发者工具快捷键)
|
|
const template = [
|
|
{
|
|
label: 'View',
|
|
submenu: [
|
|
{
|
|
label: 'Toggle Developer Tools',
|
|
accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
|
|
click: () => {
|
|
mainWindow.webContents.toggleDevTools();
|
|
}
|
|
},
|
|
{
|
|
label: 'Reload',
|
|
accelerator: 'CmdOrCtrl+R',
|
|
click: () => {
|
|
mainWindow.webContents.reload();
|
|
}
|
|
}
|
|
]
|
|
}
|
|
];
|
|
|
|
const menu = Menu.buildFromTemplate(template);
|
|
Menu.setApplicationMenu(menu);
|
|
|
|
// 加载应用
|
|
if (isDev) {
|
|
// 开发环境:连接到 Vite 开发服务器
|
|
mainWindow.loadURL('http://localhost:5173');
|
|
mainWindow.webContents.openDevTools();
|
|
} else {
|
|
// 生产环境:加载构建后的文件
|
|
mainWindow.loadFile(path.join(__dirname, '..', 'dist', 'index.html'));
|
|
// 生产环境也启用开发者工具以便调试
|
|
mainWindow.webContents.openDevTools();
|
|
}
|
|
|
|
// 窗口准备好后显示
|
|
mainWindow.once('ready-to-show', () => {
|
|
mainWindow.show();
|
|
});
|
|
|
|
// 处理窗口关闭事件
|
|
mainWindow.on('closed', () => {
|
|
mainWindow = null;
|
|
});
|
|
|
|
// 处理外部链接
|
|
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
|
shell.openExternal(url);
|
|
return { action: 'deny' };
|
|
});
|
|
}
|
|
|
|
// IPC 通信处理
|
|
ipcMain.handle('get-app-version', () => {
|
|
return app.getVersion();
|
|
});
|
|
|
|
ipcMain.handle('get-platform', () => {
|
|
return process.platform;
|
|
});
|
|
|
|
ipcMain.handle('get-backend-port', () => {
|
|
return 8081; // 后端服务端口
|
|
});
|
|
|
|
ipcMain.handle('restart-backend', async () => {
|
|
try {
|
|
stopBackendServer();
|
|
await new Promise(resolve => setTimeout(resolve, 1000)); // 等待1秒
|
|
startBackendServer();
|
|
return { success: true };
|
|
} catch (error) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
});
|
|
|
|
// 应用事件处理
|
|
app.whenReady().then(async () => {
|
|
// 启动后端服务
|
|
startBackendServer();
|
|
|
|
// 等待后端服务启动
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
createWindow();
|
|
});
|
|
|
|
app.on('window-all-closed', () => {
|
|
stopBackendServer();
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
});
|
|
|
|
app.on('activate', () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
createWindow();
|
|
} else if (mainWindow) {
|
|
mainWindow.show();
|
|
}
|
|
});
|
|
|
|
// 处理未捕获的异常
|
|
process.on('uncaughtException', (error) => {
|
|
console.error('Uncaught Exception:', error);
|
|
});
|
|
|
|
process.on('unhandledRejection', (reason, promise) => {
|
|
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
}); |