// 添加缺失的导入 const { getSystemDbPath, getUserDbPath } = require('./path.js'); const { systemSchema, userSchema, defaultData } = require('./schema.js'); const { openDatabase, batchInsert } = require('./utils.js'); const bcrypt = require('bcryptjs'); // 数据库连接池 const dbConnections = new Map(); // 获取数据库连接 exports.getDbConnection = 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; }; // 关闭所有数据库连接 exports.closeAllConnections = function closeAllConnections() { dbConnections.forEach((db, path) => { try { db.close(); console.log(`关闭数据库连接: ${path}`); } catch (error) { console.error(`关闭数据库连接失败: ${path}`, error); } }); dbConnections.clear(); }; // 检查数据库是否已初始化 exports.checkDatabaseInitialized = async function checkDatabaseInitialized() { try { console.log('开始检查数据库初始化状态...'); const systemDbPath = getSystemDbPath(); console.log('系统数据库路径:', systemDbPath); // 首先检查数据库文件是否存在 const fs = require('fs'); const dbExists = fs.existsSync(systemDbPath); console.log('系统数据库文件存在:', dbExists); if (!dbExists) { console.log('系统数据库文件不存在,返回未初始化状态'); return false; } // 检查文件大小,如果是空文件则认为未初始化 const stats = fs.statSync(systemDbPath); if (stats.size === 0) { console.log('系统数据库文件为空,返回未初始化状态'); return false; } // 尝试打开数据库连接 const systemDb = await exports.getDbConnection(systemDbPath); console.log('成功打开系统数据库'); try { // 尝试查询config表 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 (queryError) { // 如果查询失败,可能是表不存在,说明数据库未初始化 console.log('查询config表失败,可能表不存在:', queryError.message); // 尝试检查数据库是否有表结构 try { const tables = await systemDb.allAsync("SELECT name FROM sqlite_master WHERE type='table'"); console.log('数据库中的表:', tables.map(t => t.name).join(', ')); // 如果有表但没有config表,可能是结构不完整 if (tables.length > 0) { console.log('数据库有表结构但可能不完整,需要重新初始化'); return false; } } catch (tablesError) { console.error('检查数据库表结构失败:', tablesError); } return false; } } catch (error) { console.error('检查数据库初始化状态失败:', error); return false; } }; // 初始化系统数据库 async function initializeSystemDatabase() { console.log('开始初始化系统数据库...'); const systemDbPath = getSystemDbPath(); const systemDb = await exports.getDbConnection(systemDbPath); // 创建表结构 console.log('开始创建系统数据库表结构...'); // 创建config表 try { await systemDb.execAsync(systemSchema.config.trim()); console.log('创建 config 表成功'); } catch (error) { console.error('创建 config 表失败:', error); } // 创建dict_types表 try { await systemDb.execAsync(systemSchema.dict_types.trim()); console.log('创建 dict_types 表成功'); } catch (error) { console.error('创建 dict_types 表失败:', error); } // 创建dict_items表 try { await systemDb.execAsync(systemSchema.dict_items.trim()); console.log('创建 dict_items 表成功'); } catch (error) { console.error('创建 dict_items 表失败:', error); } // 创建questions表 try { await systemDb.execAsync(systemSchema.questions.trim()); console.log('创建 questions 表成功'); } catch (error) { console.error('创建 questions 表失败:', error); } // 创建question_datasets表 try { await systemDb.execAsync(systemSchema.question_datasets.trim()); console.log('创建 question_datasets 表成功'); } catch (error) { console.error('创建 question_datasets 表失败:', error); } // 创建question_images表 try { await systemDb.execAsync(systemSchema.question_images.trim()); console.log('创建 question_images 表成功'); } catch (error) { console.error('创建 question_images 表失败:', error); } // 创建question_fill_table表 try { await systemDb.execAsync(systemSchema.question_fill_table.trim()); console.log('创建 question_fill_table 表成功'); } catch (error) { console.error('创建 question_fill_table 表失败:', error); } // 创建question_fill_table_blanks表 try { await systemDb.execAsync(systemSchema.question_fill_table_blanks.trim()); console.log('创建 question_fill_table_blanks 表成功'); } catch (error) { console.error('创建 question_fill_table_blanks 表失败:', error); } // 创建question_choices表 try { await systemDb.execAsync(systemSchema.question_choices.trim()); console.log('创建 question_choices 表成功'); } catch (error) { console.error('创建 question_choices 表失败:', error); } // 创建question_fill_blanks表 try { await systemDb.execAsync(systemSchema.question_fill_blanks.trim()); console.log('创建 question_fill_blanks 表成功'); } catch (error) { console.error('创建 question_fill_blanks 表失败:', error); } // 创建question_judge表 try { await systemDb.execAsync(systemSchema.question_judge.trim()); console.log('创建 question_judge 表成功'); } catch (error) { console.error('创建 question_judge 表失败:', error); } // 创建question_short表 try { await systemDb.execAsync(systemSchema.question_short.trim()); console.log('创建 question_short 表成功'); } catch (error) { console.error('创建 question_short 表失败:', error); } // 创建exam表 try { await systemDb.execAsync(systemSchema.exam.trim()); console.log('创建 exam 表成功'); } catch (error) { console.error('创建 exam 表失败:', error); } // 创建examinee表(系统库中的考生表) try { await systemDb.execAsync(systemSchema.examinee.trim()); console.log('创建 examinee 表成功'); } catch (error) { console.error('创建 examinee 表失败:', error); } // 插入默认数据 try { console.log('开始插入默认数据...'); // 插入admin用户 const adminPasswordHash = await bcrypt.hash('123456', 10); await systemDb.runAsync( 'INSERT INTO examinee (id_card, name, role, password) VALUES (?, ?, ?, ?)', ['admin', '管理员', 'admin', adminPasswordHash] ); console.log('插入管理员用户成功'); // 插入config表数据 await systemDb.runAsync( 'INSERT OR IGNORE INTO config (key, value, description) VALUES (?, ?, ?)', ['initialized', 'false', '数据库初始化状态'] ); console.log('插入config表数据成功'); // 批量插入dict_types数据 const dictTypes = defaultData.dictTypes; for (const type of dictTypes) { await systemDb.runAsync( 'INSERT INTO dict_types (code, name, description, sort_order) VALUES (?, ?, ?, ?)', [type.code, type.name, type.description, type.sortOrder] ); } console.log('插入dict_types表数据成功'); // 批量插入dict_items数据 const dictItems = defaultData.dictItems; for (const item of dictItems) { await systemDb.runAsync( 'INSERT INTO dict_items (type_code, code, name, description, sort_order, is_active, parent_code) VALUES (?, ?, ?, ?, ?, ?, ?)', [ item.typeCode, item.code, item.name, item.description, item.sortOrder, item.isActive ? 1 : 0, item.parentCode ] ); } console.log('插入dict_items表数据成功'); console.log('默认数据插入完成'); } catch (error) { console.error('插入默认数据失败:', error); } return { success: true }; } // 初始化用户数据库 - 注意这里使用了exports导出 exports.initializeUserDatabase = async function initializeUserDatabase() { console.log('开始初始化用户数据库...'); const userDbPath = getUserDbPath(); const userDb = await exports.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 }); } // 创建question_judge表 try { await userDb.execAsync(userSchema.question_judge.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 userDb.execAsync(userSchema.question_short.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 }); } // 创建question_fill_table表 try { await userDb.execAsync(userSchema.question_fill_table.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 userDb.execAsync(userSchema.question_fill_table_blanks.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 }); } console.log('用户数据库表结构创建完成'); console.log('成功操作:', results.success.length); console.log('失败操作:', results.failed.length); if (results.failed.length > 0) { console.error('部分操作失败:', results.failed); } return { success: true, results }; }; // 初始化数据库 exports.initializeDatabase = async function initializeDatabase() { // 防止并发初始化 if (global.isInitializing) { console.log('数据库初始化正在进行中,请勿重复触发'); return { success: false, message: '数据库初始化正在进行中' }; } global.isInitializing = true; try { // 初始化系统数据库 console.log('开始数据库整体初始化...'); const systemResult = await initializeSystemDatabase(); if (!systemResult.success) { throw new Error('系统数据库初始化失败'); } // 初始化用户数据库 const userResult = await exports.initializeUserDatabase(); if (!userResult.success) { throw new Error('用户数据库初始化失败'); } // 更新初始化状态 console.log('更新数据库初始化状态...'); const systemDb = await exports.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', exports.closeAllConnections);