274 lines
7.2 KiB
JavaScript
274 lines
7.2 KiB
JavaScript
// 确保所有导入都使用 ES 模块语法
|
||
import { app, BrowserWindow, ipcMain, dialog } from "electron";
|
||
// 修改fs模块的导入方式 - 从命名导入改为默认导入
|
||
import fs from "fs";
|
||
import path from "path";
|
||
import { fileURLToPath } from "url";
|
||
import { migrateDatabases } from './db/migration.js';
|
||
import {
|
||
checkDatabaseInitialized,
|
||
initializeDatabase,
|
||
} from "./db/index.js";
|
||
// 导入配置项服务
|
||
import {
|
||
initConfigIpc,
|
||
} from "./service/configService.js";
|
||
// 导入字典服务 - 使用实际导出的函数名称
|
||
import {
|
||
initDictIpc,
|
||
} from "./service/dictService.js";
|
||
// 导入题干服务
|
||
import {
|
||
initQuestionIpc,
|
||
} from './service/questionService.js';
|
||
import {
|
||
initExamIpc,
|
||
} from "./service/examService.js";
|
||
|
||
// 添加考生服务导入
|
||
import {
|
||
initExamineeIpc
|
||
} from "./service/examineeService.js";
|
||
|
||
import {
|
||
initExamingIpc
|
||
} from "./service/examingService.js";
|
||
|
||
import {
|
||
initFileIpc
|
||
} from "./service/fileService.js";
|
||
|
||
// 定义 __dirname 和 __filename
|
||
const __filename = fileURLToPath(import.meta.url);
|
||
const __dirname = path.dirname(__filename);
|
||
|
||
// 确保在应用最开始处添加单实例锁检查
|
||
// 尝试获取单实例锁
|
||
const gotTheLock = app.requestSingleInstanceLock();
|
||
|
||
// 如果获取锁失败,说明已有实例在运行,直接退出
|
||
if (!gotTheLock) {
|
||
app.quit();
|
||
} else {
|
||
// 设置第二个实例启动时的处理
|
||
app.on("second-instance", (event, commandLine, workingDirectory) => {
|
||
// 当用户尝试启动第二个实例时,聚焦到已有的主窗口
|
||
const mainWindow = BrowserWindow.getAllWindows()[0];
|
||
if (mainWindow) {
|
||
if (mainWindow.isMinimized()) mainWindow.restore();
|
||
mainWindow.focus();
|
||
}
|
||
});
|
||
}
|
||
|
||
// 保存主窗口引用
|
||
let mainWindow = null;
|
||
|
||
function createWindow() {
|
||
// 如果已经有窗口,直接返回
|
||
if (mainWindow) {
|
||
return;
|
||
}
|
||
|
||
mainWindow = new BrowserWindow({
|
||
// 设置窗口宽度和高度为屏幕大小
|
||
width: 1200,
|
||
height: 800,
|
||
// 确保窗口最大化
|
||
maximized: true,
|
||
// 隐藏菜单栏
|
||
autoHideMenuBar: true,
|
||
// 完全禁用菜单栏
|
||
menuBarVisible: false,
|
||
webPreferences: {
|
||
preload: path.join(__dirname, "../electron/preload.js"),
|
||
nodeIntegration: false,
|
||
contextIsolation: true,
|
||
openDevTools: true,
|
||
},
|
||
});
|
||
|
||
// 显式调用最大化方法,确保窗口最大化
|
||
mainWindow.maximize();
|
||
|
||
if (process.env.NODE_ENV === "development") {
|
||
mainWindow.loadURL("http://localhost:5173/");
|
||
mainWindow.webContents.openDevTools();
|
||
} else {
|
||
// 使用应用路径来构建更可靠的加载路径
|
||
const appPath = app.getAppPath();
|
||
console.log(`应用路径: ${appPath}`);
|
||
|
||
// 尝试多种可能的路径
|
||
const pathsToTry = [
|
||
// 尝试1: 相对路径 (原有逻辑)
|
||
path.join(__dirname, "../dist/index.html"),
|
||
// 尝试2: 直接使用应用路径 + dist
|
||
path.join(appPath, "dist/index.html"),
|
||
// 尝试3: 应用路径的上一级 + dist
|
||
path.join(path.dirname(appPath), "dist/index.html")
|
||
];
|
||
|
||
let indexPath = null;
|
||
// 检查哪个路径存在
|
||
for (const pathOption of pathsToTry) {
|
||
console.log(`尝试检查路径: ${pathOption}`);
|
||
try {
|
||
if (fs.existsSync(pathOption)) {
|
||
indexPath = pathOption;
|
||
console.log(`找到文件: ${indexPath}`);
|
||
break;
|
||
}
|
||
} catch (error) {
|
||
console.error(`检查路径时出错: ${error}`);
|
||
}
|
||
}
|
||
|
||
if (indexPath) {
|
||
try {
|
||
// 使用file://协议加载本地文件,避免路径问题
|
||
mainWindow.loadFile(indexPath);
|
||
// 添加加载完成事件监听
|
||
mainWindow.webContents.on('did-finish-load', () => {
|
||
console.log('文件加载完成');
|
||
});
|
||
// 添加加载失败事件监听
|
||
mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => {
|
||
console.error(`文件加载失败: ${errorCode} - ${errorDescription}`);
|
||
dialog.showErrorBox('加载失败', `无法加载应用界面: ${errorDescription}`);
|
||
});
|
||
} catch (error) {
|
||
console.error(`加载文件时出错: ${error}`);
|
||
dialog.showErrorBox('加载失败', `无法加载应用界面: ${error.message}`);
|
||
}
|
||
} else {
|
||
console.error(`所有路径都不存在: ${pathsToTry.join(', ')}`);
|
||
dialog.showErrorBox('文件不存在', `无法找到应用界面文件,请检查打包配置`);
|
||
}
|
||
}
|
||
|
||
|
||
// 添加窗口关闭前的确认对话框
|
||
mainWindow.on('close', (event) => {
|
||
// 阻止默认关闭行为
|
||
event.preventDefault();
|
||
|
||
// 显示确认对话框
|
||
dialog.showMessageBox({
|
||
type: 'warning',
|
||
title: '关闭确认',
|
||
message: '系统关闭后,已进行中的试卷将不会被保存,是否确认要关闭?',
|
||
buttons: ['取消', '确认关闭'],
|
||
defaultId: 0
|
||
}).then((result) => {
|
||
// 如果用户点击确认关闭
|
||
if (result.response === 1) {
|
||
// 允许窗口关闭
|
||
mainWindow.destroy();
|
||
}
|
||
// 否则取消关闭
|
||
});
|
||
});
|
||
|
||
// 当窗口关闭时,清空引用
|
||
mainWindow.on("closed", () => {
|
||
mainWindow = null;
|
||
});
|
||
}
|
||
|
||
// 初始化应用
|
||
async function setupApp() {
|
||
try {
|
||
console.log("应用启动 - 检查数据库初始化状态...");
|
||
|
||
// 等待应用就绪
|
||
await app.whenReady();
|
||
|
||
// 执行数据库迁移
|
||
await migrateDatabases();
|
||
|
||
// 使用全局变量防止重复初始化检查
|
||
if (global.dbInitCheck) {
|
||
console.log("数据库初始化检查已完成");
|
||
return;
|
||
}
|
||
global.dbInitCheck = true;
|
||
|
||
const isInitialized = await checkDatabaseInitialized();
|
||
console.log("数据库初始化状态:", isInitialized);
|
||
|
||
// 只检查状态,不自动初始化
|
||
} catch (error) {
|
||
console.error("数据库检查过程中出错:", error);
|
||
}
|
||
}
|
||
|
||
function setupIpcMain() {
|
||
|
||
// 数据库相关
|
||
ipcMain.handle("check-database-initialized", async () => {
|
||
try {
|
||
return await checkDatabaseInitialized();
|
||
} catch (error) {
|
||
console.error("Failed to check database initialization:", error);
|
||
return false;
|
||
}
|
||
});
|
||
|
||
ipcMain.handle("initialize-database", async () => {
|
||
try {
|
||
return await initializeDatabase();
|
||
} catch (error) {
|
||
console.error("Failed to initialize database:", error);
|
||
return false;
|
||
}
|
||
});
|
||
|
||
// 初始化config相关IPC
|
||
initConfigIpc(ipcMain);
|
||
|
||
// 初始化dict相关IPC
|
||
initDictIpc(ipcMain);
|
||
|
||
// 初始化exam相关IPC
|
||
initExamIpc(ipcMain);
|
||
|
||
// 初始化question相关IPC
|
||
initQuestionIpc(ipcMain);
|
||
|
||
// 初始化考生相关IPC
|
||
initExamineeIpc(ipcMain);
|
||
|
||
initExamingIpc(ipcMain);
|
||
|
||
initFileIpc(ipcMain);
|
||
}
|
||
|
||
// 只保留一个app.whenReady().then()调用
|
||
app.whenReady().then(() => {
|
||
setupApp();
|
||
createWindow();
|
||
setupIpcMain();
|
||
});
|
||
|
||
app.on("window-all-closed", () => {
|
||
// 在所有窗口关闭后,清空主窗口引用
|
||
mainWindow = null;
|
||
// 对于非macOS平台,仍然需要退出应用
|
||
if (process.platform !== "darwin") {
|
||
app.quit();
|
||
}
|
||
});
|
||
|
||
app.on("activate", () => {
|
||
// 只有当没有窗口时才创建新窗口
|
||
if (BrowserWindow.getAllWindows().length === 0) {
|
||
createWindow();
|
||
}
|
||
});
|
||
|
||
// 在应用退出前关闭所有数据库连接
|
||
app.on("will-quit", () => {
|
||
console.log("应用即将退出...");
|
||
});
|