electron-vue-exam-single/electron/main.js

431 lines
11 KiB
JavaScript

// 确保所有导入都使用 ES 模块语法
import { app, BrowserWindow, ipcMain } from 'electron';
import path from 'path';
import { fileURLToPath } from 'url';
import { checkDatabaseInitialized, initializeDatabase } from './db/index.js';
// 导入配置项服务
import {
fetchAllConfigs,
fetchConfigById,
saveConfig,
removeConfig,
getSystemConfig,
updateSystemConfig,
increaseQuestionBankVersion,
initAuthIpc
} from './service/configService.js';
// 导入字典服务 - 使用实际导出的函数名称
import {
fetchDictTypes,
fetchDictItemsByTypeCode,
createDictType,
modifyDictType,
removeDictType,
createDictItem,
modifyDictItem,
removeDictItem,
fetchDictItemsWithTypes,
checkDictParentCode, // 添加这一行
checkDictChildReferences // 添加这一行
} from './service/dictService.js';
// 导入题干服务
import {
createQuestion,
fetchAllQuestions,
fetchQuestionById,
modifyQuestion,
removeQuestion,
fetchAllQuestionsWithRelations,
modifyQuestionDescription,
createChoiceQuestion // 添加新函数导入
} from './service/questionService.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({
fullscreen: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true
}
})
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:5173/')
mainWindow.webContents.openDevTools()
} else {
mainWindow.loadFile(path.join(__dirname, '../dist/index.html'))
}
// 当窗口关闭时,清空引用
mainWindow.on('closed', () => {
mainWindow = null;
});
}
// Initalize app
app.whenReady().then(() => {
setupApp()
createWindow()
setupIpcMain()
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// 只有当没有窗口时才创建新窗口
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
// Check database initialization status
async function setupApp() {
try {
console.log('应用启动 - 检查数据库初始化状态...');
// 使用全局变量防止重复初始化检查
if (global.dbInitCheck) {
console.log('数据库初始化检查已完成');
return;
}
global.dbInitCheck = true;
const isInitialized = await checkDatabaseInitialized();
console.log('数据库初始化状态:', isInitialized);
// 只检查状态,不自动初始化
} catch (error) {
console.error('数据库检查过程中出错:', error);
}
}
// Setup IPC communication
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;
}
});
// 系统相关
ipcMain.handle('system-get-config', async () => {
try {
return await getSystemConfig();
} catch (error) {
console.error('Failed to get system config:', error);
return null;
}
});
ipcMain.handle('system-update-config', async (event, config) => {
try {
return await updateSystemConfig(config);
} catch (error) {
console.error('Failed to update system config:', error);
return false;
}
});
ipcMain.handle('system-increase-question-band-version', async () => {
try {
return await increaseQuestionBankVersion();
} catch (error) {
console.error('Failed to increase question band version:', error);
return false;
}
});
// 初始化认证相关IPC
initAuthIpc(ipcMain);
// 配置项管理相关IPC
ipcMain.handle('config-fetch-all', async () => {
try {
return await fetchAllConfigs();
} catch (error) {
console.error('Failed to fetch all configs:', error);
throw error;
}
});
ipcMain.handle('config-fetch-by-id', async (event, id) => {
try {
return await fetchConfigById(id);
} catch (error) {
console.error(`Failed to fetch config by id ${id}:`, error);
throw error;
}
});
ipcMain.handle('config-save', async (event, { key, value }) => {
try {
await saveConfig(key, value);
return true;
} catch (error) {
console.error(`Failed to save config ${key}:`, error);
throw error;
}
});
ipcMain.handle('config-delete', async (event, id) => {
try {
await removeConfig(id);
return true;
} catch (error) {
console.error(`Failed to delete config ${id}:`, error);
throw error;
}
});
// 字典管理相关IPC - 使用正确的函数名称
ipcMain.handle('dict-fetch-types', async () => {
try {
return await fetchDictTypes();
} catch (error) {
console.error('Failed to fetch dict types:', error);
throw error;
}
});
ipcMain.handle('dict-fetch-items-by-type', async (event, typeCode, isActive = undefined) => {
try {
return await fetchDictItemsByTypeCode(typeCode, isActive);
} catch (error) {
console.error(`Failed to fetch dict items by type ${typeCode}:`, error);
throw error;
}
});
ipcMain.handle('dict-create-type', async (event, dictType) => {
try {
return await createDictType(dictType);
} catch (error) {
console.error('Failed to create dict type:', error);
throw error;
}
});
// 将 updateDictType 改为 modifyDictType
ipcMain.handle('dict-update-type', async (event, dictType) => {
try {
return await modifyDictType(dictType.id, dictType);
} catch (error) {
console.error('Failed to update dict type:', error);
throw error;
}
});
// 将 deleteDictType 改为 removeDictType
ipcMain.handle('dict-delete-type', async (event, typeCode) => {
try {
return await removeDictType(typeCode);
} catch (error) {
console.error(`Failed to delete dict type ${typeCode}:`, error);
throw error;
}
});
ipcMain.handle('dict-create-item', async (event, dictItem) => {
try {
return await createDictItem(dictItem);
} catch (error) {
console.error('Failed to create dict item:', error);
throw error;
}
});
// 将 updateDictItem 改为 modifyDictItem
ipcMain.handle('dict-update-item', async (event, dictItem) => {
try {
return await modifyDictItem(dictItem.id, dictItem);
} catch (error) {
console.error('Failed to update dict item:', error);
throw error;
}
});
// 将 deleteDictItem 改为 removeDictItem
ipcMain.handle('dict-delete-item', async (event, id) => {
try {
return await removeDictItem(id);
} catch (error) {
console.error(`Failed to delete dict item ${id}:`, error);
throw error;
}
});
// 将 fetchAllDictItemsWithTypes 改为 fetchDictItemsWithTypes
ipcMain.handle('dict-fetch-all-items-with-types', async () => {
try {
return await fetchDictItemsWithTypes();
} catch (error) {
console.error('Failed to fetch all dict items with types:', error);
throw error;
}
});
// 添加在setupIpcMain函数中
// 检查parent_code是否存在
ipcMain.handle('dict-check-parent-code', async (event, parentCode) => {
try {
return await checkDictParentCode(parentCode); // 修改这一行
} catch (error) {
console.error('检查parent_code失败:', error);
throw error;
}
});
// 检查是否有子引用
ipcMain.handle('dict-check-child-references', async (event, itemCode) => {
try {
return await checkDictChildReferences(itemCode); // 修改这一行
} catch (error) {
console.error('检查子引用失败:', error);
throw error;
}
});
// 题干管理相关IPC
ipcMain.handle('question-create', async (event, questionData) => {
try {
return await createQuestion(questionData);
} catch (error) {
console.error('Failed to create question:', error);
throw error;
}
});
ipcMain.handle('question-fetch-all', async () => {
try {
return await fetchAllQuestions();
} catch (error) {
console.error('Failed to fetch questions:', error);
throw error;
}
});
ipcMain.handle('question-fetch-by-id', async (event, id) => {
try {
return await fetchQuestionById(id);
} catch (error) {
console.error(`Failed to fetch question by id ${id}:`, error);
throw error;
}
});
ipcMain.handle('question-update', async (event, id, questionData) => {
try {
return await modifyQuestion(id, questionData);
} catch (error) {
console.error('Failed to update question:', error);
throw error;
}
});
ipcMain.handle('question-delete', async (event, id) => {
try {
return await removeQuestion(id);
} catch (error) {
console.error(`Failed to delete question ${id}:`, error);
throw error;
}
});
// 在已有的 question 相关 IPC 处理程序区域添加
ipcMain.handle('question-fetch-all-with-relations', async (event) => {
try {
return await fetchAllQuestionsWithRelations();
} catch (error) {
console.error('Failed to fetch all questions with relations:', error);
throw error;
}
});
// 添加更新题干描述的 IPC 处理程序
ipcMain.handle('question-update-description', async (event, id, questionDescription) => {
try {
return await modifyQuestionDescription(id, questionDescription);
} catch (error) {
console.error('Failed to update question description:', error);
throw error;
}
});
// 添加选择题问题的IPC处理程序
ipcMain.handle('question-create-choice', async (event, choiceData) => {
try {
return await createChoiceQuestion(choiceData);
} catch (error) {
console.error('Failed to create choice question:', error);
throw error;
}
});
}
// 确保在 app.whenReady() 中调用 setupIpcMain()
app.whenReady().then(() => {
setupApp()
createWindow()
setupIpcMain()
});
// 删除下面这段重复的代码
// app.whenReady().then(() => {
// setupApp()
// createWindow()
// setupIpcMain()
// });
// 在应用退出前关闭所有数据库连接
app.on('will-quit', () => {
console.log('应用即将退出...');
// closeAllConnections();
});