Files
hzdyjs/docs/设计文档/database/学工管理-学生信息管理/05-batch-views-and-procedures.sql
T
2025-07-19 10:18:27 +08:00

220 lines
7.3 KiB
SQL

-- 第一阶段:创建批次相关的视图和存储过程
-- 说明:用于简化查询和批量操作
-- 1. 创建视图:当前活跃批次
CREATE VIEW v_current_active_batch AS
SELECT
b.*,
COUNT(bs.id) as total_students,
SUM(CASE WHEN bs.has_submitted = 1 THEN 1 ELSE 0 END) as submitted_students,
ROUND(SUM(CASE WHEN bs.has_submitted = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(bs.id), 2) as completion_rate
FROM xg_collection_batch b
LEFT JOIN xg_collection_batch_student bs ON b.id = bs.batch_id AND bs.deleted = 0
WHERE b.deleted = 0
AND b.status = 'active'
AND b.is_published = 1
AND NOW() BETWEEN b.start_time AND b.end_time
GROUP BY b.id;
-- 2. 创建视图:学生批次权限
CREATE VIEW v_student_batch_permission AS
SELECT
bs.student_id,
bs.student_code,
bs.student_name,
b.id as batch_id,
b.batch_name,
b.batch_code,
b.start_time,
b.end_time,
b.status as batch_status,
bs.can_edit,
bs.has_submitted,
bs.submit_time,
CASE
WHEN b.status != 'active' THEN 0
WHEN b.is_published != 1 THEN 0
WHEN NOW() < b.start_time THEN 0
WHEN NOW() > b.end_time THEN 0
WHEN bs.can_edit != 1 THEN 0
WHEN bs.has_submitted = 1 THEN 0
ELSE 1
END as can_edit_now
FROM xg_collection_batch_student bs
JOIN xg_collection_batch b ON bs.batch_id = b.id
WHERE bs.deleted = 0 AND b.deleted = 0;
-- 3. 创建存储过程:批量生成批次学生关联
DELIMITER //
CREATE PROCEDURE sp_generate_batch_students(
IN p_batch_id BIGINT,
IN p_target_grade VARCHAR(50),
IN p_target_college_ids TEXT,
IN p_target_major_ids TEXT,
IN p_target_class_ids TEXT,
IN p_creator_id BIGINT
)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE v_student_id BIGINT;
DECLARE v_student_code VARCHAR(50);
DECLARE v_student_name VARCHAR(100);
DECLARE v_college_id BIGINT;
DECLARE v_college_name VARCHAR(100);
DECLARE v_major_id BIGINT;
DECLARE v_major_name VARCHAR(100);
DECLARE v_class_id BIGINT;
DECLARE v_class_name VARCHAR(100);
DECLARE v_grade VARCHAR(50);
-- 构建条件SQL
SET @sql = CONCAT('
SELECT
s.id, s.student_code, s.student_name,
s.college_id, c.college_name,
s.major_id, m.major_name,
s.class_id, cl.class_name,
s.grade
FROM xg_student_info s
LEFT JOIN xg_college c ON s.college_id = c.id
LEFT JOIN xg_major m ON s.major_id = m.id
LEFT JOIN xg_class_info cl ON s.class_id = cl.id
WHERE s.deleted = 0'
);
-- 添加届别条件
IF p_target_grade IS NOT NULL AND p_target_grade != '' THEN
SET @sql = CONCAT(@sql, ' AND s.grade = ''', p_target_grade, '''');
END IF;
-- 添加学院条件
IF p_target_college_ids IS NOT NULL AND p_target_college_ids != '' THEN
SET @sql = CONCAT(@sql, ' AND FIND_IN_SET(s.college_id, ''', p_target_college_ids, ''')');
END IF;
-- 添加专业条件
IF p_target_major_ids IS NOT NULL AND p_target_major_ids != '' THEN
SET @sql = CONCAT(@sql, ' AND FIND_IN_SET(s.major_id, ''', p_target_major_ids, ''')');
END IF;
-- 添加班级条件
IF p_target_class_ids IS NOT NULL AND p_target_class_ids != '' THEN
SET @sql = CONCAT(@sql, ' AND FIND_IN_SET(s.class_id, ''', p_target_class_ids, ''')');
END IF;
-- 清空该批次的现有学生关联
DELETE FROM xg_collection_batch_student WHERE batch_id = p_batch_id;
-- 准备插入语句
SET @insert_sql = CONCAT('
INSERT INTO xg_collection_batch_student (
batch_id, student_id, student_code, student_name,
college_id, college_name, major_id, major_name,
class_id, class_name, grade, can_edit, has_submitted,
create_by, tenant_id
) ', @sql, ' AND s.id NOT IN (
SELECT student_id FROM xg_collection_batch_student
WHERE batch_id = ', p_batch_id, ' AND deleted = 0
)');
-- 替换SELECT为INSERT VALUES
SET @insert_sql = REPLACE(@insert_sql, 'SELECT ', CONCAT('SELECT ', p_batch_id, ', '));
SET @insert_sql = CONCAT(@insert_sql, ', 1, 0, ', p_creator_id, ', 0');
-- 执行插入
PREPARE stmt FROM @insert_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 记录日志
INSERT INTO xg_collection_batch_log (
batch_id, operation_type, operation_desc,
operator_id, operator_type, create_time
) VALUES (
p_batch_id, 'BATCH_GENERATE',
CONCAT('批量生成批次学生关联,条件:届别=', IFNULL(p_target_grade, 'ALL'),
',学院=', IFNULL(p_target_college_ids, 'ALL'),
',专业=', IFNULL(p_target_major_ids, 'ALL'),
',班级=', IFNULL(p_target_class_ids, 'ALL')),
p_creator_id, 'ADMIN', NOW()
);
END //
DELIMITER ;
-- 4. 创建存储过程:检查学生是否可以编辑信息
DELIMITER //
CREATE PROCEDURE sp_check_student_can_edit(
IN p_student_id BIGINT,
OUT p_can_edit TINYINT,
OUT p_batch_id BIGINT,
OUT p_message VARCHAR(500)
)
BEGIN
DECLARE v_batch_count INT DEFAULT 0;
DECLARE v_batch_id BIGINT;
DECLARE v_batch_name VARCHAR(200);
DECLARE v_start_time DATETIME;
DECLARE v_end_time DATETIME;
DECLARE v_can_edit TINYINT DEFAULT 0;
DECLARE v_has_submitted TINYINT DEFAULT 0;
-- 初始化输出参数
SET p_can_edit = 0;
SET p_batch_id = NULL;
SET p_message = '';
-- 查找当前活跃的批次中是否包含该学生
SELECT COUNT(*), MAX(b.id), MAX(b.batch_name), MAX(b.start_time), MAX(b.end_time)
INTO v_batch_count, v_batch_id, v_batch_name, v_start_time, v_end_time
FROM xg_collection_batch b
JOIN xg_collection_batch_student bs ON b.id = bs.batch_id
WHERE bs.student_id = p_student_id
AND b.deleted = 0
AND bs.deleted = 0
AND b.status = 'active'
AND b.is_published = 1
AND NOW() BETWEEN b.start_time AND b.end_time;
IF v_batch_count = 0 THEN
SET p_message = '当前没有开放的信息采集批次';
LEAVE proc_label;
END IF;
-- 检查学生在该批次中的权限
SELECT can_edit, has_submitted
INTO v_can_edit, v_has_submitted
FROM xg_collection_batch_student
WHERE batch_id = v_batch_id AND student_id = p_student_id AND deleted = 0;
IF v_can_edit = 0 THEN
SET p_message = '您没有编辑权限';
LEAVE proc_label;
END IF;
IF v_has_submitted = 1 THEN
SET p_message = '您已经提交过信息,无法再次编辑';
LEAVE proc_label;
END IF;
-- 检查时间范围
IF NOW() < v_start_time THEN
SET p_message = CONCAT('信息采集尚未开始,开始时间:', DATE_FORMAT(v_start_time, '%Y-%m-%d %H:%i:%s'));
LEAVE proc_label;
END IF;
IF NOW() > v_end_time THEN
SET p_message = CONCAT('信息采集已结束,结束时间:', DATE_FORMAT(v_end_time, '%Y-%m-%d %H:%i:%s'));
LEAVE proc_label;
END IF;
-- 所有检查通过
SET p_can_edit = 1;
SET p_batch_id = v_batch_id;
SET p_message = CONCAT('可以编辑信息,批次:', v_batch_name);
proc_label: BEGIN END;
END //
DELIMITER ;
-- 验证创建
SELECT 'Views and procedures created!' as message;