405 lines
14 KiB
JavaScript
405 lines
14 KiB
JavaScript
// 辅助函数:将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,
|
||
},
|
||
],
|
||
};
|
||
|