// 辅助函数:将db.run包装为Promise export const runAsync = (db, sql, params = []) => { return new Promise((resolve, reject) => { db.run(sql, params, function (err) { if (err) reject(err); else resolve(this); }); }); }; // 系统数据库表结构 export const systemSchema = { config: ` CREATE TABLE IF NOT EXISTS config ( id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT NOT NULL, value TEXT NOT NULL, protected INTEGER DEFAULT 0 ); `, dictTypes: ` CREATE TABLE IF NOT EXISTS dict_types ( id INTEGER PRIMARY KEY AUTOINCREMENT, type_code TEXT NOT NULL UNIQUE, type_name TEXT NOT NULL, description TEXT, created_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, dictItems: ` CREATE TABLE IF NOT EXISTS dict_items ( id INTEGER PRIMARY KEY AUTOINCREMENT, type_code TEXT NOT NULL, item_code TEXT NOT NULL, item_name TEXT NOT NULL, item_description TEXT DEFAULT '', parent_code TEXT, is_active BOOLEAN DEFAULT 1, created_at TEXT DEFAULT CURRENT_TIMESTAMP, UNIQUE(type_code, item_code), FOREIGN KEY (type_code) REFERENCES dict_types(type_code) ); `, questions: ` CREATE TABLE IF NOT EXISTS questions ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_type TEXT NOT NULL, question_name TEXT NOT NULL DEFAULT '', question_description TEXT NOT NULL DEFAULT '', created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_type) REFERENCES dict_types(type_code) ); `, questionDatasets: ` CREATE TABLE IF NOT EXISTS question_datasets ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, dataset_name TEXT NOT NULL DEFAULT '', dataset_data TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_id) REFERENCES questions(id) ); `, questionImages: ` CREATE TABLE IF NOT EXISTS question_images ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, image_name TEXT NOT NULL DEFAULT '', image_base64 TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_id) REFERENCES questions(id) ); `, questionFillTable: ` CREATE TABLE IF NOT EXISTS question_fill_table ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, table_name TEXT NOT NULL DEFAULT '', table_data TEXT NOT NULL, table_description TEXT NOT NULL DEFAULT '', score REAL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_id) REFERENCES questions(id) ); `, questionFillTableBlanks: ` CREATE TABLE IF NOT EXISTS question_fill_table_blanks ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, table_id INTEGER NOT NULL, cell_position TEXT NOT NULL, cell_type TEXT NOT NULL DEFAULT 'number', correct_answer TEXT NOT NULL DEFAULT '', created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_id) REFERENCES questions(id), FOREIGN KEY (table_id) REFERENCES question_fill_table(id) ); `, questionChoices: ` CREATE TABLE IF NOT EXISTS question_choices ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, choice_description TEXT NOT NULL DEFAULT '', choice_type TEXT NOT NULL DEFAULT 'single', choice_options TEXT NOT NULL, correct_answers TEXT NOT NULL, score REAL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_id) REFERENCES questions(id) ); `, questionFillBlanks: ` CREATE TABLE IF NOT EXISTS question_fill_blanks ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, blank_description TEXT NOT NULL DEFAULT '', blank_count INTEGER NOT NULL DEFAULT 0, correct_answers TEXT NOT NULL DEFAULT '', score REAL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_id) REFERENCES questions(id) ); `, questionJudge: ` CREATE TABLE IF NOT EXISTS question_judge ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, judge_ask TEXT NOT NULL DEFAULT '', judge_answer INTEGER NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_id) REFERENCES questions(id) ); `, questionShort: ` CREATE TABLE IF NOT EXISTS question_short ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, short_ask TEXT NOT NULL DEFAULT '', short_answer_ref TEXT NOT NULL DEFAULT '', created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (question_id) REFERENCES questions(id) ); `, exam: ` CREATE TABLE IF NOT EXISTS exam ( id INTEGER PRIMARY KEY AUTOINCREMENT, exam_name TEXT NOT NULL DEFAULT '', exam_description TEXT NOT NULL DEFAULT '', exam_examinee_type TEXT NOT NULL DEFAULT '', exam_notice TEXT NOT NULL DEFAULT '', exam_minutes INTEGER NOT NULL DEFAULT 0, exam_minutes_min INTEGER NOT NULL DEFAULT 0, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, examinee: ` CREATE TABLE IF NOT EXISTS examinee ( id INTEGER PRIMARY KEY AUTOINCREMENT, examinee_name TEXT NOT NULL DEFAULT '', examinee_gender TEXT NOT NULL DEFAULT '', examinee_unit TEXT NOT NULL DEFAULT '', written_exam_room TEXT NOT NULL DEFAULT '', written_exam_seat TEXT NOT NULL DEFAULT '', computer_exam_room TEXT NOT NULL DEFAULT '', computer_exam_seat TEXT NOT NULL DEFAULT '', examinee_id_card TEXT NOT NULL DEFAULT '', examinee_admission_ticket TEXT NOT NULL DEFAULT '', created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, }; // 用户数据库表结构 export const userSchema = { examinee: ` CREATE TABLE IF NOT EXISTS examinee ( id INTEGER PRIMARY KEY AUTOINCREMENT, examinee_name TEXT NOT NULL DEFAULT '', examinee_gender TEXT NOT NULL DEFAULT '', examinee_unit TEXT NOT NULL DEFAULT '', written_exam_room TEXT NOT NULL DEFAULT '', written_exam_seat TEXT NOT NULL DEFAULT '', computer_exam_room TEXT NOT NULL DEFAULT '', computer_exam_seat TEXT NOT NULL DEFAULT '', examinee_id_card TEXT NOT NULL DEFAULT '', examinee_admission_ticket TEXT NOT NULL DEFAULT '', created_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, examinee_papers: ` CREATE TABLE IF NOT EXISTS examinee_papers ( id INTEGER PRIMARY KEY AUTOINCREMENT, examinee_id INTEGER NOT NULL, paper_minutes INTEGER NOT NULL DEFAULT 0, paper_minuts_min INTEGER NOT NULL DEFAULT 0, paper_start_time TEXT, paper_last_time TEXT, paper_submit_time TEXT, paper_end_time TEXT, paper_status INTEGER NOT NULL DEFAULT 0, -- 试卷状态:0未开始,1进行中,2已交卷 paper_score_real REAL DEFAULT 0, paper_score REAL DEFAULT 0, created_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, paper_questions: ` CREATE TABLE IF NOT EXISTS paper_questions ( id INTEGER PRIMARY KEY AUTOINCREMENT, examinee_id INTEGER NOT NULL, paper_id INTEGER NOT NULL, question_type TEXT NOT NULL, question_name TEXT NOT NULL DEFAULT '', question_description TEXT NOT NULL DEFAULT '', created_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, question_datasets: ` CREATE TABLE IF NOT EXISTS question_datasets ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, dataset_name TEXT NOT NULL DEFAULT '', dataset_data TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, question_images: ` CREATE TABLE IF NOT EXISTS question_images ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, image_name TEXT NOT NULL DEFAULT '', image_base64 TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, question_choices: ` CREATE TABLE IF NOT EXISTS question_choices ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, choice_description TEXT NOT NULL DEFAULT '', choice_type TEXT NOT NULL DEFAULT 'single', choice_options TEXT NOT NULL, correct_answers TEXT NOT NULL, examinee_answers TEXT NOT NULL DEFAULT '', score REAL, score_real REAL DEFAULT 0, -- 本题得分 created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP ); `, question_fill_blanks: ` CREATE TABLE IF NOT EXISTS question_fill_blanks ( id INTEGER PRIMARY KEY AUTOINCREMENT, question_id INTEGER NOT NULL, blank_description TEXT NOT NULL DEFAULT '', blank_count INTEGER NOT NULL DEFAULT 0, correct_answers TEXT NOT NULL DEFAULT '', examinee_answers TEXT NOT NULL DEFAULT '', score REAL, score_real REAL DEFAULT 0, -- 本题得分 created_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP ); ` }; // 初始化默认数据 // 系统配置默认数据 const plainPassword = "t2t6a9"; // 明文密码变量定义 // 注意:在实际初始化数据库时,需要使用argon2对plainPassword进行哈希 // 这里只定义默认数据结构,哈希操作应在index.js中的初始化函数中完成 export const defaultData = { config: [ { key: "admin_password", value: plainPassword, protected: 1 }, { key: "question_bank_version", value: "1", protected: 1 }, { key: "exam_version", value: "1", protected: 1 }, { key: "initialized", value: "1", protected: 1 }, ], // 字典类型默认数据 dictTypes: [ { type_code: "question_category", type_name: "题型分类", description: "用于区分客观题和主观题", }, { type_code: "question_type", type_name: "题型", description: "存储所有题型(选择题、填空题等)", }, { type_code: "user_role", type_name: "用户角色", description: "区分不同用户类型", }, ], // 字典项默认数据 dictItems: [ // 题型分类 { type_code: "question_category", item_code: "objective", item_name: "客观题", item_description: "有固定答案,机器可自动评分", is_active: 1, parent_code: null, }, { type_code: "question_category", item_code: "subjective", item_name: "主观题", item_description: "需人工评分,答案不唯一", is_active: 1, parent_code: null, }, // 题型 { type_code: "question_type", item_code: "choice", item_name: "选择题", item_description: "包含单选和多选", is_active: 1, parent_code: "objective", }, { type_code: "question_type", item_code: "fill_blank", item_name: "填空题", item_description: "填写空白处的答案", is_active: 1, parent_code: "objective", }, { type_code: "question_type", item_code: "fill_table", item_name: "填表题", item_description: "填写表格内容", is_active: 0, parent_code: "objective", }, { type_code: "question_type", item_code: "true_false", item_name: "判断题", item_description: "判断对错", is_active: 0, parent_code: "objective", }, { type_code: "question_type", item_code: "short_answer", item_name: "问答题", item_description: "简短回答问题", is_active: 0, parent_code: "subjective", }, { type_code: "question_type", item_code: "analysis", item_name: "分析题", item_description: "需要分析问题", is_active: 0, parent_code: "subjective", }, { type_code: "question_type", item_code: "essay", item_name: "论述题", item_description: "详细论述", is_active: 0, parent_code: "subjective", }, // 用户角色 { type_code: "user_role", item_code: "admin", item_name: "管理员", item_description: "系统管理员", is_active: 1, parent_code: null, }, { type_code: "user_role", item_code: "student", item_name: "考生", item_description: "参加考试的用户", is_active: 1, parent_code: null, }, ], };