app
This commit is contained in:
parent
7f90027647
commit
561ed85294
@ -40,7 +40,7 @@ if (isDev) {
|
|||||||
dataDir = path.join(appDir, 'data');
|
dataDir = path.join(appDir, 'data');
|
||||||
} else {
|
} else {
|
||||||
// 非便携模式:数据存储在应用同级的data目录
|
// 非便携模式:数据存储在应用同级的data目录
|
||||||
dataDir = path.join(appDir, 'data');
|
dataDir = path.join(path.dirname(appDir), 'data');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保数据目录存在
|
// 确保数据目录存在
|
||||||
|
@ -41,97 +41,77 @@ protocol.registerSchemesAsPrivileged([
|
|||||||
let mainWindow = null;
|
let mainWindow = null;
|
||||||
|
|
||||||
async function createWindow() {
|
async function createWindow() {
|
||||||
try {
|
// Create the browser window.
|
||||||
// Create the browser window.
|
mainWindow = new BrowserWindow({
|
||||||
mainWindow = new BrowserWindow({
|
width: 800, // 默认宽度(实际会被最大化覆盖)
|
||||||
width: 800,
|
height: 600, // 默认高度(实际会被最大化覆盖)
|
||||||
height: 600,
|
show: false, // 先隐藏窗口,避免闪烁
|
||||||
show: true, // 直接显示窗口,避免隐藏后显示可能导致的问题
|
webPreferences: {
|
||||||
webPreferences: {
|
// 改为使用绝对路径解析
|
||||||
// 修复preload路径,使用更可靠的解析方式
|
preload: require("path").join(process.cwd(), "src/preload.js"),
|
||||||
preload: path.join(__dirname, '..', 'src', 'preload.js'),
|
nodeIntegration: false,
|
||||||
nodeIntegration: false,
|
contextIsolation: true,
|
||||||
contextIsolation: true,
|
},
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// 设置隐藏菜单栏
|
// 设置隐藏菜单栏
|
||||||
mainWindow.setMenu(null);
|
mainWindow.setMenu(null);
|
||||||
|
|
||||||
// 设置窗口最大化(放在窗口创建后,确保窗口已经初始化)
|
// 在窗口显示前设置最大化
|
||||||
|
mainWindow.maximize();
|
||||||
|
// 然后显示窗口
|
||||||
|
mainWindow.show();
|
||||||
|
|
||||||
|
// 添加窗口关闭事件监听
|
||||||
|
mainWindow.on("close", (event) => {
|
||||||
|
console.log("检测到窗口关闭事件");
|
||||||
|
|
||||||
|
// 阻止默认的关闭行为
|
||||||
|
event.preventDefault();
|
||||||
|
console.log("已阻止默认关闭行为");
|
||||||
|
|
||||||
|
// 使用同步方式显示对话框(Electron 11.5支持的方式)
|
||||||
try {
|
try {
|
||||||
mainWindow.maximize();
|
// 直接显示对话框并获取结果
|
||||||
} catch (error) {
|
const response = dialog.showMessageBoxSync(mainWindow, {
|
||||||
console.warn('窗口最大化失败:', error);
|
type: "warning",
|
||||||
}
|
title: "确认关闭",
|
||||||
|
message: "确认要退出软件吗?退出后,未完成的考试将不会被保存。",
|
||||||
|
buttons: ["取消", "确认关闭"],
|
||||||
|
defaultId: 0,
|
||||||
|
cancelId: 0,
|
||||||
|
});
|
||||||
|
|
||||||
// 加载URL
|
console.log("用户选择了response:", response);
|
||||||
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
|
||||||
// Load the url of the dev server if in development mode
|
|
||||||
await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
|
|
||||||
if (!process.env.IS_TEST) mainWindow.webContents.openDevTools();
|
|
||||||
} else {
|
|
||||||
createProtocol("app");
|
|
||||||
// Load the index.html when not in development
|
|
||||||
mainWindow.loadURL("app://./index.html");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加窗口关闭事件监听
|
// 检查用户选择的按钮索引
|
||||||
mainWindow.on("close", (event) => {
|
if (response === 1) {
|
||||||
console.log("检测到窗口关闭事件");
|
console.log("用户确认关闭,准备退出应用");
|
||||||
|
// 移除所有事件监听器以防止任何干扰
|
||||||
// 阻止默认的关闭行为
|
mainWindow.removeAllListeners();
|
||||||
event.preventDefault();
|
// 强制关闭窗口
|
||||||
console.log("已阻止默认关闭行为");
|
mainWindow.destroy();
|
||||||
|
// 然后退出应用
|
||||||
// 使用同步方式显示对话框(Electron 11.5支持的方式)
|
setTimeout(() => {
|
||||||
try {
|
console.log("强制退出应用");
|
||||||
// 直接显示对话框并获取结果
|
app.quit();
|
||||||
const response = dialog.showMessageBoxSync(mainWindow, {
|
}, 100);
|
||||||
type: "warning",
|
} else {
|
||||||
title: "确认关闭",
|
console.log("用户取消关闭");
|
||||||
message: "确认要退出软件吗?退出后,未完成的考试将不会被保存。",
|
|
||||||
buttons: ["取消", "确认关闭"],
|
|
||||||
defaultId: 0,
|
|
||||||
cancelId: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("用户选择了response:", response);
|
|
||||||
|
|
||||||
// 检查用户选择的按钮索引
|
|
||||||
if (response === 1) {
|
|
||||||
console.log("用户确认关闭,准备退出应用");
|
|
||||||
// 移除所有事件监听器以防止任何干扰
|
|
||||||
mainWindow.removeAllListeners();
|
|
||||||
// 强制关闭窗口
|
|
||||||
mainWindow.destroy();
|
|
||||||
// 然后退出应用
|
|
||||||
setTimeout(() => {
|
|
||||||
console.log("强制退出应用");
|
|
||||||
app.quit();
|
|
||||||
}, 100);
|
|
||||||
} else {
|
|
||||||
console.log("用户取消关闭");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("显示对话框时出错:", error);
|
|
||||||
}
|
}
|
||||||
});
|
} catch (error) {
|
||||||
|
console.error("显示对话框时出错:", error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 添加错误监听
|
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
||||||
mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => {
|
// Load the url of the dev server if in development mode
|
||||||
console.error(`页面加载失败: ${errorCode} - ${errorDescription}`);
|
await mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
|
||||||
});
|
if (!process.env.IS_TEST) mainWindow.webContents.openDevTools();
|
||||||
|
} else {
|
||||||
// 添加崩溃监听
|
createProtocol("app");
|
||||||
mainWindow.webContents.on('crashed', (event, killed) => {
|
// Load the index.html when not in development
|
||||||
console.error(`渲染进程崩溃: killed=${killed}`);
|
mainWindow.loadURL("app://./index.html");
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('创建窗口时出错:', error);
|
|
||||||
// 如果创建窗口失败,显示错误对话框
|
|
||||||
dialog.showErrorBox('应用启动失败', `无法创建应用窗口: ${error.message}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,104 +175,92 @@ const sqlite3 = require("sqlite3").verbose();
|
|||||||
|
|
||||||
// 在app.on('ready')事件中添加
|
// 在app.on('ready')事件中添加
|
||||||
app.on("ready", async () => {
|
app.on("ready", async () => {
|
||||||
|
// 禁用Vue DevTools扩展
|
||||||
|
/*
|
||||||
|
if (isDevelopment && !process.env.IS_TEST) {
|
||||||
|
// Install Vue Devtools
|
||||||
|
try {
|
||||||
|
await installExtension(VUEJS_DEVTOOLS)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Vue Devtools failed to install:', e.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 初始化配置相关的IPC处理程序
|
||||||
|
initConfigIpc(ipcMain);
|
||||||
|
// 初始化字典相关的IPC处理程序
|
||||||
|
initDictIpc(ipcMain);
|
||||||
|
// 初始化试题相关的IPC处理程序
|
||||||
|
initQuestionIpc(ipcMain);
|
||||||
|
// 初始化考试相关的IPC处理程序
|
||||||
|
initExamIpc(ipcMain);
|
||||||
|
// 初始化考生相关的IPC处理程序
|
||||||
|
initExamineeIpc(ipcMain);
|
||||||
|
// 初始化考生考试相关的IPC处理程序
|
||||||
|
initExamingIpc(ipcMain);
|
||||||
|
// 初始化文件相关的IPC处理程序
|
||||||
|
initFileIpc(ipcMain);
|
||||||
|
|
||||||
|
// 检查数据库是否初始化
|
||||||
try {
|
try {
|
||||||
// 禁用Vue DevTools扩展
|
const isInitialized = await checkDatabaseInitialized();
|
||||||
/*
|
if (!isInitialized) {
|
||||||
if (isDevelopment && !process.env.IS_TEST) {
|
await initializeDatabase();
|
||||||
// Install Vue Devtools
|
|
||||||
try {
|
|
||||||
await installExtension(VUEJS_DEVTOOLS)
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Vue Devtools failed to install:', e.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 初始化配置相关的IPC处理程序
|
|
||||||
initConfigIpc(ipcMain);
|
|
||||||
// 初始化字典相关的IPC处理程序
|
|
||||||
initDictIpc(ipcMain);
|
|
||||||
// 初始化试题相关的IPC处理程序
|
|
||||||
initQuestionIpc(ipcMain);
|
|
||||||
// 初始化考试相关的IPC处理程序
|
|
||||||
initExamIpc(ipcMain);
|
|
||||||
// 初始化考生相关的IPC处理程序
|
|
||||||
initExamineeIpc(ipcMain);
|
|
||||||
// 初始化考生考试相关的IPC处理程序
|
|
||||||
initExamingIpc(ipcMain);
|
|
||||||
// 初始化文件相关的IPC处理程序
|
|
||||||
initFileIpc(ipcMain);
|
|
||||||
|
|
||||||
// 检查数据库是否初始化
|
|
||||||
try {
|
|
||||||
const isInitialized = await checkDatabaseInitialized();
|
|
||||||
if (!isInitialized) {
|
|
||||||
await initializeDatabase();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("数据库初始化失败:", error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加数据库初始化相关的IPC处理
|
|
||||||
ipcMain.handle('initialize-database', async (event) => {
|
|
||||||
try {
|
|
||||||
console.log('收到初始化数据库请求');
|
|
||||||
await initializeDatabase();
|
|
||||||
console.log('数据库初始化成功');
|
|
||||||
return { success: true };
|
|
||||||
} catch (error) {
|
|
||||||
console.error('数据库初始化失败:', error);
|
|
||||||
return { success: false, error: error.message };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.handle('check-database-initialized', async (event) => {
|
|
||||||
try {
|
|
||||||
return await checkDatabaseInitialized();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('检查数据库初始化状态失败:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查user.db是否存在的IPC处理
|
|
||||||
ipcMain.handle('checkUserDbExists', async (event) => {
|
|
||||||
try {
|
|
||||||
const userDbPath = getUserDbPath();
|
|
||||||
const exists = fs.existsSync(userDbPath);
|
|
||||||
console.log(`用户数据库检查结果: ${exists ? '存在' : '不存在'}`);
|
|
||||||
return exists;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('检查用户数据库失败:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 静默初始化用户数据库的IPC处理
|
|
||||||
ipcMain.handle('initializeUserDatabaseSilently', async (event) => {
|
|
||||||
try {
|
|
||||||
await initializeUserDatabase();
|
|
||||||
console.log('用户数据库静默初始化成功');
|
|
||||||
return { success: true };
|
|
||||||
} catch (error) {
|
|
||||||
console.error('用户数据库静默初始化失败:', error);
|
|
||||||
return { success: false, error: error.message };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检测是否为便携模式运行
|
|
||||||
try {
|
|
||||||
const isInitialized = await checkDatabaseInitialized();
|
|
||||||
console.log(`应用启动 - 数据库状态: ${isInitialized ? '已初始化' : '未初始化'}`);
|
|
||||||
createWindow();
|
|
||||||
} catch (error) {
|
|
||||||
console.error('检查数据库状态时出错:', error);
|
|
||||||
createWindow();
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('应用初始化失败:', error);
|
console.error("数据库初始化失败:", error);
|
||||||
dialog.showErrorBox('应用初始化失败', `无法初始化应用: ${error.message}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加数据库初始化相关的IPC处理
|
||||||
|
ipcMain.handle('initialize-database', async (event) => {
|
||||||
|
try {
|
||||||
|
console.log('收到初始化数据库请求');
|
||||||
|
await initializeDatabase();
|
||||||
|
console.log('数据库初始化成功');
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('数据库初始化失败:', error);
|
||||||
|
return { success: false, error: error.message };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('check-database-initialized', async (event) => {
|
||||||
|
try {
|
||||||
|
return await checkDatabaseInitialized();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查数据库初始化状态失败:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查user.db是否存在的IPC处理
|
||||||
|
ipcMain.handle('checkUserDbExists', async (event) => {
|
||||||
|
try {
|
||||||
|
const userDbPath = getUserDbPath();
|
||||||
|
const exists = fs.existsSync(userDbPath);
|
||||||
|
console.log(`用户数据库检查结果: ${exists ? '存在' : '不存在'}`);
|
||||||
|
return exists;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查用户数据库失败:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 静默初始化用户数据库的IPC处理
|
||||||
|
ipcMain.handle('initializeUserDatabaseSilently', async (event) => {
|
||||||
|
try {
|
||||||
|
await initializeUserDatabase();
|
||||||
|
console.log('用户数据库静默初始化成功');
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('用户数据库静默初始化失败:', error);
|
||||||
|
return { success: false, error: error.message };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检测是否为便携模式运行
|
||||||
|
createWindow();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Exit cleanly on request from parent process in development mode.
|
// Exit cleanly on request from parent process in development mode.
|
||||||
|
Loading…
Reference in New Issue
Block a user