1. 项目背景与核心需求
这个基于Web的师资管理系统是我去年为本地一所职业院校开发的毕业设计项目,也是我接手的第三个教育行业信息化系统。当时学校面临的主要问题是教师课程安排混乱、请假流程纸质化、排班信息不透明,导致教务管理效率低下。系统上线后,教务处的排课时间从原来的3天缩短到2小时,教师请假审批周期从平均48小时降到4小时以内。
系统采用B/S架构设计,主要包含四大功能模块:
- 课程信息管理:支持课程的新增、修改、查询和统计
- 排班管理:可视化排课界面+冲突检测算法
- 请假申请:电子化审批流程+课务自动调整
- 数据报表:自动生成教师工作量统计和课程分布分析
关键设计原则:所有功能必须支持200+教师同时在线操作,响应时间控制在1秒内,且要兼容学校现有的LDAP认证系统。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构选型解析
2.1 前端技术栈
采用Vue3+Element Plus组合,主要考虑因素:
- 学校现有管理员大多非技术背景,需要极低的学习成本
- 排课模块需要拖拽交互,Element Plus的Table组件支持最好
- 内置的ECharts能满足数据可视化需求
javascript复制// 典型排课组件实现
<template>
<el-table :data="scheduleData">
<el-table-column
v-for="day in workDays"
:key="day"
:label="day">
<template #default="{row}">
<draggable
:list="row[day]"
group="courses"
@change="handleScheduleChange">
<!-- 课程卡片实现 -->
</draggable>
</template>
</el-table-column>
</el-table>
</template>
2.2 后端技术栈
选择Spring Boot+MyBatis组合而非JPA的原因:
- 学校已有MySQL数据库,且DBA熟悉SQL优化
- 排课冲突检测需要复杂SQL查询(如下示例)
- 与学校OA系统对接需要灵活的结果集处理
sql复制/* 检测教师时间冲突的SQL */
SELECT COUNT(*) FROM schedule
WHERE teacher_id = #{teacherId}
AND day_of_week = #{day}
AND (
(start_time BETWEEN #{start} AND #{end})
OR (end_time BETWEEN #{start} AND #{end})
)
AND status != 'CANCELLED'
2.3 数据库设计要点
课程表核心字段设计:
sql复制CREATE TABLE `course_schedule` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`course_id` VARCHAR(20) NOT NULL COMMENT '课程编码',
`teacher_id` VARCHAR(10) NOT NULL COMMENT '工号',
`classroom_id` VARCHAR(10) NOT NULL COMMENT '教室编号',
`day_of_week` TINYINT NOT NULL COMMENT '1-7对应周一到周日',
`start_time` TIME NOT NULL COMMENT '开始时间',
`end_time` TIME NOT NULL COMMENT '结束时间',
`week_pattern` VARCHAR(20) NOT NULL DEFAULT '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16' COMMENT '生效周次',
INDEX `idx_teacher` (`teacher_id`),
INDEX `idx_time` (`day_of_week`,`start_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心功能实现细节
3.1 可视化排课模块
采用双层冲突检测机制:
- 前端实时检测:基于Timetable.js实现的可视化冲突提示
- 后端强校验:通过数据库事务确保数据一致性
java复制// 排课服务伪代码
@Transactional
public void arrangeCourse(CourseArrangement arrangement) {
// 检查教师时间冲突
if (scheduleMapper.checkTeacherConflict(arrangement) > 0) {
throw new ConflictException("教师时间冲突");
}
// 检查教室占用
if (scheduleMapper.checkClassroomConflict(arrangement) > 0) {
throw new ConflictException("教室已被占用");
}
// 写入排课记录
scheduleMapper.insert(arrangement);
// 同步到教师课表
teacherScheduleMapper.sync(arrangement);
}
3.2 请假审批流程
状态机设计:
mermaid复制stateDiagram-v2
[*] --> PENDING
PENDING --> APPROVED: 教研室主任审批
PENDING --> REJECTED
APPROVED --> PROCESSING: 教务处长审批
PROCESSING --> COMPLETED: 系统自动调课
PROCESSING --> CANCELLED: 撤销申请
实际采用工作流引擎时需要注意:
- 审批人动态获取(根据课程所属教研室)
- 自动调课要避开教师原有空闲时间
- 需要记录完整的操作日志
4. 安全防护方案
4.1 接口安全
- 采用JWT+RBAC权限控制
- 敏感操作(如删除课程)需要二次密码确认
- 所有表单提交增加CSRF Token
java复制// 权限拦截器示例
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
String token = request.getHeader("X-Auth-Token");
UserRole role = JwtUtil.parseRole(token);
// 获取请求路径对应的权限
String path = request.getRequestURI();
RequiredPermission perm = permissionMap.get(path);
if (!role.hasPermission(perm)) {
response.sendError(403);
return false;
}
return true;
}
}
4.2 数据安全
- 教师敏感信息(身份证号、银行卡等)加密存储
- 数据库定时备份+Binlog恢复机制
- 操作日志保留180天以上
5. 性能优化实践
5.1 排课列表优化
典型问题:当学期末查询所有教师的排课情况时,响应时间超过5秒
解决方案:
- 添加复合索引:
(teacher_id, day_of_week, start_time) - 引入二级缓存(Caffeine)
- 分页查询默认只加载本周数据
java复制@Cacheable(value = "teacherSchedule",
key = "#teacherId+'-'+#week",
unless = "#result == null || #result.isEmpty()")
public List<Schedule> queryByTeacher(String teacherId, int week) {
return scheduleMapper.selectByTeacher(teacherId, week);
}
5.2 批量导入优化
原始方案:每条记录单独插入 → 200条课程需要40秒
优化方案:
java复制// 使用MyBatis批量插入
@Transactional
public void batchImport(List<Course> courses) {
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
CourseMapper mapper = session.getMapper(CourseMapper.class);
for (Course course : courses) {
mapper.insert(course);
}
session.commit();
} finally {
session.close();
}
}
优化后200条记录仅需2.8秒
6. 部署实施要点
6.1 服务器配置建议
- 生产环境最低配置:
- 2核4G云服务器(排课高峰期CPU使用率约65%)
- MySQL 5.7+(必须开启查询缓存)
- Redis缓存服务(用于会话存储)
6.2 高可用方案
- 采用Nginx负载均衡(2个应用实例)
- 数据库主从复制
- 每日凌晨自动备份(保留最近7天)
7. 踩坑实录
-
时间格式问题:
- 坑:前端传'08:00'到后端变成'8:00'导致排课查询异常
- 解决:统一使用ISO8601格式传输时间
-
并发修改冲突:
- 场景:两个教务同时修改同一教师的排课
- 方案:增加乐观锁版本号控制
java复制@Update("UPDATE schedule SET ..., version=version+1
WHERE id=#{id} AND version=#{version}")
int updateWithVersion(Schedule schedule);
- 跨周排课BUG:
- 现象:第1周周五的课被错误地排到第2周
- 根因:周次计算未考虑学期起始日期
- 修复:引入学期日历配置表
8. 扩展建议
- 移动端适配:增加企业微信/钉钉集成
- 智能排课:基于遗传算法实现自动排课
- 教室利用率分析:热力图展示教室使用情况
- 对接考勤系统:通过教室摄像头实现自动考勤
实际开发中发现,教务人员最需要的不是复杂功能,而是清晰的操作指引和及时的系统反馈。建议在用户培训时重点演示:①如何快速查询某教师的所有课程 ②怎样处理调课冲突 ③请假后的自动课务调整规则
