次级排课系统的设计与实现

2023-05-30 14:32刘玥高铭文超丁鑫
计算机应用文摘 2023年4期

刘玥 高铭 文超 丁鑫

关键词:次级排课系统;权限验证;数据同步

1后端资源的权限管理

后端的接口实际上是一种资源,为了方便后端资源的开发与维护,本系统将后端资源划分为以下两种。

(1)用户使用的资源(下称用户接口)。

(2)所有人都能使用的资源(下称通用接口)。

不同资源的受众、用途以及重要程度不尽相同,导致它们的开放性也有所差别。其中,还对用户接口的访问采取了权限控制,即不同角色的用户可以访问的接口是不一样的。

1.1资源的开放性

用户接口暴露的数据涉及每个用户的私人信息,因此需要较为严格的鉴权机制来管控;相比之下,通用接口通常标识着一些不重要的资源,如系统中的一些常量,因此不需要任何权限控制,来者不拒。

1.2接口的认证机制

1.2.1令牌

用户接口的访问需要受到管制,所以必须有一套机制来实现这个目的。本系统采用token鉴权机制。

在本系统中,用户接口的token称为login-token,它们都是接口受众的临时凭证。无论是login-token还是app-access-token,其中只携带相关实体的id,login-token中携带的是系统用户的id,app-access-token中则携带了第三方程序的id。

1.2.2令牌的颁发

login-token的颁发由接口/auth _user接口颁发。前端访问该接口时,需要携带用户名和密码,/auth—user接口认证用户名密码无误后,下发用户令牌。前端妥善保存令牌,在访问用户接口时,将该令牌置于header login-token中,以表明用户身份。

1.2.3令牌失效

上文提及的两种令牌都有一定的时效,调用者在必要时可以通过令牌时效查询接口、令牌是否有效,若令牌失效,则需要重新向相应的令牌颁发接口申请新的令牌。login-token的时效查询接口是/token—expire,app-access-token的时效查询接口是/app—access_token/token-expire.

1.3用户接口

与用户交互的前端需要通过用户接口来获取数据并展示给用户。用户接口的访问者必须在HTTP请求中携带用户的token,以证明自己是系统中的合法用户。

1.4用户Token认证机制

1.4.1颁发login-token

前端调用接口/auth—user,并携带用户的用户名和密码,如果经查询,数据库中有相应的用户记录,则生成token并通过响应返回前端。前端保存该token,可以用来访问其他用户接口。

1.4.2token方案

只要在颁发token时将颁发时间点和token时效一并设置到token中[1].就相当于将token时效信息内嵌到了token自身。这不但合理利用了token携带信息的特性,也省去了额外的计时措施,降低了系统的复杂度。

1.5灵活配置接口的开放性

接口有两种开放性,本系统中使用的是“拦截器+注解”。规定注解:@ AuthLogin标识用户接口,其他没有标注的都是通用接口。定义一个拦截器:Authenticationlnterceptor处理用户认证的逻辑,判断目标接口是否标注@ AuthLogin注解,若标注了,则拦截并认证。由此,变更某个接口的开放性,添加或取消该接口的注解即可。

2用户接口的权限鉴别

本系统采用“拦截器+注解”的方式,可以灵活配置接口的权限。设置注解:@ Permlssion。设置拦截器:AuthorizationlnterceptorAuthorizationlnterceptor只拦截被注解@ Permission标注了的接口。

在拦截器中,获取来访者的角色,根据角色查询到来访者能访问的所有资源,再对比当前接口是否在可访问资源列表中,如果在,则放行,否则不能访问。

3数据同步

3.1概述

本系统通过后端代码调用学校教务系统的接口,拉取教务系统数据库数据,作为本系统的数据源,再结合前端的可交互式界面,达到真正意义上的一键导人数据。虽然一键导人数据方便、快捷,节省人力及时间,但是通过这种方法导人数据的方式通常需要两个系统,即数据源系统(教务系统)和消费数据的系统(本排课系统)。这种定制化的工作并不需要重复进行,除非两个系统的数据存储结构发生变化,否则接口不会发生较大变化,因此,对接口的适配能达到接近“一劳永逸”的效果。

3.2同步机制

3.2.1数据存储结构

在数据同步的语境中,数据消费方的数据存储结构总是依赖数据生产方[2]。根据生产方的数据结构,在本系统中构建两个对应的数据接收实体类和两个数据存储实体类(数据库对象PO)。数据接收实体类字段与数据生产方的数据结构完全一致,而数据存储实体类则是根据本系统的情况定制的实体类。为了让消费方的数据存储结构保持相对稳定的状态,需要加一层数据接收实体类作为缓冲,这部分实体类只作为数据生产方的映射实体,每当数据生产方的数据结构改变,对数据接收实体的修改是不会对本系统产生关键性改动的。虽然增加了一层,但本系统的数据存储实体还是需要改变,即使如此,大部分的改变已经被数据接收实体类层吸收了,存储结构做微调即可。

3.2.2一次拉取的数据量

由于拉取到的數据在持久化之前都需要在内存中驻留一段时间,因此需要考虑数据量是否会超出进程的内存空间大小。排课系统涉及数据量较大,一次拉取所有数据的方案是不可行的[3]。所以,可以采取不同数据依次分开同步的方式拉取数据。在同步一种数据时,可以先拉取数据的主键,再根据主键逐条拉取详细数据[4]。经测试,当JVM的最大堆内存设置为128MB时,最大可以开辟10000000个整形变量,以一次性拉取所有学生的主键为例,内存完全能够承受。

3.2.3数据更新策略

要完成数据消费方的数据与数据生产方的数据同步,需要实现以下两点[5]:寻找生产方和消费方数据的差集并消除双方的差异:比对更新生产方和消费方都有的数据。项目组给消费方的数据库待同步数据增加一个字段latest_sync,标识该数据是否是最新的。每次同步数据前,将表中的latest_sync字段置为0,表示数据都没更新,然后拉取并遍历生产方的数据,逐个查找消费方的数据库,是否存在数据,若不存在,则说明该数据需要在消费方新增,并置lastest_sync字段为1,若存在,则比对更新,也置lastest_sync字段为1,如此遍历完成后,所有lastest_sync字段为0的数据就都是生产方没有但消费方有的数据,需要删除。

4排课

4.1概述

排课问题主要有以下几类实体:教师、上课教室、上课班级、授课课程。排课问题主要是要解决上述实体之间对资源利用的冲突。该问题的最终产出是教学课表,课表中的每一项大致可以分为某个时间段、某个教师、某个教室、某个班级、教授某门课程。

4.2排课约束条件

排课的约束条件主要来源于时间和空间上的限制。例如,同一个教室在同一个时间片只能有一场授课活动、同一个教师在同一个时间片只能在一个教室教同一个班级的课,同样的,同一个班级在同一个时间片也只能在同一个教室上同一门课。排课系统的主要约束条件有以下几个因素:日寸间片、教室、教师、课程和班级。为了使排课能够顺利进行,排课的所有因素必须满足上述時空约束条件。

4.3排课的输入

排课最核心的基础数据是学期计划表,每一个学期计划表的每一行构成了排课流程的主要输入。计划表规定了授课教师、授课班级、教授课程,计划表的每一行包括该节课的课时数、上课人数、上课班级等。

4.4排课关键流程

本系统的排课算法采用遍历算法。排课的核心任务就是,针对每个学期计划表行,将人(教师、班级)安排到计划表指定教室的某个时间片中,因此,排课过程实际要确定的是一个学期计划表行的上课时间和上课地点,对于教师和班级条件都是在学期计划表中规定好的。本系统以时间片作为遍历的顶层因素,遍历一个学期内所有可以排课的时间片,以时间片为条件,查询已经排好的课表数据,若没有结果,则该时间片没有被占用,可以继续嵌套遍历所有教室。以教室主键为查询条件,查询已经排好的课表数据,若没有结果,则该教室在当前日寸间片没有其他课程安排,该教室条件满足,在遍历教室的循环中依次检查授课教师和授课班级在当前时间片、当前教室是否有其他课程安排。若上述教室、教师、班级都符合条件、不冲突,则完成了对一个学期计划表行的排课,可以生成一条排课数据并将其持久化。上述循环结束后,所有计划表都被安排完毕,算法结束。