第4章 系统设计
用户对着浏览器操作,肯定会出现某些不可预料的问题,但是不代表着系统对于用户在浏览器上的操作不进行处理,所以说,要提前考虑可能会出现的问题。
4.1 功能结构设计
图4.1即为设计的管理员功能结构,管理员权限操作的功能包括增删改查网课信息,教师信息,学生信息,试卷,试题信息等,管理论坛帖子,管理观看进度信息,管理学生测试信息等。
图4.1 管理员功能结构
图4.2即为设计的教师功能结构,教师权限操作的功能包括查看学生对于网课信息的观看进度信息,管理网课信息,管理论坛帖子,管理学生测试试卷和试题,对学生的测试记录和错题信息进行管理等。
图4.2 教师功能结构
图4.3即为设计的学生功能结构,学生权限操作的功能包括选择试卷在线答题,查看测试记录和错题信息,播放网课视频,下载网课文件,通过论坛模块进行主题讨论交流。
图4.3 学生功能结构
4.2 数据库设计
教育培训微信小程序运行中产生的数据需要按照提前设置的存储规则进行保存,设计出一个符合项目的最优数据存储格式,因为它能减少用户的等待时间,还可以对系统的请求在最短时间内进行响应。所以,对数据库设计时,需要对功能需求进行详细的拆分,以及对业务状态的细分,然后设计具体的存储规则,保证数据库能正常运作,缩短数据处理时间,并在一定程度上降低数据冗余,节省存储空间。
4.2.1 数据库概念设计
实体-联系图还有一个名称即E-R图,是Entity Relationship Diagram各英文单词首字母的缩写,它这种概念模型通常用于对现实世界进行描述。同时它还是一种能够直观表达数据中实体,联系,属性的有效手段。绘制E-R图能够选择的工具也有很多,但是Office Visio 这款软件在E-R图的绘制上一般都是作为首选工具,因为它是基于可视化处理,使用它创建E-R图非常简单。使用基本的E-R图构成元素,比如椭圆,菱形,矩形,还有实线段来表达对应的信息,椭圆代表属性,即实体的特征,矩形代表实体,即数据库中的一个具体数据表,菱形代表实体中相互关系,实线段主要是完成椭圆,矩形,菱形的连接。
(1)图4.4即为教师这个实体所拥有的属性值。
图4.4 教师实体属性图
(2)图4.5即为网课这个实体所拥有的属性值。
图4.5 网课实体属性图
(3)图4.6即为学生这个实体所拥有的属性值。
图4.6 学生实体属性图
- 图4.7即为试题这个实体所拥有的属性值。
图4.7 试题实体属性图
- 图4.8即为上面介绍的实体中存在的联系。
图4.8 实体间关系E-R图
4.2.2 数据库物理设计
本小节主要任务即是根据上述内容进行数据存储结构的设计,实体的属性就用来表示字段名称,不同的字段表示的数据类型以及取值都不相同,以及该表各个字段是否能够保持空等进行说明,设计完成一张数据表的结构之后,在保存时同样要命名,尽量选择英文名称进行命名并保存,还不容易导致系统出错。接下来就对设计的表进行简单说明。
表4.1 课后习题测试表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
yonghu_id | 提问用户 | int(11) | 是 |
chat_issue | 问题 | varchar(200) | 是 |
issue_time | 问题时间 | timestamp | 是 |
chat_reply | 回复 | varchar(200) | 是 |
reply_time | 回复时间 | timestamp | 是 |
zhuangtai_types | 状态 | int(255) | 是 |
chat_types | 数据类型 | int(11) | 是 |
insert_time | 创建时间 | timestamp | 是 |
表4.2 试卷表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(20) | 否 |
exampaper_name | 试卷名称 | varchar(200) | 否 |
exampaper_date | 测试时长(分钟) | int(11) | 否 |
exampaper_myscore | 试卷总分 | int(11) | 否 |
jiaoshi_id | 教师 | int(11) | 是 |
exampaper_types | 试卷状态 | int(11) | 否 |
create_time | 创建时间 | timestamp | 否 |
表4.3 试题表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(20) | 否 |
exampaper_id | 所属试卷id(外键) | int(20) | 否 |
examquestion_name | 试题名称 | varchar(200) | 否 |
examquestion_options | 选项 | longtext | 是 |
examquestion_score | 分值 | int(20) | 是 |
examquestion_types | 试题类型 | int(20) | 是 |
examquestion_sequence | 试题排序,值越大排越前面 | int(20) | 是 |
create_time | 创建时间 | timestamp | 否 |
表4.4 测试记录表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(20) | 否 |
examrecord_uuid_number | 测试编号 | varchar(200) | 是 |
yonghu_id | 测试用户 | int(20) | 否 |
exampaper_id | 所属试卷id(外键) | int(20) | 否 |
total_score | 所得总分 | int(200) | 是 |
insert_time | 测试时间 | timestamp | 否 |
create_time | 创建时间 | timestamp | 否 |
表4.5 答题详情表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(20) | 否 |
examredetails_uuid_number | 试卷编号 | varchar(200) | 是 |
yonghu_id | 用户id | int(20) | 否 |
examquestion_id | 试题id(外键) | int(20) | 否 |
examredetails_myanswer | 学生答案 | varchar(200) | 是 |
examredetails_myscore | 试题得分 | int(20) | 是 |
examination_name | 审核教师 | varchar(200) | 是 |
examredetails_types | 审核结果 | int(20) | 是 |
create_time | 创建时间 | timestamp | 否 |
表4.6 错题表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(20) | 否 |
yonghu_id | 用户id | int(20) | 否 |
exampaper_id | 试卷(外键) | int(20) | 否 |
examquestion_id | 试题id(外键) | int(20) | 否 |
examredetails_myanswer | 学生作答 | varchar(200) | 是 |
insert_time | 记录时间 | timestamp | 否 |
create_time | 创建时间 | timestamp | 否 |
表4.7 论坛表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
forum_name | 帖子标题 | varchar(200) | 是 |
yonghu_id | 用户 | int(11) | 是 |
jiaoshi_id | 教师 | int(11) | 是 |
users_id | 管理员 | int(11) | 是 |
forum_content | 发布内容 | text | 是 |
super_ids | 父id | int(11) | 是 |
forum_state_types | 帖子状态 | int(11) | 是 |
insert_time | 发帖时间 | timestamp | 是 |
update_time | 修改时间 | timestamp | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.8 观看进度表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
kecheng_id | 网课 | int(11) | 是 |
yonghu_id | 学生 | int(11) | 是 |
insert_time | 观看时间 | timestamp | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.9 教师表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
username | 账户 | varchar(200) | 是 |
password | 密码 | varchar(200) | 是 |
jiaoshi_name | 教师姓名 | varchar(200) | 是 |
jiaoshi_photo | 头像 | varchar(200) | 是 |
jiaoshi_phone | 手机号 | varchar(200) | 是 |
jiaoshi_email | 电子邮箱 | varchar(200) | 是 |
sex_types | 性别 | int(11) | 是 |
jiaoshi_delete | 假删 | int(11) | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.10 网课信息表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
kecheng_name | 网课标题 | varchar(200) | 是 |
kecheng_types | 网课类型 | int(11) | 是 |
jiaoshi_id | 教师 | int(11) | 是 |
kecheng_photo | 网课封面 | varchar(200) | 是 |
kecheng_video | 网课视频 | varchar(200) | 是 |
kecheng_file | 网课文件 | varchar(200) | 是 |
kecheng_content | 通知详情 | text | 是 |
insert_time | 添加时间 | timestamp | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.11 公告信息表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
news_name | 公告标题 | varchar(200) | 是 |
news_types | 公告类型 | int(11) | 是 |
news_photo | 公告图片 | varchar(200) | 是 |
insert_time | 添加时间 | timestamp | 是 |
news_content | 公告详情 | text | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.12 管理员表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
username | 用户名 | varchar(100) | 否 |
password | 密码 | varchar(100) | 否 |
role | 角色 | varchar(100) | 是 |
addtime | 新增时间 | timestamp | 否 |
表4.13 学生表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
username | 账户 | varchar(200) | 是 |
password | 密码 | varchar(200) | 是 |
yonghu_name | 学生姓名 | varchar(200) | 是 |
yonghu_photo | 头像 | varchar(200) | 是 |
yonghu_phone | 手机号 | varchar(200) | 是 |
yonghu_email | 电子邮箱 | varchar(200) | 是 |
sex_types | 性别 | int(11) | 是 |
banji_types | 班级 | int(11) | 是 |
yonghu_delete | 假删 | int(11) | 是 |
create_time | 创建时间 | timestamp | 是 |
第5章系统实现
编程人员在搭建的开发环境中,会让各种编程技术一起呈现出最终效果。本节就展示关键部分的页面效果。
5.1 管理员功能实现
5.1.1 教师管理
图5.1 即为编码实现的教师管理界面,教师信息包括手机号,教师姓名,教师性别等信息,管理员可以使用修改功能对有错误信息的教师信息进行更正,需要删除的教师信息也能使用删除功能及时删除。
图5.1 教师管理界面
删除教师:
@RequestMapping("/delete")
public R delete(@RequestBody Integer[] ids){
logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
ArrayList<JiaoshiEntity> list = new ArrayList<>();
for(Integer id:ids){
JiaoshiEntity jiaoshiEntity = new JiaoshiEntity();
jiaoshiEntity.setId(id);
jiaoshiEntity.setJiaoshiDelete(2);
list.add(jiaoshiEntity);
}
if(list != null && list.size() >0){
jiaoshiService.updateBatchById(list);
}
return R.ok();
}
5.1.2 网课信息管理
图5.2 即为编码实现的网课信息管理界面,网课信息包括网课视频,网课文件,网课标题,网课封面等信息,管理不仅需要上传网课文件,上传网课视频,还可以修改网课信息,可以对需要删除的网课信息进行删除。
图5.2 网课信息管理界面
删除网课:
@RequestMapping("/delete")
public R delete(@RequestBody Integer[] ids){
logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
kechengService.deleteBatchIds(Arrays.asList(ids));
return R.ok();
}
5.1.3 学生管理
图5.3 即为编码实现的学生管理界面,学生信息包括性别,班级,手机号等信息,学生信息存在登记错误的情况,管理员则可以使用修改功能及时更正,需要删除的学生信息,管理员也能及时删除。
图5.3 学生管理界面
删除学生:
@RequestMapping("/delete")
public R delete(@RequestBody Long[] ids){
usersService.deleteBatchIds(Arrays.asList(ids));
return R.ok();
}
5.2 教师功能实现
5.2.1 观看进度查看
图5.4 即为编码实现的观看进度查看界面,教师可以查看学生对于网课信息的查看进度情况,可以通过学生姓名查询学生对于网课信息的观看进度信息。
图5.4 观看进度查看界面
查看详情:
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id, HttpServletRequest request){
logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
GuankanjiluEntity guankanjilu = guankanjiluService.selectById(id);
if(guankanjilu !=null){
//entity转view
GuankanjiluView view = new GuankanjiluView();
BeanUtils.copyProperties( guankanjilu , view );//把实体数据重构到view中
//级联表
KechengEntity kecheng = kechengService.selectById(guankanjilu.getKechengId());
if(kecheng != null){
BeanUtils.copyProperties( kecheng , view ,new String[]{ "id", "createTime", "insertTime", "updateTime"});//把级联的数据添加到view中,并排除id和创建时间字段
view.setKechengId(kecheng.getId());
}
//级联表
YonghuEntity yonghu = yonghuService.selectById(guankanjilu.getYonghuId());
if(yonghu != null){
BeanUtils.copyProperties( yonghu , view ,new String[]{ "id", "createTime", "insertTime", "updateTime"});//把级联的数据添加到view中,并排除id和创建时间字段
view.setYonghuId(yonghu.getId());
}
//修改对应字典表字段
dictionaryService.dictionaryConvert(view, request);
return R.ok().put("data", view);
}else {
return R.error(511,"查不到数据");
}
}
5.2.2 试卷管理
图5.5 即为编码实现的试卷管理界面,教师可以设置试卷状态为启用或禁用试卷状态,可以修改试卷考试时长信息,以及修改试卷总分信息等,教师也能新增试卷,对之前新增的已经无效的试卷信息及时删除。
图5.5 试卷管理界面
添加试卷:
@RequestMapping("/save")
public R save(@RequestBody ExampaperEntity exampaper, HttpServletRequest request){
logger.debug("save方法:,,Controller:{},,exampaper:{}",this.getClass().getName(),exampaper.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永远不会进入");
else if("教师".equals(role))
exampaper.setJiaoshiId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));
Wrapper<ExampaperEntity> queryWrapper = new EntityWrapper<ExampaperEntity>()
.eq("exampaper_name", exampaper.getExampaperName())
.eq("exampaper_date", exampaper.getExampaperDate())
.eq("exampaper_myscore", exampaper.getExampaperMyscore())
.eq("jiaoshi_id", exampaper.getJiaoshiId())
.eq("exampaper_types", exampaper.getExampaperTypes())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
ExampaperEntity exampaperEntity = exampaperService.selectOne(queryWrapper);
if(exampaperEntity==null){
exampaper.setCreateTime(new Date());
exampaperService.insert(exampaper);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
5.2.3 试题管理
图5.6 即为编码实现的试题管理界面,所有试卷都是由许多试题组成的,因此教师在组装试卷之前,先要对试题进行添加,以及及时更正登记有错误信息的试题信息,对于不需要的试题信息进行及时删除。
图5.6 试题管理界面
添加试题:
@RequestMapping("/save")
public R save(@RequestBody ExamquestionEntity examquestion, HttpServletRequest request){
logger.debug("save方法:,,Controller:{},,examquestion:{}",this.getClass().getName(),examquestion.toString());
String role = String.valueOf(request.getSession().getAttribute("role"));
if(false)
return R.error(511,"永远不会进入");
Wrapper<ExamquestionEntity> queryWrapper = new EntityWrapper<ExamquestionEntity>()
.eq("exampaper_id", examquestion.getExampaperId())
.eq("examquestion_name", examquestion.getExamquestionName())
.eq("examquestion_options", examquestion.getExamquestionOptions())
.eq("examquestion_score", examquestion.getExamquestionScore())
.eq("examquestion_types", examquestion.getExamquestionTypes())
.eq("examquestion_sequence", examquestion.getExamquestionSequence())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
ExamquestionEntity examquestionEntity = examquestionService.selectOne(queryWrapper);
if(examquestionEntity==null){
examquestion.setCreateTime(new Date());
examquestionService.insert(examquestion);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
5.3 学生功能实现
5.3.1 在线答题
图5.7 即为编码实现的在线答题界面,学生在试卷模块对需要答题的试卷进行答题,答题过程中不仅需要回答试题问题,还需要在试卷规定时间内提交答卷。
图5.7 在线答题界面
5.3.2 网课信息
图5.8 即为编码实现的网课信息界面,学生在网课信息界面中可以通过播放网课视频的方式进行学习,同时,该网课信息界面也展示了网课文件,学生可以下载网课文件。
图5.8 网课信息界面
5.3.3 我的发帖
图5.9 即为编码实现的我的发帖界面,学生在我的发帖界面中可以发布帖子,该界面展示的帖子都是学生自己发布的帖子,因此支持学生对帖子进行更改,删除。同时学生也能跟踪已发布的帖子,比如查看帖子的评论,学生也能回复帖子等。
图5.9 我的发帖界面
发帖:
@RequestMapping("/add")
public R add(@RequestBody ForumEntity forum, HttpServletRequest request){
logger.debug("add方法:,,Controller:{},,forum:{}",this.getClass().getName(),forum.toString());
Wrapper<ForumEntity> queryWrapper = new EntityWrapper<ForumEntity>()
.eq("forum_name", forum.getForumName())
.eq("yonghu_id", forum.getYonghuId())
.eq("jiaoshi_id", forum.getJiaoshiId())
.eq("users_id", forum.getUsersId())
.eq("super_ids", forum.getSuperIds())
.eq("forum_state_types", forum.getForumStateTypes())
;
logger.info("sql语句:"+queryWrapper.getSqlSegment());
ForumEntity forumEntity = forumService.selectOne(queryWrapper);
if(forumEntity==null){
forum.setInsertTime(new Date());
forum.setCreateTime(new Date());
forumService.insert(forum);
return R.ok();
}else {
return R.error(511,"表中有相同数据");
}
}
5.3.4 测试记录
图5.10 即为编码实现的测试记录界面,测试记录界面展示的信息都是学生对试卷答题产生的信息,学生不仅可以查看试卷答题的详细信息,包括试卷每道题的得分信息,以及学生对试题提交的答案信息等,除此以外,学生也能查看试卷的总体得分信息。
图5.10 测试记录界面