详细设计
引言
编写目的
该文档在软件计划文档的基础上,进一步的细化系统结构,展示了软件结构的功能与流程逻辑、程序系统结构及接口设计,详细的介绍了系统各个模块是如何实现的,包括涉及到的算法,逻辑流程等,以便用户和项目开发人员了解产品详细的设计与实现,为开发人员提供开发参考书。以下叙述将结合文字描述、伪代码、图表等来描述Qiaqia选课系统的详细设计和相关的模块描述。 本报告的预期读者包括客户,开发人员以及跟该项目相关的其他有关人员。
系统概述参见:Qiaqia选课系统需求分析
背景
- 项目名称:Qiaqia选课系统
- 任务提出者:tsn
- 任务开发者:软工2022 Qiaqia小队
- 用户:各大高校的师生和管理员
- 实施单位:软工2022 Qiaqia小队
关键技术
数据持久化: MySql 缓存: Redis 后端框架: SpringBoot、Mybatis、Gin 安全与授权:JWT 算法:课时安排冲突检测
开发环境
软件环境
表项 | 选型 | 版本 | 说明 |
---|---|---|---|
操作系统 | Ubuntu(Linux) | 20.04LTS | 您也可选Windows 10。 |
数据库平台 | PostgreSQL | 14.2 | 为后端服务提供关系型数据库支持。 |
应用平台 | Java | JDK11 | 后端服务采用Java语言编写,并采用JDK11作为开发套件,所以可能需要最低版本为11的Java运行环境。 |
Web容器 | Nginx | 1.21.6 | 作为承载Web静态资源的容器,同时支持反向代理将API调用代理到后端服务上。 |
您也可以在一台性能较好的服务器上安装Docker
与Docker Compose
,使用我们提供的docker compose
配置,在Docker
中运行本系统,无需考虑环境配置。
硬件环境
服务器 | 推荐配置 |
---|---|
应用服务器 | CPU核心数:2;内存:8GB |
数据库服务器 | CPU核心数:2;内存:4GB;数据容量:500GB |
参考资料
- 软工2022 Qiaqia小队Qiaqia选课系统软件计划文档
- 软工2022 Qiaqia小队Qiaqia选课系统设计文档
- 软工2022 Qiaqia小队Qiaqia选课系统需求文档
- 窦万峰.软件工程方法与实践(第三版).北京:机械工业出版社,2016
- 普莱斯曼.软件工程:实践者的研究方法(原书第8版).北京:机械工业出版社,2016
程序系统结构
架构描述
系统总体上采用三层MVC架构,其中水平层次上自上而下分为前端界面view层、Controller控制层、Service业务逻辑兼model层,底层为用于数据库访问的Dao。垂直层次主要依据面向用户权限划分为四个切面:StudentController为代表的学生服务切面、TeacherController为代表的教师服务切面、AdminController为代表的管理员服务切面,CommonController为代表的公用服务切面。对应个个Controller于Service层划分了如下公用构件StudentService(用于学生特有业务处理构件)、CourseSelectService(单独将选课相关业务抽离出来有利于优化和非功能性需求的满足)、CourseService(用于课程特有业务处理构件,间接控制关系较为密切的CourseSelectService)、UserService(用于用户管理特有业务处理构件)、TeacherService(用于教师特有业务处理构件),CommonService(用于公用业务业务处理构件)
系统功能设计与流程描述
下面分用户角色简要说明一下前端需要考虑的页面及大致的逻辑、细节。
此外,用户访问需要用户权限的页面之前均需要先登录,否则无法访问。
当用户未登录时访问其他页面,会被自动导航到登录页面提示用户登录,待登录完成自动跳转至登录前的页面。
用户
这些页面主要完成与所有用户都有关系的功能。
登录/注册
用户可在登录页面登录或注册。目前考虑将两个功能结合到一个页面,但是放到不同的Tab里。
当用户登录成功之后,如果用户是从别的页面跳转至登录页面的,则会被导航至跳转前的页面;否则会被导航至首页。
首页
用户在首页可以快速预览个人信息,以及当前学期的课程表——对于学生来说,是学生所需要上课的表;对于教师来说,是教师所教授的课程的表;对于管理员来说,此项功能暂时无用。
个人信息页
用户可以在个人信息页面查看自己的个人信息,并可以对密码进行修改。
学生
这些页面主要关注仅针对学生的功能。
选课
学生可以在选课页面查看当前学期可以选择的课程以及它们的详细信息——比如,课程名、学分、学时、授课教师、授课时间、授课地点、容量、余量等等。并且还可以根据课程的信息来对可选课程进行条件筛选,比如查询“计算机网络”课程,查询由计算机学院开办的课程等等,这些条件可以混合查询。
查询已选课程
用户可以根据自己需要查询已选的课程,这些课程可以是当前学期的,也可以是过去的学期的,同时可以查询选过的所有课程,并展示这些课程的详细信息以及获得的成绩。
成绩
用户可以在成绩页面查看自己的成绩,并可以计算GPA。
教师
这些页面主要关注与教师相关的功能。
所授课程
教师可以在所授课程页面查看自己所授课程的详细信息,包括课程名、学分、学时、授课教师、授课时间、授课地点、容量、余量等等。
此外,教师还可以:
- 详细查看该课程包含的所有学生的信息,包括学号、姓名、性别、年龄、学院、专业等等。
- 可以对该门课程的学生登记成绩,但是会受时间限制。
管理员
用户管理
管理员可以在用户管理页面对用户进行管理:
- 查询用户:可根据用户名字、学号、学院等信息筛选用户。
- 增加用户:可以增加新的用户,指定其角色以及详细信息。
- 修改用户信息:可以调整用户的部分信息,如所在学院等等。
- 删除用户:可以删除用户,但是实际上该用户只会被标记为移除状态,还是会保留其信息。
学院管理
- 查询学院:可根据学院名称等信息筛选学院。
- 增加学院:可以增加新的学院。
课程管理
- 查询课程:可根据课程名称、学分、学时、授课教师、授课时间、授课地点、容量、余量等信息筛选课程。
- 新增课程:可以增加新的课程,并指定其名称、开课学院、学分等信息,
课程
代表了某一门课程的公共信息。 - 新增课头:可以对已有课程增加课头,它是一门
课程
的具体实例,还包括了一些额外的信息,如开课时间、地点、所属学期、授课教师等。 - 强制选课、撤课:可以对指定课头,强制导入学生(强制选课),或强制将学生从课头移除(强制撤课)。
后端功能接口描述
详细接口定义请参见API接口定义
非功能需求
- 并发性需求
- 优化用户场景: 针对某个用户场景要考虑到执行相应功能时,是否可以将请求数量进行优化压缩,这考验
API
的设计是否完善全面。并且针对前端页面,要对单个页面的请求数量和数据显示数量进行慎重考虑,尽量做到数据简洁且全面,没有冗余的数据请求与数据显示。 - 应对峰值访问: 在峰值访问时,考虑
Cache
等解决方案。另外也需要优化数据库访问、关注DAO
层的设计等,前端考虑数据持久化。 同时也对硬件提出要求,考虑采用配置更好的服务器。 - 对用户数量进行调研: 要对用户的所有数量、平均每天访问数量、峰值用户数量、用户从登录系统到退出系统的时间间隔、被考察时间长度等进行调研与反馈。 根据并发数公式算出相应数据后 ,针对该数据进行更充分的并发性需求讨论。
- 优化用户场景: 针对某个用户场景要考虑到执行相应功能时,是否可以将请求数量进行优化压缩,这考验
- 安全性需求
- 身份校验和权限: 用户在登录后根据身份不同会得到不同的权限,各个权限有用户需求确定。 利用网页
session
存储来保存用户的权限令牌(即token
),或者保存一些辅助校验的键值对。在用户进行每一次请求时,要发送这些用于校验的键值对。在服务器收到请求时应根据请求头内容来选择是否同意该次请求。 - 表单验证: 需要对用户的输入进行合法性校验,比如密码长度、非法字符、格式冲突、数据临界值等等。前端可以选做对输入的检查,也可以将数据发送给服务器后,有服务器进行最后的、最权威的校验。前端接收到服务器的消息后,选择性进行提示或返回。
- 防止
SQL
注入和XSS
攻击:SQL
注入随着服务器框架的完善已经被解决。在面对XSS
攻击时,后端开发者应该遵守一个原则即不相信任何用户输入和输入来源。 - 处理表单的二次提交: 用户可以快速点击某些提交类组件多次,前端需要对这类情况进行处理,例如在一次提交后就对该组件进行阻塞,或者后端对多次提交进行检查与提示。
- 文件上传: 文件的上传需要有文件类型和大小的严格限制。 另外,不应该上传可执行文件;需要获取文件真实的类型信息而非后缀名。 文件上传的一个陷阱就是使用了客户端来源的文件名作为文件存储的文件名,这是极为不可靠的,在上传后的文件系统中需要使用内建的唯一命名,并通过数据库来记录用户上传的文件名。
- 数据库加密: 在数据库中将敏感的数据进行加密处理。例如对用户密码进行
base64
的加密。以防止数据库文件泄露,造成经济损失。
- 身份校验和权限: 用户在登录后根据身份不同会得到不同的权限,各个权限有用户需求确定。 利用网页
- 性能需求
- 响应时间: 用户进行操作或请求后,是否需要服务器返回数据。如果需要返回数据,则应设置一个请求时间的上限,假如没有该上限,可能造成用户体验不流畅。并且在超过响应时长后应进行提示。在优化响应时长方面可以考虑:优化
SQL
语句、优化静态资源的存储、同异步操作、第三方集成等。硬件配置也可以优化响应时间,在系统对此迭代后可以考虑更换服务器主机。 - 考虑是否实现实时消息通知: 需要消息模块的系统要考虑如何动态、实时显示消息数量。若考虑实时显示,则需要使用轮询、长连接等解决方案,此时后端开发人员需要添加更复杂的逻辑。若不考虑显示,对开发团队而言无疑减少工作量但对会削弱用户体验。
- 分布式系统: 考虑到本系统的用户仅为某一学校或机构的所有教职工、学生等,用户量小。故不采用分布式系统。
- 游离数据处理: 如果将部分删除功能授权给用户,则需要考虑是否要对被删除数据的关联数据也进行删除。
- 响应时间: 用户进行操作或请求后,是否需要服务器返回数据。如果需要返回数据,则应设置一个请求时间的上限,假如没有该上限,可能造成用户体验不流畅。并且在超过响应时长后应进行提示。在优化响应时长方面可以考虑:优化
- 易用性需求
- 加载状态的UI设计: 加载状态是比较容易被忽视的需求,在高并发量的开发模式下,数据的获取都是异步加载,如果忽略该需求,会在网络条件较好时出现闪烁的情况,而在网络条件不好时又会看起来卡顿。
- 输出格式化: 在前端页面展示时,需要将从后端拉取的数据进行处理,也可以后端进行处理后再返回数据。在显示数据时,要考虑到易读、方便。例如,对数字使用千分位分隔显示;对时间进行格式化输出,可以使用
“一天前”
、“一月前”
等人性化显示方式;图片的输出要进行裁剪与缩放等。 - 用户返回与用户确认: 若用户进行到某一步骤时,需要点击“确认”或“取消”,则需要考虑在点击后用户将会返回或跳转到哪一页面。是在该页进行跳转还是另开新页进行跳转。
- 用户界面美观易用: 在前端设计时,要参考用户量大的几个网站(例如bilibili、爱奇艺、淘宝、知乎、微博、百度等),学习并借鉴这类网站的用户操作逻辑、交互组件摆放、交互组件样式等。同时要做到美观,尽量做到色调统一、扁平化设计。
储存分配
采用的数据库
采用的数据库:MySql。
对应的版本号:8.0.28。
数据库表的设计
user(用户表)
名 | 类型 | 长度 | 是否可空 | 主键 | 默认值 | 备注 |
---|---|---|---|---|---|---|
user_id | bigint | × | √ | 自增 | ||
name | varchar | 32 | × | |||
role | tinyint | × | ||||
roll_date | date | × | ||||
password | varchar | 255 | × | |||
institute_id | int | × | 外键 |
course(课程表)
名 | 类型 | 长度 | 是否可空 | 主键 | 默认值 | 备注 |
---|---|---|---|---|---|---|
course_id | bigint | × | √ | 自增 | ||
course_name | varchar | 255 | × | |||
course_hour | int | × | ||||
credit | float | × | ||||
institute_id | int | × | 外键 |
institute(院系表)
名 | 类型 | 长度 | 是否可空 | 主键 | 默认值 | 备注 |
---|---|---|---|---|---|---|
institute_id | int | × | √ | 自增 | ||
institute_name | varchar | 255 | × |
course_head(课头表)
名 | 类型 | 长度 | 是否可空 | 主键 | 默认值 | 备注 |
---|---|---|---|---|---|---|
head_id | bigint | × | √ | 自增 | ||
head_name | varchar | 255 | × | |||
teacher_id | bigint | × | 外键 | |||
head_address | varchar | 255 | × | |||
course_id | bigint | × | 外键 | |||
head_year | int | × | ||||
volume | int | × | ||||
volume_left | int | × | ||||
head_term | tinyint | × |
course_user_rel(课程学生联系表)
名 | 类型 | 长度 | 是否可空 | 主键 | 默认值 | 备注 |
---|---|---|---|---|---|---|
head_id | bigint | × | √ | 自增 | ||
student_id | bigint | × | 外键 | |||
grade | float | × | ||||
state | tinyint | × | 1 |