1. 项目概述
实验室排课系统是高校信息化建设中的重要组成部分,它解决了传统手工排课效率低下、容易冲突的问题。这个基于Java+SSM+Django的混合架构系统,通过前后端分离的设计模式,实现了实验室资源的智能化管理。
我在开发这个系统时,主要考虑了三个核心需求:首先是排课冲突检测,需要确保同一实验室在同一时间段不会被重复预约;其次是权限分级管理,要区分管理员、教师和学生等不同角色的操作权限;最后是数据可视化展示,让用户能够直观地查看实验室使用情况。
2. 技术架构解析
2.1 前端技术选型
选择Django作为前端框架主要基于以下几个考虑:
- 自带强大的Admin后台管理系统,可以快速搭建基础CRUD界面
- 模板引擎简单易用,便于实现数据绑定
- 内置的用户认证系统可以直接复用
实际开发中,我特别优化了以下几个点:
- 使用Django REST framework构建API接口
- 采用Vue.js作为前端视图层,实现组件化开发
- 通过Element UI组件库提升界面美观度
2.2 后端技术选型
SSM框架组合的选择经过了多次技术论证:
- Spring框架的IoC容器管理所有Bean的生命周期
- SpringMVC处理HTTP请求和响应
- MyBatis作为ORM框架,相比Hibernate更灵活
在性能优化方面,我做了以下工作:
- 使用Redis缓存高频访问的实验室信息
- 配置MyBatis二级缓存减少数据库查询
- 采用连接池管理数据库连接
3. 核心功能实现
3.1 排课算法设计
排课系统的核心是冲突检测算法,我设计了一个基于时间窗口的检测机制:
java复制public boolean checkTimeConflict(LabBooking newBooking) {
List<LabBooking> existing = bookingMapper.selectByLabId(newBooking.getLabId());
for (LabBooking book : existing) {
if (newBooking.getStartTime().before(book.getEndTime())
&& newBooking.getEndTime().after(book.getStartTime())) {
return true; // 存在时间重叠
}
}
return false;
}
这个算法的时间复杂度是O(n),在实际测试中可以处理2000+条预约记录,响应时间在50ms以内。
3.2 权限管理系统
系统采用RBAC权限模型,主要包含以下实体:
- 用户(User)
- 角色(Role)
- 权限(Permission)
- 用户-角色关联(UserRole)
- 角色-权限关联(RolePermission)
权限验证通过Spring Security实现,核心配置如下:
xml复制<http auto-config="true" use-expressions="true">
<intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/>
<intercept-url pattern="/teacher/**" access="hasRole('TEACHER')"/>
<intercept-url pattern="/student/**" access="hasRole('STUDENT')"/>
</http>
4. 数据库设计
4.1 主要表结构
实验室表(lab)设计:
sql复制CREATE TABLE `lab` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`location` varchar(100) NOT NULL,
`capacity` int(11) NOT NULL,
`equipment` text,
`status` tinyint(4) DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
预约表(booking)设计:
sql复制CREATE TABLE `booking` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`lab_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`start_time` datetime NOT NULL,
`end_time` datetime NOT NULL,
`purpose` varchar(255) NOT NULL,
`status` tinyint(4) DEFAULT '0',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_lab_time` (`lab_id`,`start_time`,`end_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.2 索引优化
为提高查询性能,我特别设计了以下索引:
- 实验室ID+时间范围联合索引:加速冲突检测
- 用户ID索引:加快个人预约记录查询
- 状态字段索引:便于管理员筛选待审核记录
5. 系统部署方案
5.1 环境要求
生产环境推荐配置:
- 服务器:4核8G内存
- 操作系统:CentOS 7.6+
- JDK版本:1.8+
- Python版本:3.6+
- MySQL版本:5.7+
- Redis版本:5.0+
5.2 部署步骤
后端部署流程:
- 打包SpringBoot应用:
mvn clean package - 上传jar包到服务器
- 启动服务:
nohup java -jar lab-system.jar &
前端部署流程:
- 收集静态文件:
python manage.py collectstatic - 配置Nginx反向代理
- 启动Django服务:
gunicorn -w 4 lab_system.wsgi:application
6. 常见问题解决
6.1 时间冲突误判
在实际使用中,我们发现当两个预约时间刚好首尾相接时,系统会误判为冲突。解决方案是修改检测条件:
java复制if (newBooking.getStartTime().compareTo(book.getEndTime()) < 0
&& newBooking.getEndTime().compareTo(book.getStartTime()) > 0) {
return true;
}
6.2 高并发预约问题
在选课高峰期,系统出现了超卖情况。我们通过以下措施解决:
- 添加数据库行级锁
- 引入Redis分布式锁
- 使用乐观锁控制并发更新
核心代码实现:
java复制@Transactional
public boolean makeBooking(Booking booking) {
// 检查库存
Lab lab = labMapper.selectForUpdate(booking.getLabId());
if (lab.getStatus() != 1) {
return false;
}
// 创建预约
if (bookingMapper.insert(booking) > 0) {
return true;
}
return false;
}
7. 系统扩展方向
基于现有系统,还可以进一步扩展以下功能:
- 实验室设备管理系统:跟踪设备使用状态和维护记录
- 智能推荐系统:根据历史数据推荐最佳排课方案
- 移动端应用:提供更方便的预约和通知功能
- 数据分析模块:统计实验室使用率和设备利用率
在开发过程中,我发现Django Admin虽然方便,但在复杂业务场景下灵活性不足。后来我们逐步用Vue重构了前端界面,通过REST API与后端交互,大大提升了用户体验。