v0.1测试

This commit is contained in:
2026-04-07 17:07:13 +08:00
parent 593973f598
commit 6b1b586fe3
80 changed files with 9073 additions and 32 deletions

331
sql/init.sql Normal file
View File

@@ -0,0 +1,331 @@
-- ===========================================
-- 班级操行分管理系统 - 数据库初始化脚本
-- ===========================================
-- 开发者: Canglan
-- 联系方式: admin@sea-studio.top
-- 版权归属: Sea Network Technology Studio
-- 许可证: MIT License
-- 版权所有: Copyright (c) 2024 Sea Network Technology Studio
-- ===========================================
-- 数据库: classmanagerdb
-- 字符集: utf8mb4
-- ===========================================
-- 创建数据库(如果不存在)
CREATE DATABASE IF NOT EXISTS `classmanagerdb`
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE `classmanagerdb`;
-- ===========================================
-- 1. 班级表
-- ===========================================
DROP TABLE IF EXISTS `classes`;
CREATE TABLE `classes` (
`class_id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '班级ID',
`class_name` VARCHAR(50) NOT NULL COMMENT '班级名称',
`grade` VARCHAR(20) DEFAULT NULL COMMENT '年级',
`academic_year` VARCHAR(20) DEFAULT NULL COMMENT '学年',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX `idx_class_name` (`class_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='班级表';
-- ===========================================
-- 2. 科目表(支持动态增删)
-- ===========================================
DROP TABLE IF EXISTS `subjects`;
CREATE TABLE `subjects` (
`subject_id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '科目ID',
`subject_name` VARCHAR(50) NOT NULL COMMENT '科目名称',
`subject_code` VARCHAR(20) DEFAULT NULL COMMENT '科目代码',
`is_active` TINYINT DEFAULT 1 COMMENT '是否启用0禁用/1启用',
`sort_order` INT DEFAULT 0 COMMENT '排序序号',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX `idx_active` (`is_active`),
UNIQUE KEY `uk_subject_name` (`subject_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='科目表';
-- ===========================================
-- 3. 学生表
-- ===========================================
DROP TABLE IF EXISTS `students`;
CREATE TABLE `students` (
`student_id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '学生ID',
`student_no` VARCHAR(20) NOT NULL COMMENT '学号',
`name` VARCHAR(50) NOT NULL COMMENT '学生姓名',
`class_id` INT NOT NULL COMMENT '班级ID',
`total_points` INT DEFAULT 100 COMMENT '操行分总分',
`parent_phone` VARCHAR(20) DEFAULT NULL COMMENT '家长手机号',
`status` TINYINT DEFAULT 1 COMMENT '状态0离校/1在校',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
FOREIGN KEY (`class_id`) REFERENCES `classes`(`class_id`) ON DELETE RESTRICT,
UNIQUE KEY `uk_student_no` (`student_no`),
INDEX `idx_class_id` (`class_id`),
INDEX `idx_parent_phone` (`parent_phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='学生表';
-- ===========================================
-- 4. 用户表(统一账号)
-- ===========================================
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`user_id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',
`username` VARCHAR(50) NOT NULL COMMENT '登录账号',
`password_hash` VARCHAR(64) NOT NULL COMMENT '密码哈希SHA1+MD5',
`real_name` VARCHAR(50) NOT NULL COMMENT '真实姓名',
`user_type` ENUM('student', 'parent', 'admin') NOT NULL COMMENT '用户类型',
`student_id` INT DEFAULT NULL COMMENT '关联学生ID学生/家长)',
`status` TINYINT DEFAULT 1 COMMENT '状态0禁用/1启用',
`need_change_password` TINYINT DEFAULT 1 COMMENT '是否需要修改密码1需要/0不需要',
`last_login_time` DATETIME DEFAULT NULL COMMENT '最后登录时间',
`last_login_ip` VARCHAR(45) DEFAULT NULL COMMENT '最后登录IP',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
UNIQUE KEY `uk_username` (`username`),
INDEX `idx_user_type` (`user_type`),
INDEX `idx_student_id` (`student_id`),
FOREIGN KEY (`student_id`) REFERENCES `students`(`student_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
-- ===========================================
-- 5. 管理员角色表
-- ===========================================
DROP TABLE IF EXISTS `admin_roles`;
CREATE TABLE `admin_roles` (
`admin_role_id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '管理员角色ID',
`user_id` INT NOT NULL COMMENT '用户ID',
`role_type` ENUM('班主任', '班长', '科代表', '考勤委员', '劳动委员') NOT NULL COMMENT '角色类型',
`class_id` INT NOT NULL COMMENT '管理的班级ID',
`subject_id` INT DEFAULT NULL COMMENT '关联科目ID科代表专用',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE,
FOREIGN KEY (`class_id`) REFERENCES `classes`(`class_id`) ON DELETE CASCADE,
FOREIGN KEY (`subject_id`) REFERENCES `subjects`(`subject_id`) ON DELETE CASCADE,
INDEX `idx_user_id` (`user_id`),
INDEX `idx_role_type` (`role_type`),
UNIQUE KEY `uk_user_class_subject` (`user_id`, `class_id`, `subject_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='管理员角色表';
-- ===========================================
-- 6. 操行分记录表
-- ===========================================
DROP TABLE IF EXISTS `conduct_records`;
CREATE TABLE `conduct_records` (
`record_id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '记录ID',
`student_id` INT NOT NULL COMMENT '学生ID',
`points_change` INT NOT NULL COMMENT '分数变动(正数加分,负数扣分)',
`reason` VARCHAR(255) NOT NULL COMMENT '变动原因',
`recorder_id` INT NOT NULL COMMENT '操作人ID',
`recorder_name` VARCHAR(50) DEFAULT NULL COMMENT '操作人姓名(冗余字段)',
`related_type` ENUM('manual', 'homework', 'attendance') DEFAULT 'manual' COMMENT '关联类型',
`related_id` INT DEFAULT NULL COMMENT '关联ID作业ID/考勤ID',
`is_revoked` TINYINT DEFAULT 0 COMMENT '是否已撤销0未撤销/1已撤销',
`revoked_by` INT DEFAULT NULL COMMENT '撤销人ID',
`revoked_at` DATETIME DEFAULT NULL COMMENT '撤销时间',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
FOREIGN KEY (`student_id`) REFERENCES `students`(`student_id`) ON DELETE CASCADE,
FOREIGN KEY (`recorder_id`) REFERENCES `users`(`user_id`) ON DELETE RESTRICT,
FOREIGN KEY (`revoked_by`) REFERENCES `users`(`user_id`) ON DELETE RESTRICT,
INDEX `idx_student_id` (`student_id`),
INDEX `idx_recorder_id` (`recorder_id`),
INDEX `idx_created_at` (`created_at`),
INDEX `idx_related` (`related_type`, `related_id`),
INDEX `idx_is_revoked` (`is_revoked`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='操行分记录表';
-- ===========================================
-- 7. 作业表
-- ===========================================
DROP TABLE IF EXISTS `assignments`;
CREATE TABLE `assignments` (
`assignment_id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '作业ID',
`class_id` INT NOT NULL COMMENT '班级ID',
`subject_id` INT NOT NULL COMMENT '科目ID',
`title` VARCHAR(100) NOT NULL COMMENT '作业标题',
`description` TEXT COMMENT '作业描述',
`deadline` DATE NOT NULL COMMENT '截止日期',
`created_by` INT NOT NULL COMMENT '发布人ID',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
FOREIGN KEY (`class_id`) REFERENCES `classes`(`class_id`) ON DELETE CASCADE,
FOREIGN KEY (`subject_id`) REFERENCES `subjects`(`subject_id`) ON DELETE RESTRICT,
FOREIGN KEY (`created_by`) REFERENCES `users`(`user_id`) ON DELETE RESTRICT,
INDEX `idx_class_id` (`class_id`),
INDEX `idx_deadline` (`deadline`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='作业表';
-- ===========================================
-- 8. 作业提交记录表
-- ===========================================
DROP TABLE IF EXISTS `homework_submissions`;
CREATE TABLE `homework_submissions` (
`submission_id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '提交记录ID',
`assignment_id` INT NOT NULL COMMENT '作业ID',
`student_id` INT NOT NULL COMMENT '学生ID',
`status` ENUM('submitted', 'not_submitted', 'late') DEFAULT 'not_submitted' COMMENT '提交状态',
`submit_time` DATETIME DEFAULT NULL COMMENT '提交时间',
`comments` TEXT COMMENT '备注',
`deduction_applied` TINYINT DEFAULT 0 COMMENT '是否已应用扣分',
`deduction_record_id` BIGINT DEFAULT NULL COMMENT '关联的扣分记录ID',
`updated_by` INT DEFAULT NULL COMMENT '最后更新人ID',
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
FOREIGN KEY (`assignment_id`) REFERENCES `assignments`(`assignment_id`) ON DELETE CASCADE,
FOREIGN KEY (`student_id`) REFERENCES `students`(`student_id`) ON DELETE CASCADE,
FOREIGN KEY (`updated_by`) REFERENCES `users`(`user_id`) ON DELETE RESTRICT,
FOREIGN KEY (`deduction_record_id`) REFERENCES `conduct_records`(`record_id`) ON DELETE SET NULL,
INDEX `idx_assignment_id` (`assignment_id`),
INDEX `idx_student_id` (`student_id`),
INDEX `idx_status` (`status`),
UNIQUE KEY `uk_assignment_student` (`assignment_id`, `student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='作业提交记录表';
-- ===========================================
-- 9. 考勤记录表
-- ===========================================
DROP TABLE IF EXISTS `attendance_records`;
CREATE TABLE `attendance_records` (
`attendance_id` INT PRIMARY KEY AUTO_INCREMENT COMMENT '考勤记录ID',
`student_id` INT NOT NULL COMMENT '学生ID',
`date` DATE NOT NULL COMMENT '考勤日期',
`status` ENUM('present', 'absent', 'late', 'leave') DEFAULT 'present' COMMENT '考勤状态',
`reason` VARCHAR(255) DEFAULT NULL COMMENT '原因',
`recorder_id` INT NOT NULL COMMENT '记录人ID',
`deduction_applied` TINYINT DEFAULT 0 COMMENT '是否已应用扣分',
`deduction_record_id` BIGINT DEFAULT NULL COMMENT '关联的扣分记录ID',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
FOREIGN KEY (`student_id`) REFERENCES `students`(`student_id`) ON DELETE CASCADE,
FOREIGN KEY (`recorder_id`) REFERENCES `users`(`user_id`) ON DELETE RESTRICT,
FOREIGN KEY (`deduction_record_id`) REFERENCES `conduct_records`(`record_id`) ON DELETE SET NULL,
INDEX `idx_student_id` (`student_id`),
INDEX `idx_date` (`date`),
INDEX `idx_status` (`status`),
UNIQUE KEY `uk_student_date` (`student_id`, `date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='考勤记录表';
-- ===========================================
-- 10. 操作日志表
-- ===========================================
DROP TABLE IF EXISTS `operation_logs`;
CREATE TABLE `operation_logs` (
`log_id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID',
`operator_id` INT NOT NULL COMMENT '操作人ID',
`operator_name` VARCHAR(50) DEFAULT NULL COMMENT '操作人姓名',
`operator_role` VARCHAR(50) DEFAULT NULL COMMENT '操作人角色',
`operation_type` VARCHAR(50) NOT NULL COMMENT '操作类型',
`target_type` VARCHAR(50) DEFAULT NULL COMMENT '目标类型',
`target_id` INT DEFAULT NULL COMMENT '目标ID',
`details` TEXT COMMENT '详细信息',
`ip_address` VARCHAR(45) DEFAULT NULL COMMENT 'IP地址',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX `idx_operator_id` (`operator_id`),
INDEX `idx_operation_type` (`operation_type`),
INDEX `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='操作日志表';
-- ===========================================
-- 11. 登录日志表
-- ===========================================
DROP TABLE IF EXISTS `login_logs`;
CREATE TABLE `login_logs` (
`log_id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID',
`username` VARCHAR(50) NOT NULL COMMENT '登录账号',
`login_result` TINYINT NOT NULL COMMENT '登录结果0失败/1成功',
`fail_reason` VARCHAR(100) DEFAULT NULL COMMENT '失败原因',
`ip_address` VARCHAR(45) DEFAULT NULL COMMENT 'IP地址',
`user_agent` VARCHAR(255) DEFAULT NULL COMMENT '用户代理',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX `idx_username` (`username`),
INDEX `idx_created_at` (`created_at`),
INDEX `idx_login_result` (`login_result`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='登录日志表';
-- ===========================================
-- 创建存储过程:撤销扣分记录
-- ===========================================
DROP PROCEDURE IF EXISTS `revoke_conduct_record`;
DELIMITER //
CREATE PROCEDURE `revoke_conduct_record`(
IN p_record_id BIGINT,
IN p_revoker_id INT
)
BEGIN
DECLARE v_student_id INT;
DECLARE v_points_change INT;
DECLARE v_is_revoked TINYINT;
SELECT `student_id`, `points_change`, `is_revoked`
INTO v_student_id, v_points_change, v_is_revoked
FROM `conduct_records`
WHERE `record_id` = p_record_id;
IF v_is_revoked = 1 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '该记录已被撤销';
END IF;
UPDATE `conduct_records`
SET `is_revoked` = 1,
`revoked_by` = p_revoker_id,
`revoked_at` = NOW()
WHERE `record_id` = p_record_id;
UPDATE `students`
SET `total_points` = `total_points` - v_points_change
WHERE `student_id` = v_student_id;
END //
DELIMITER ;
-- ===========================================
-- 创建触发器:更新学生总分
-- ===========================================
DROP TRIGGER IF EXISTS `update_student_points_on_insert`;
DELIMITER //
CREATE TRIGGER `update_student_points_on_insert`
AFTER INSERT ON `conduct_records`
FOR EACH ROW
BEGIN
IF NEW.is_revoked = 0 THEN
UPDATE `students`
SET `total_points` = `total_points` + NEW.points_change
WHERE `student_id` = NEW.student_id;
END IF;
END //
DELIMITER ;
-- ===========================================
-- 创建视图:学生操行分排行榜
-- ===========================================
DROP VIEW IF EXISTS `v_student_ranking`;
CREATE VIEW `v_student_ranking` AS
SELECT
s.student_id,
s.student_no,
s.name,
c.class_name,
s.total_points,
RANK() OVER (PARTITION BY s.class_id ORDER BY s.total_points DESC) as rank_in_class
FROM `students` s
JOIN `classes` c ON s.class_id = c.class_id
WHERE s.status = 1;
-- ===========================================
-- 创建视图:今日考勤汇总
-- ===========================================
DROP VIEW IF EXISTS `v_today_attendance`;
CREATE VIEW `v_today_attendance` AS
SELECT
c.class_name,
COUNT(CASE WHEN a.status = 'present' THEN 1 END) as present_count,
COUNT(CASE WHEN a.status = 'absent' THEN 1 END) as absent_count,
COUNT(CASE WHEN a.status = 'late' THEN 1 END) as late_count,
COUNT(CASE WHEN a.status = 'leave' THEN 1 END) as leave_count,
COUNT(*) as total_count
FROM `attendance_records` a
JOIN `students` s ON a.student_id = s.student_id
JOIN `classes` c ON s.class_id = c.class_id
WHERE a.date = CURDATE()
GROUP BY c.class_id;