Files
pqs-9100_client/electron/main.js

266 lines
6.8 KiB
JavaScript
Raw Permalink Normal View History

2025-10-15 14:12:24 +08:00
const { ElectronEgg } = require('ee-core');
2025-11-26 08:50:22 +08:00
const { app, Menu, ipcMain, Tray, dialog, BrowserWindow } = require('electron');
const path = require('path');
2025-10-16 20:14:55 +08:00
const lifecycle = require('./preload/lifecycle');
2025-10-15 14:12:24 +08:00
const { preload } = require('./preload');
// new app
2025-10-16 20:14:55 +08:00
const electronApp = new ElectronEgg();
2025-10-15 14:12:24 +08:00
2025-11-26 08:50:22 +08:00
// 全局变量
let tray = null;
let isQuitting = false;
// 创建系统托盘
function createTray() {
try {
// 开发环境和生产环境的图标路径
const isDev = !process.resourcesPath;
const iconPath = isDev
? path.join(__dirname, '..', 'public', 'images', 'tray.png')
: path.join(process.resourcesPath, 'app.asar.unpacked', 'public', 'images', 'tray.png');
console.log('[Tray] Icon path:', iconPath);
// 检查图标文件是否存在
const fs = require('fs');
if (!fs.existsSync(iconPath)) {
console.error('[Tray] Icon file not found:', iconPath);
// 如果找不到,尝试使用备用路径(主图标)
const fallbackIcon = isDev
? path.join(__dirname, '..', 'public', 'images', 'icon.png')
: path.join(process.resourcesPath, 'app.asar.unpacked', 'public', 'images', 'icon.png');
if (fs.existsSync(fallbackIcon)) {
console.log('[Tray] Using fallback icon:', fallbackIcon);
tray = new Tray(fallbackIcon);
} else {
console.error('[Tray] No icon available, tray not created');
return;
}
} else {
tray = new Tray(iconPath);
}
tray.setToolTip('NPQS-9100自动检测平台');
console.log('[Tray] Tray created successfully');
// 创建托盘菜单
const contextMenu = Menu.buildFromTemplate([
{
label: '显示主窗口',
click: () => {
const mainWindow = BrowserWindow.getAllWindows()[0];
if (mainWindow) {
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
mainWindow.show();
mainWindow.focus();
}
}
},
{ type: 'separator' },
{
label: '退出',
click: async () => {
// 弹出确认对话框
const { response } = await dialog.showMessageBox({
type: 'question',
title: '退出确认',
message: '确定退出应用吗?',
buttons: ['取消', '确定退出'],
defaultId: 0,
cancelId: 0
});
if (response === 1) {
// 用户点击了"确定退出"
isQuitting = true;
// 获取主窗口
const mainWindow = BrowserWindow.getAllWindows()[0];
// 移除所有 close 监听器,避免阻止关闭
if (mainWindow) {
mainWindow.removeAllListeners('close');
}
// 执行清理
await lifecycle.cleanup();
// 退出应用
app.quit();
}
}
}
]);
tray.setContextMenu(contextMenu);
// 双击托盘图标显示窗口
tray.on('double-click', () => {
const mainWindow = BrowserWindow.getAllWindows()[0];
if (mainWindow) {
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
mainWindow.show();
mainWindow.focus();
}
});
} catch (error) {
console.error('[Tray] Failed to create tray:', error);
tray = null;
}
}
2025-10-16 20:14:55 +08:00
// 创建应用菜单
function createApplicationMenu() {
2025-11-27 17:10:08 +08:00
// 生产环境隐藏菜单栏
Menu.setApplicationMenu(null);
// 调试时可以使用下面的菜单(取消注释)
/*
2025-10-16 20:14:55 +08:00
const template = [
{
label: '查看',
submenu: [
{ role: 'reload', label: '刷新' },
{ role: 'forceReload', label: '强制刷新' },
{ type: 'separator' },
{ role: 'toggleDevTools', label: '开发者工具' }
]
},
{
label: '帮助',
submenu: [
{
label: '使用说明',
click: () => {
// 可以打开帮助文档
}
},
{ type: 'separator' },
{
label: '关于',
click: () => {
// 可以显示关于信息
}
}
]
}
];
2025-11-27 17:10:08 +08:00
2025-10-16 20:14:55 +08:00
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
2025-11-27 17:10:08 +08:00
*/
2025-10-16 20:14:55 +08:00
}
// 注册 IPC 处理器
ipcMain.handle('show-log-window', () => {
if (lifecycle.logWindowManager) {
lifecycle.logWindowManager.show();
}
});
ipcMain.handle('hide-log-window', () => {
if (lifecycle.logWindowManager) {
lifecycle.logWindowManager.hide();
}
});
ipcMain.handle('toggle-log-window', () => {
if (lifecycle.logWindowManager) {
lifecycle.logWindowManager.toggle();
}
});
2025-11-26 08:50:22 +08:00
// 检查是否正在退出
ipcMain.handle('is-quitting', () => {
return isQuitting;
});
// 处理单实例:当尝试启动第二个实例时,聚焦已有窗口
app.on('second-instance', (event, commandLine, workingDirectory) => {
console.log('[Main] Second instance detected, focusing main window...');
// 获取主窗口
const mainWindow = BrowserWindow.getAllWindows().find(win => {
return win.getTitle().includes('NPQS') || win.getTitle().includes('检测平台');
});
if (mainWindow) {
// 如果窗口最小化,恢复它
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
// 如果窗口隐藏,显示它
if (!mainWindow.isVisible()) {
mainWindow.show();
}
// 聚焦窗口
mainWindow.focus();
console.log('[Main] Main window focused');
} else {
console.warn('[Main] Main window not found');
}
});
// 监听应用退出前事件(确保清理托盘)
app.on('before-quit', () => {
console.log('[Main] App before-quit, destroying tray...');
// 销毁托盘图标
if (tray && !tray.isDestroyed()) {
tray.destroy();
tray = null;
}
});
// 监听 will-quit 事件(强制退出时)
app.on('will-quit', () => {
console.log('[Main] App will-quit');
// 确保托盘被销毁
if (tray && !tray.isDestroyed()) {
tray.destroy();
tray = null;
}
});
2025-10-16 20:14:55 +08:00
// register lifecycle (绑定 this 上下文)
electronApp.register("ready", lifecycle.ready.bind(lifecycle));
electronApp.register("electron-app-ready", () => {
lifecycle.electronAppReady.bind(lifecycle)();
createApplicationMenu();
2025-11-26 08:50:22 +08:00
createTray(); // 创建系统托盘
2025-10-16 20:14:55 +08:00
});
electronApp.register("window-ready", lifecycle.windowReady.bind(lifecycle));
2025-11-26 08:50:22 +08:00
electronApp.register("before-close", async () => {
// 如果不是真正退出,不执行清理
if (!isQuitting) {
console.log('[Main] Not quitting, skip cleanup');
return;
}
console.log('[Main] Quitting, execute cleanup');
// 销毁托盘图标
if (tray && !tray.isDestroyed()) {
tray.destroy();
tray = null;
}
await lifecycle.beforeClose.bind(lifecycle)();
});
2025-10-15 14:12:24 +08:00
// register preload
2025-10-16 20:14:55 +08:00
electronApp.register("preload", preload);
2025-10-15 14:12:24 +08:00
// run
2025-10-16 20:14:55 +08:00
electronApp.run();