// 将 CommonJS 导入改为 ES 模块导入(注意添加 .js 扩展名) import { getSystemDbPath, getUserDbPath } from './path.js'; import { systemSchema, userSchema, defaultData } from './schema.js'; import { openDatabase, batchInsert } from './utils.js'; import * as argon2 from "argon2"; // 数据库连接池 const dbConnections = new Map(); // 获取数据库连接 export async function getDbConnection(dbPath) { if (dbConnections.has(dbPath)) { console.log(`使用现有数据库连接: ${dbPath}`); return dbConnections.get(dbPath); } const db = await openDatabase(dbPath); dbConnections.set(dbPath, db); return db; } // 关闭所有数据库连接 export function closeAllConnections() { dbConnections.forEach((db, path) => { try { db.close(); console.log(`关闭数据库连接: ${path}`); } catch (error) { console.error(`关闭数据库连接失败: ${path}`, error); } }); dbConnections.clear(); } // 检查数据库是否已初始化 export async function checkDatabaseInitialized() { try { initializeUserDatabase(); console.log('开始检查数据库初始化状态...'); const systemDb = await getDbConnection(getSystemDbPath()); console.log('成功打开系统数据库'); const result = await systemDb.getAsync('SELECT value FROM config WHERE key = ?', ['initialized']); console.log('查询初始化状态结果:', result); const isInitialized = result && result.value === 'true'; console.log('数据库初始化状态:', isInitialized ? '已初始化' : '未初始化'); return isInitialized; } catch (error) { console.error('检查数据库初始化状态失败:', error); return false; } } // 初始化系统数据库 async function initializeSystemDatabase() { console.log('开始初始化系统数据库...'); const systemDbPath = getSystemDbPath(); const systemDb = await getDbConnection(systemDbPath); // 记录成功和失败的操作 const results = { success: [], failed: [] }; // 创建表结构 console.log('开始创建系统数据库表结构...'); // 创建config表 try { await systemDb.execAsync(systemSchema.config.trim()); console.log('创建 config 表成功'); results.success.push('创建 config 表'); } catch (error) { console.error('创建 config 表失败:', error); results.failed.push({ operation: '创建 config 表', error: error.message }); } // 创建dict_types表 try { await systemDb.execAsync(systemSchema.dictTypes.trim()); console.log('创建 dict_types 表成功'); results.success.push('创建 dict_types 表'); } catch (error) { console.error('创建 dict_types 表失败:', error); results.failed.push({ operation: '创建 dict_types 表', error: error.message }); } // 创建dict_items表 try { await systemDb.execAsync(systemSchema.dictItems.trim()); console.log('创建 dict_items 表成功'); results.success.push('创建 dict_items 表'); } catch (error) { console.error('创建 dict_items 表失败:', error); results.failed.push({ operation: '创建 dict_items 表', error: error.message }); } // 创建questions表 try { await systemDb.execAsync(systemSchema.questions.trim()); console.log('创建 questions 表成功'); results.success.push('创建 questions 表'); } catch (error) { console.error('创建 questions 表失败:', error); results.failed.push({ operation: '创建 questions 表', error: error.message }); } // 创建question_datasets表 try { await systemDb.execAsync(systemSchema.questionDatasets.trim()); console.log('创建 question_datasets 表成功'); results.success.push('创建 question_datasets 表'); } catch (error) { console.error('创建 question_datasets 表失败:', error); results.failed.push({ operation: '创建 question_datasets 表', error: error.message }); } // 创建question_images表 try { await systemDb.execAsync(systemSchema.questionImages.trim()); console.log('创建 question_images 表成功'); results.success.push('创建 question_images 表'); } catch (error) { console.error('创建 question_images 表失败:', error); results.failed.push({ operation: '创建 question_images 表', error: error.message }); } // 创建question_fill_table表 try { await systemDb.execAsync(systemSchema.questionFillTable.trim()); console.log('创建 question_fill_table 表成功'); results.success.push('创建 question_fill_table 表'); } catch (error) { console.error('创建 question_fill_table 表失败:', error); results.failed.push({ operation: '创建 question_fill_table 表', error: error.message }); } // 创建question_fill_table_blanks表 try { await systemDb.execAsync(systemSchema.questionFillTableBlanks.trim()); console.log('创建 question_fill_table_blanks 表成功'); results.success.push('创建 question_fill_table_blanks 表'); } catch (error) { console.error('创建 question_fill_table_blanks 表失败:', error); results.failed.push({ operation: '创建 question_fill_table_blanks 表', error: error.message }); } // 创建question_choices表 try { await systemDb.execAsync(systemSchema.questionChoices.trim()); console.log('创建 question_choices 表成功'); results.success.push('创建 question_choices 表'); } catch (error) { console.error('创建 question_choices 表失败:', error); results.failed.push({ operation: '创建 question_choices 表', error: error.message }); } // 创建question_fill_blanks表 try { await systemDb.execAsync(systemSchema.questionFillBlanks.trim()); console.log('创建 question_fill_blanks 表成功'); results.success.push('创建 question_fill_blanks 表'); } catch (error) { console.error('创建 question_fill_blanks 表失败:', error); results.failed.push({ operation: '创建 question_fill_blanks 表', error: error.message }); } // 创建question_judge表 try { await systemDb.execAsync(systemSchema.questionJudge.trim()); console.log('创建 question_judge 表成功'); results.success.push('创建 question_judge 表'); } catch (error) { console.error('创建 question_judge 表失败:', error); results.failed.push({ operation: '创建 question_judge 表', error: error.message }); } // 创建question_short表 try { await systemDb.execAsync(systemSchema.questionShort.trim()); console.log('创建 question_short 表成功'); results.success.push('创建 question_short 表'); } catch (error) { console.error('创建 question_short 表失败:', error); results.failed.push({ operation: '创建 question_short 表', error: error.message }); } // 创建exam表 try { await systemDb.execAsync(systemSchema.exam.trim()); console.log('创建 exam 表成功'); results.success.push('创建 exam 表'); } catch (error) { console.error('创建 exam 表失败:', error); results.failed.push({ operation: '创建 exam 表', error: error.message }); } // 创建examinee表 try { await systemDb.execAsync(systemSchema.examinee.trim()); console.log('创建 examinee 表成功'); results.success.push('创建 examinee 表'); } catch (error) { console.error('创建 examinee 表失败:', error); results.failed.push({ operation: '创建 examinee 表', error: error.message }); } // 插入默认数据 console.log('开始插入默认数据...'); // 处理密码哈希 try { const plainPassword = defaultData.config.find(item => item.key === 'admin_password').value; const hashedPassword = await argon2.hash(plainPassword); // 更新密码为哈希值 const configData = defaultData.config.map(item => { if (item.key === 'admin_password') { return { ...item, value: hashedPassword }; } return item; }); // 插入config表数据 try { await batchInsert(systemDb, 'config', configData); console.log('插入 config 表数据成功'); results.success.push('插入 config 表数据'); } catch (error) { console.error('插入 config 表数据失败:', error); results.failed.push({ operation: '插入 config 表数据', error: error.message }); } } catch (error) { console.error('处理密码哈希失败:', error); results.failed.push({ operation: '处理密码哈希', error: error.message }); } // 插入dict_types表数据 try { await batchInsert(systemDb, 'dict_types', defaultData.dictTypes); console.log('插入 dict_types 表数据成功'); results.success.push('插入 dict_types 表数据'); } catch (error) { console.error('插入 dict_types 表数据失败:', error); results.failed.push({ operation: '插入 dict_types 表数据', error: error.message }); } // 插入dict_items表数据 try { await batchInsert(systemDb, 'dict_items', defaultData.dictItems); console.log('插入 dict_items 表数据成功'); results.success.push('插入 dict_items 表数据'); } catch (error) { console.error('插入 dict_items 表数据失败:', error); results.failed.push({ operation: '插入 dict_items 表数据', error: error.message }); } console.log('系统数据库初始化结果:'); console.log('成功操作:', results.success); console.log('失败操作:', results.failed); // 如果有失败操作,抛出错误 if (results.failed.length > 0) { console.log(`系统数据库初始化有 ${results.failed.length} 个操作失败,请查看日志`); // 输出详细的失败信息 results.failed.forEach((item, index) => { console.log(`${index + 1}. ${item.operation} 失败: ${item.error}`); }); } return true; } // 初始化用户数据库 async function initializeUserDatabase() { console.log('开始初始化用户数据库...'); const userDbPath = getUserDbPath(); const userDb = await getDbConnection(userDbPath); // 记录成功和失败的操作 const results = { success: [], failed: [] }; // 创建表结构 console.log('开始创建用户数据库表结构...'); // 创建examinee表 try { await userDb.execAsync(userSchema.examinee.trim()); console.log('创建 examinee 表成功'); results.success.push('创建 examinee 表'); } catch (error) { console.error('创建 examinee 表失败:', error); results.failed.push({ operation: '创建 examinee 表', error: error.message }); } // 创建examinee_papers表 try { await userDb.execAsync(userSchema.examinee_papers.trim()); console.log('创建 examinee_papers 表成功'); results.success.push('创建 examinee_papers 表'); } catch (error) { console.error('创建 examinee_papers 表失败:', error); results.failed.push({ operation: '创建 examinee_papers 表', error: error.message }); } // 创建paper_questions表 try { await userDb.execAsync(userSchema.paper_questions.trim()); console.log('创建 paper_questions 表成功'); results.success.push('创建 paper_questions 表'); } catch (error) { console.error('创建 paper_questions 表失败:', error); results.failed.push({ operation: '创建 paper_questions 表', error: error.message }); } // 创建question_datasets表 try { await userDb.execAsync(userSchema.question_datasets.trim()); console.log('创建 question_datasets 表成功'); results.success.push('创建 question_datasets 表'); } catch (error) { console.error('创建 question_datasets 表失败:', error); results.failed.push({ operation: '创建 question_datasets 表', error: error.message }); } // 创建question_images表 try { await userDb.execAsync(userSchema.question_images.trim()); console.log('创建 question_images 表成功'); results.success.push('创建 question_images 表'); } catch (error) { console.error('创建 question_images 表失败:', error); results.failed.push({ operation: '创建 question_images 表', error: error.message }); } // 创建question_choices表 try { await userDb.execAsync(userSchema.question_choices.trim()); console.log('创建 question_choices 表成功'); results.success.push('创建 question_choices 表'); } catch (error) { console.error('创建 question_choices 表失败:', error); results.failed.push({ operation: '创建 question_choices 表', error: error.message }); } // 创建question_fill_blanks表 try { await userDb.execAsync(userSchema.question_fill_blanks.trim()); console.log('创建 question_fill_blanks 表成功'); results.success.push('创建 question_fill_blanks 表'); } catch (error) { console.error('创建 question_fill_blanks 表失败:', error); results.failed.push({ operation: '创建 question_fill_blanks 表', error: error.message }); } console.log('用户数据库初始化结果:'); console.log('成功操作:', results.success); console.log('失败操作:', results.failed); // 如果有失败操作,仅打印错误信息,不抛出异常 if (results.failed.length > 0) { console.error(`用户数据库初始化有 ${results.failed.length} 个操作失败,请查看日志`); // 输出详细的失败信息 results.failed.forEach((item, index) => { console.error(`${index + 1}. ${item.operation} 失败: ${item.error}`); }); } return true; } // 初始化数据库 export async function initializeDatabase() { try { console.log('开始初始化数据库...'); // 确保只有一个初始化请求在执行 if (global.isInitializing) { console.log('数据库初始化已在进行中,等待完成...'); while (global.isInitializing) { await new Promise(resolve => setTimeout(resolve, 100)); } return global.initResult; } global.isInitializing = true; global.initResult = false; // 先初始化系统数据库 console.log('开始初始化系统数据库...'); const systemResult = await initializeSystemDatabase(); console.log('系统数据库初始化结果:', systemResult ? '成功' : '失败'); if (!systemResult) { throw new Error('系统数据库初始化失败'); } // 再初始化用户数据库 console.log('开始初始化用户数据库...'); const userResult = await initializeUserDatabase(); console.log('用户数据库初始化结果:', userResult ? '成功' : '失败'); if (!userResult) { throw new Error('用户数据库初始化失败'); } // 更新初始化状态 console.log('更新数据库初始化状态...'); const systemDb = await getDbConnection(getSystemDbPath()); await systemDb.runAsync('UPDATE config SET value = ? WHERE key = ?', ['true', 'initialized']); console.log('数据库初始化状态更新成功'); console.log('数据库整体初始化成功'); global.initResult = true; return { success: true }; } catch (error) { console.error('数据库初始化失败:', error); global.initResult = false; return { success: false, error: error.message }; } finally { global.isInitializing = false; } } // 应用退出时关闭所有连接 process.on('exit', closeAllConnections);