exam11/background/db/index.js
2025-09-09 22:35:44 +08:00

403 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 systemDb = await exports.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 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);