题目名称: 自动排课系统
姓 名 谢晓艳
专 业 物联网工程
本课题是自动排课系统,整个系统分为B/S结构的教师与教务管理员登录功能、排课功能、课程管理功能、教室管理功能、教师管理功能。
登录模块:在C/S结构中,登入系统有对角色的分类与合法性的验证,并且根据不同的类型角色分配不同的权限。
排课模块:可根据分课记录进行自动排课,可查看课表。
管理模块:专业管理、班级管理、课程管理、教师管理、教室管理、分课管理。
系统应包含以下功能模块:
(1)系统管理:用户管理、菜单管理、角色管理
(2)教学系统:专业管理、班级管理、课程管理、教师管理、教室管理、分课管理。
(3)排课管理:能够根据限定条件进行自动排课,生成课表。
(4)输出管理:实现对班级、教师的课表进行查询和打印。
随着计算机技术的飞速发展,特别是计算机的应用已普及到经济和社会生活的各个领域,使原本的旧的管理方法越来越不适应现在社会的发展。许多人还停留在以前的手工操作,这大大地阻碍了人类经济的发展,为了适应现代社会人们高度强烈的时间观念,利用计算机实现高校排课系统势在必行。对于各大高校来说,利用计算机支持学校管理员排课,是适应现代学校的制度要求、推动学校管理走向科学化、系统化、规范化的必要条件,从而达到提高校管理效率的目的。
排课的实质是给教学计划中设置的课程安排合适的时问和地点,保证教学工作能够顺利地进行。排课工作也是一项复杂的工作,排课是一个NP问题,始终找不到一个最优的方法能够解决的问题,因为这个问题涉及了多种因素进行组合规划,有教师、学生的因素,也有教室的因素。尤其在目前各高校规模不断扩大,教学资源面临紧张,教师总数不足的前提下,排课工作问题更为凸出。
Vue
Vue 是一套用于构建用户界面的渐进式 JavaScript 框架 ,开发者只需要关注视图层, 它不仅易于上手,还便于与第三方库或既有项目的整合。是基于MVVM(Model-View-ViewModel 即:视图层-视图模型层-模型层)设计思想。
ElementUI
element 是基于 vue 实现的一套不依赖业务的 UI 组件库,提供了丰富的PC端组件,减少用户对常用组件的封装,降低了开发的难易程度。
Axios
Axios,是一个基于promise的网络请求库,作用于node.js和浏览器中,它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生node.js http模块, 而在客户端 (浏览端) 则使用XMLHttpRequest。
ECharts
ECharts,全称Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,能够流畅的运行在PC以及移动设备上,兼容当前绝大部分浏览器。为我们许多提供直观,生动,可交互,可高度个性化定制的数据可视化图表。ECharts 能够支持折线图、柱状图、散点图、K线图、饼图、雷达图、和弦图、力导向布局图、地图、仪表盘、漏斗图、事件河流图等12类图表,同时提供标题,详情气泡、图例、值域、数据区域、时间轴、工具箱等7个可交 互组件,支持多图表、组件的联动和混搭展现。
Maven
Apache Maven是一个(特别是Java编程)项目管理及自动构建工具,由Apache软件基金会所提供。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。当你使用Maven的时候,你用一个明确定义的项目对象模型来描述你的项目,然后Maven可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义的)插件。Maven特性:依赖管理系统、多模块构建、一致的项目结构、一致的构建模型和插件机制
SpringBoot
SpringBoot是目前后端开发中,比较流行的开发框架。SpringBoot 不会像传统spring一样需要繁琐的配置和整合第三方框架的配置。Springboot集成了大量的常用的第三方库配置,spingboot应用中这些第三方库几乎可以说是零配置开箱即用。大部分的springboot应用都只需求非常少的配置代码,这能然开发者更专注与业务逻辑的开发。
Mybaits Plus
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。Mybatis-Plus(简称MP)是 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
Mysql
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,它分为社区版和商业版,其体积小、速度快、总体拥有成本低,并且开源.
Nacos
Nacos 是阿里巴巴推出来的一个新开源项目,这是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助发现、配置和管理微服务,且提供了一组简单易用的特性集,帮助更快速实现动态服务发现、服务配置、服务元数据及流量管理,帮助更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。Nacos 的关键特性包括:服务发现和服务健康监测、动态配置服务、动态 DNS服务、服务及其元数据管理。
Gateway
Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
Redis
Redis是完全开源免费的,遵守BSD协议,是一种支持key-value等多种数据结构的存储系统。可用于缓存,事件发布或订阅,高速队列等场景。支持网络,提供字符串,哈希,列表,队列,集合结构直接存取,基于内存,可持久化。Redis 与其他 key - value 缓存产品有以下特点:Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。Redis支持数据的备份,即master-slave模式的数据备份。Redis 优势:性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
图 3-1总体架构图
图 3-2总体设计图
该系统包括两大子系统,一为系统管理,二为教学系统。系统管理包括:用户管理、菜单管理、角色管理等功能。教学系统包括:专业管理、班级管理、课程管理、教师管理、教室管理、分课管理、排课与课表查询等其他功能。
系统管理功能分析:
教学系统功能分析:
src:源代码文件
├──main:主要代码
│ ├──java:主要代码
│ │ ├──com/mingyuean/university/teaching:主要代码
│ │ │ ├──aop:切面
│ │ │ ├──config:配置类
│ │ │ ├──controller:控制层
│ │ │ ├──dao:dao层
│ │ │ ├──entity:实体类
│ │ │ ├──exception:异常处理
│ │ │ ├──feign:远程调用
│ │ │ ├──service:业务层
│ │ │ ├──utils:通用
│ └── resources:资源文件
│ │ ├──mapper/teaching:mapper.xml文件
│ │ ├──src/views/modules/teaching:前端vue文件
└── test:测试代码
用例图(英语:use case diagram)是用户与系统交互的最简表示形式,展现了用户和与他相关的用例之间的关系。通过用例图,人们可以获知系统不同种类的用户和用例。
该系统中总共有四种角色,不同的角色有着不同的权限,有着不同的功能,现对该系统中的四种角色即学生、教师、教学系统管理员、超级管理员进行分析。
图 4-1总体用例图
图 4-2数据库E-R图
专业管理数据表设计
表 1专业字段表
字段 | 名称 | 类型 | 是否必须 |
---|---|---|---|
id | 序号 | bigint | true |
professional_name | 名字 | varchar(255) | true |
professional_code | 编码 | varchar(255) | true |
professional_type | 专业类型 | varchar(20) | true |
班级管理数据
表 2班级字段表
字段 | 名称 | 类型 | 是否必须 |
---|---|---|---|
id | 序号 | bigint | true |
classes_name | 名字 | varchar(255) | true |
classes_number | 人数 | int | true |
classes_week_max | 每周课程上限 | int | true |
professional_id | 专业id | bigint | true |
课程管理数据表设计
表 3课程字段表
字段 | 名称 | 类型 | 是否必须 |
---|---|---|---|
id | 序号 | bigint | true |
course_name | 名字 | varchar(255) | true |
course_book | 教材 | varchar(255) | true |
course_type | 课程类型 | varchar(20) | true |
教师管理数据表设计
表 4教师字段表
字段 | 名称 | 类型 | 是否必须 |
---|---|---|---|
id | 序号 | bigint | true |
teacher_name | 姓名 | varchar(100) | true |
teacher_telephone | 电话 | varchar(100) | true |
teacher_week_max | 每周课程上限 | int | true |
教室管理数据表设计
表 5教室字段表
字段 | 名称 | 类型 | 是否必须 |
---|---|---|---|
id | 序号 | bigint | true |
classroom_name | 名字 | varchar(255) | true |
classroom_size | 教室大小 | int | true |
classroom_type | 教室类型 | varchar(20) | true |
分课管理数据表设计
表 6分课字段表
字段 | 名称 | 类型 | 是否必须 |
---|---|---|---|
id | 序号 | bigint | true |
classes_id | 班级id | bigint | true |
course_id | 课程id | bigint | true |
teacher_id | 教师id | bigint | true |
week_number | 星期 课 ABCDE 01 | varchar(255) | true |
classroom_id | 随机分配教室id | bigint | true |
(1)功能描述:可以通过专业信息实现对专业的增删改查。list是查询专业方法,info是根据id查询专业方法,save是添加专业方法,update是修改专业方法,delete是删除专业方法。
因为添加班级时,需要添加专业门类,专业门类共有十二类,即理学、工学、文学、法学、农学、医学、哲学、管理学、教育学、历史学、经济学、艺术学,为方便前端添加专业时选择专业门类需要一个查询所有专业门类的方法即findType。因为在数据库设计时,班级表中存在专业id字段,为方便前端添加班级时选择专业需要一个查询所有专业的方法即findAll。
(2)类图:
图 5-1专业控制层类图
(3)重点代码说明:
现对查询所有专业门类代码进行说明,ProfessionalType是一个枚举,list是枚举转换而来的,resMap是需要返回的数据,循环遍历枚举类转换的list,获取枚举中的TypeName和TypeCode,将获取到的值存入map中,将map添加到resMap中。
public R findType() {
final List <ProfessionalType> list = Arrays.asList(ProfessionalType.values());
List <Map<String, java.io.Serializable>> resMap = new ArrayList <>();
for(int i=0;i<list.size();i++) {
String name= list.get(i).getTypeName();
String code= list.get(i).getTypeCode();
Map <String, java.io.Serializable > map = new HashMap <String, java.io.Serializable>();
map.put("id",i);
map.put("code",code);
map.put("name",name);
map.put("value",code);
map.put("text",name);
resMap.add(map);
}
return R.ok().put("professionalTypeList", resMap);
}
(1)功能描述:可以通过班级信息实现对班级的增删改查。list是查询班级方法,info是根据id查询班级方法,save是添加班级方法,update是修改班级方法,delete是删除班级方法。
因为在数据库设计时,分课表中存在班级id字段,为方便前端添加分课记录时选择班级需要一个查询所有班级的方法即findAll。
(2)类图:
图 5-2班级控制层类图
(1)功能描述:可以通过课程信息实现对课程的增删改查。list是查询课程方法,info是根据id查询课程方法,save是添加课程方法,update是修改课程方法,delete是删除课程方法。
因为在数据库设计时,分课表中存在课程id字段,为方便前端添加分课记录时选择课程需要一个查询所有课程的方法即findAll。
(2)类图:
图 5-3课程控制层类图
(1)功能描述:可以通过教师信息实现对教师的增删改查。list是查询教师方法,info是根据id查询教师方法,save是添加教师方法,update是修改教师方法,delete是删除教师方法。
因为在数据库设计时,分课表中存在教师id字段,为方便前端添加分课记录时选择教师需要一个查询所有教师的方法即findAll。
(2)类图:
图 5-4教师控制层类图
(1)功能描述:可以通过教室信息实现对教室的增删改查。list是查询教室方法,info是根据id查询教室方法,save是添加教室方法,update是修改教室方法,delete是删除教室方法。
(2)类图:
图 5-5教室控制层类图
(1)功能描述:可以通过分课信息实现对分课记录的增删改查。list是查询分课记录方法,info是根据id查询分课记录方法,save是添加分课记录方法,update是修改分课记录方法,delete是删除分课记录方法。
init:初始化操作
queryPage:分页查询操作
saveByDetail:添加操作(判断是否达到上限)
updateByIdDetail:修改操作(判断是否达到上限)
getTeacherCount:获取该教师在分课记录中存在的数量
getClassesCount:获取该班级在分课记录中存在的数量
time:数据解析,将char数组中字符转换成对应的字符串
(2)类图:
图 5-6分课控制层类图
图 5-7分课业务层类
(3)代码注意事项:
添加、修改分课记录时需要注意当前需要添加或修改的分课记录中,该教师每周课程上限是否大于该教师已教课程数;该班级每周课程上限是否大于该班级已分配课程数。
为能在分课记录表中能够看到更多的详细信息,在查询分课记录前,需根据班级id、教师id、课程id、教室id进行初始化操作。
(1)功能描述:可以进行排课操作,可以根据班级或教师查看课表。
(2)类图:
图 5-8排课控制层类
图 5-9排课业务层类
(3)排课代码:
@CacheEvict(value = {"Curriculum"}, allEntries = true)
@Override
public void timeTable() {
//条件修改
final UpdateWrapper <ClassesCourseTeacherEntity> updateWrapper = new UpdateWrapper < >();
//全部置空
updateWrapper.set("week_number", null);
updateWrapper.set("classroom_id", null);
//修改表
classesCourseTeacherDao.update(null, updateWrapper);
//查询所有分课记录
List <ClassesCourseTeacherEntity > list = classesCourseTeacherService.init(classesCourseTeacherDao.selectList(new QueryWrapper < >()));
if (list.size() == 0) {
list = null;
}
Assert.notNull(list, "请先添加分课记录");
//查询所有教室记录
List <ClassroomEntity > classroomList = classroomDao.selectList(new QueryWrapper < >());
if (classroomList.size() == 0) {
classroomList = null;
}
Assert.notNull(classroomList, "请先添加教室");
//循环遍历
for (ClassesCourseTeacherEntity classesCourseTeacherEntity : list) {
// log.warn("当前分课id:{}", classesCourseTeacherEntity.getId());
//可用教室列表
List <ClassroomEntity> okClassroomList = okClassroomList(classroomList, classesCourseTeacherEntity.getClassesEntity().getClassesNumber(), classesCourseTeacherEntity.getCourseEntity().getCourseType());
// log.info("可用教室列表:{}", okClassroomList);
//okClassroomList=null,可用教室列表为空
Assert.notNull(okClassroomList, "教室空间不足,不符合班级人数要求");
//时间冲突,分配教室,分配时间
Map <String, String > map = byWeekNumberAndClassroomId(okClassroomList, new HashSet < >());
//map=null,教室不够
Assert.notNull(map, "教室数量不足,请增加教室");
classesCourseTeacherEntity.setWeekNumber(map.get("week_number"));
classesCourseTeacherEntity.setClassroomId(Long.valueOf(map.get("classroom_id")));
//保存修改后的记录
classesCourseTeacherDao.updateById(classesCourseTeacherEntity);
}
list.forEach(System.out::println);
}
图 6-1指定删除页面
图 6-2批量删除页面
(1)新增或修改测试
图 6-3专业新增页面
(2)查询测试
图 6-4专业分页查询页面
图 6-5专业模糊查询页面
(3)压力测试
图 6-6专业查询压力测试
(1)新增或修改测试
图 6-7班级新增页面
(2)查询测试
图 6-8班级分页查询页面
图 6-9班级模糊查询页面
(3)压力测试
图 6-10班级查询压力测试
(1)新增或修改测试
图 6-11课程新增页面
(2)查询测试
图 6-12课程分页查询页面
图 6-13课程模糊查询页面
(3)压力测试
图 6-14课程查询压力测试
(1)新增或修改测试
图 6-15教师新增页面
(2)查询测试
图 6-16教师分页查询页面
图 6-17教师模糊查询页面
(3)压力测试
图 6-18教师查询压力测试
(1)新增或修改测试
图 6-19教室新增页面
(2)查询测试
图 6-20教室分页查询页面
图 6-21教室模糊查询页面
(3)压力测试
图 6-22教室查询压力测试
(1)新增或修改测试
图 6-23分课新增页面
(2)查询测试
图 6-24分课查询页面
(3)压力测试
图 6-25分课查询压力测试
(1)整体页面测试
图 6-26首页
(2)班级课表查询测试
图 6-27班级课程表
(3)教师课表查询测试
图 6-28教师课程表
(4)打印测试
图 6-29打印测试
(6)压力测试
图 6-30查看课表压力测试
图 7-1登录页面
图 7-2首页
图 7-3统计页面
图 7-4用户管理
图 7-5菜单管理
图 7-6角色管理
通过这次课程设计,发现其中有很多知识没有接触过,上网查资料的时候才发现自己学到的仅仅只是皮毛,还有很多需要我们掌握的东西不太清楚。也有许多已经学过的知识点没有理解到位,不能灵活的运用于实际,不能很好的用来解决问题,例如:缓存、安全控制等。在本次课程设计中缓存和安全控制只用到了一点点,感觉自己并没有深入地了解这些知识点,只学到了一点点皮毛。
在课程设计的过程中,也有遇到许多困难,比如分课表的设计,课表的显示,排课的过程,但最终还是将这些困难给解决了。但也有些问题并没有解决,比如课表显示,现在只能显示课程名称,关于其他的信息难以显示处理,这是之后我需要进行改进的地方。整体的课程设计中,感觉自己学到了许多知识,同时这个排课系统虽基本实现了所要求的功能,但后续还有许多能够改进的地方,我希望在后续能对排课系统进行改进,同时将其作为后续的微服务项目中的一个服务,后续还能集成更多服务,如:学生成绩管理系统、教材管理系统等等。
回顾此次课程设计,从理论到实践,这些日子学到了很多知识。只有理论知识是远远不够的,只有把所学的理论知识与实践结合起来,从而提高自己的实际动手能力和独立思考能力。在课程设计的过程中也有遇到许多问题,可以说是困难重重,但可喜的是最终都解决了。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。