refactor(database): 迁移到SQLite并清理旧MySQL相关代码

移除MySQL相关依赖和配置,完全迁移到SQLite数据库
删除不再需要的MySQL迁移脚本和备份文件
更新README文档说明新的数据库架构
在init_db.js中整合教师和系统设置表的初始化逻辑
This commit is contained in:
祀梦
2025-12-23 00:02:44 +08:00
parent 84d5840391
commit e63ef0af0a
13 changed files with 193 additions and 761 deletions

View File

@@ -28,6 +28,13 @@ const insertStudent = async (student) => {
);
};
const insertTeacher = async (teacher) => {
await run(
'INSERT INTO teachers (id, name, department, title, contact_info) VALUES (?, ?, ?, ?, ?)',
[teacher.id, teacher.name, teacher.department, teacher.title, teacher.contact_info]
);
};
const insertClass = async (cls) => {
return await run(
'INSERT INTO classes (class_name, grade, major, teacher_id) VALUES (?, ?, ?, ?)',
@@ -91,6 +98,8 @@ const init = async () => {
await run('DROP TABLE IF EXISTS students');
await run('DROP TABLE IF EXISTS users');
await run('DROP TABLE IF EXISTS operation_logs');
await run('DROP TABLE IF EXISTS system_settings');
await run('DROP TABLE IF EXISTS teachers');
// Create tables
console.log('创建表结构...');
@@ -174,8 +183,38 @@ const init = async () => {
)
`);
await run(`
CREATE TABLE teachers (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
department TEXT,
title TEXT,
contact_info TEXT,
FOREIGN KEY (id) REFERENCES users(id) ON DELETE CASCADE
)
`);
await run(`
CREATE TABLE system_settings (
key TEXT PRIMARY KEY,
value TEXT
)
`);
console.log('生成基础数据...');
// 0. System Settings
const defaultSettings = [
['system_name', '学校成绩管理系统'],
['current_semester', '2023-2024-2'],
['allow_course_selection', '1'],
['allow_grade_check', '1']
];
for (const [key, value] of defaultSettings) {
await run('INSERT OR IGNORE INTO system_settings (key, value) VALUES (?, ?)', [key, value]);
}
// 1. Admin
await insertUser({
id: 'admin',
@@ -187,9 +226,16 @@ const init = async () => {
// 2. Teachers (20 teachers)
const teachers = [];
const departments = ['计算机学院', '软件学院', '信息工程学院', '理学院', '外国语学院'];
const titles = ['教授', '副教授', '讲师', '助教'];
for (let i = 1; i <= 20; i++) {
const id = `T${1000 + i}`;
const name = `教师${String.fromCharCode(65 + (i % 26))}${i}`;
const dept = departments[i % departments.length];
const title = titles[i % titles.length];
const contact = `139${Math.floor(Math.random() * 90000000 + 10000000)}`;
await insertUser({
id,
name,
@@ -197,6 +243,15 @@ const init = async () => {
role: 'teacher',
class: null
});
await insertTeacher({
id,
name,
department: dept,
title: title,
contact_info: contact
});
teachers.push(id);
}

View File

@@ -13,9 +13,7 @@
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"express-mysql-session": "^3.0.0",
"express-session": "^1.17.3",
"mysql2": "^3.6.0",
"sqlite3": "^5.1.7"
},
"devDependencies": {

View File

@@ -1,31 +0,0 @@
const db = require('../config/database');
async function fixTeachers() {
const departments = ['计算机学院', '软件学院', '信息工程学院', '理学院', '外国语学院'];
const titles = ['教授', '副教授', '讲师', '助教'];
try {
const teachers = await db.query('SELECT id FROM teachers');
for (let i = 0; i < teachers.length; i++) {
const dept = departments[i % departments.length];
const title = titles[i % titles.length];
const contact = `139${Math.floor(Math.random() * 90000000 + 10000000)}`;
await db.query(
'UPDATE teachers SET department = ?, title = ?, contact_info = ? WHERE id = ?',
[dept, title, contact, teachers[i].id]
);
// Also sync back to users table's class field if needed (though we'll use teachers table now)
await db.query(
'UPDATE users SET class = ? WHERE id = ?',
[dept, teachers[i].id]
);
}
console.log('教师信息修复完成!');
} catch (err) {
console.error('修复失败:', err);
}
}
fixTeachers();

View File

@@ -1,48 +0,0 @@
const db = require('../config/database');
async function migrate() {
try {
console.log('Starting migration v2...');
// 1. System Settings Table
await db.query(`
CREATE TABLE IF NOT EXISTS system_settings (
key TEXT PRIMARY KEY,
value TEXT
)
`);
// Default settings
const defaultSettings = [
['system_name', '学校成绩管理系统'],
['current_semester', '2023-2024-2'],
['allow_course_selection', '1'],
['allow_grade_check', '1']
];
for (const [key, value] of defaultSettings) {
await db.query('INSERT OR IGNORE INTO system_settings (key, value) VALUES (?, ?)', [key, value]);
}
// 2. Operation Logs Table
await db.query(`
CREATE TABLE IF NOT EXISTS operation_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT,
operation_type TEXT,
operation_target TEXT,
description TEXT,
ip_address TEXT,
created_at TEXT DEFAULT (datetime('now', 'localtime'))
)
`);
console.log('Migration v2 completed successfully.');
process.exit(0);
} catch (error) {
console.error('Migration v2 failed:', error);
process.exit(1);
}
}
migrate();

View File

@@ -1,33 +0,0 @@
const db = require('../config/database');
async function migrate() {
console.log('开始执行 v3 迁移: 创建 teachers 表...');
try {
await db.query(`
CREATE TABLE IF NOT EXISTS teachers (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
department TEXT,
title TEXT,
contact_info TEXT,
FOREIGN KEY (id) REFERENCES users(id) ON DELETE CASCADE
)
`);
// 从 users 表中迁移现有的教师数据
const teachers = await db.query('SELECT id, name, class FROM users WHERE role = "teacher"');
for (const t of teachers) {
await db.query(
'INSERT OR IGNORE INTO teachers (id, name, department) VALUES (?, ?, ?)',
[t.id, t.name, t.class]
);
}
console.log('v3 迁移成功!');
} catch (err) {
console.error('v3 迁移失败:', err);
}
}
migrate();

View File

@@ -1,7 +1,6 @@
const express = require('express');
const cors = require('cors');
const session = require('express-session');
// const MySQLStore = require('express-mysql-session')(session);
const path = require('path');
require('dotenv').config();
@@ -27,26 +26,9 @@ app.use(cors({
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Session
/*
const sessionStore = new MySQLStore({
expiration: 86400000,
createDatabaseTable: true,
schema: {
tableName: 'sessions',
columnNames: {
session_id: 'session_id',
expires: 'expires',
data: 'data'
}
}
}, db.pool);
*/
app.use(session({
key: 'session_cookie',
secret: process.env.SESSION_SECRET || 'your-secret-key',
// store: sessionStore, // Use MemoryStore for SQLite migration simplification
resave: false,
saveUninitialized: false,
cookie: {