@TOC
springboot199疫情打卡健康评测系统">springboot199疫情打卡健康评测系统
第1章 绪论
1.1 选题动因
到现在为止,互联网已经进入了千家万户,最普通的平民百姓也有属于自己的智能设备,计算机各种技术的储备也是相当的丰富,并且实现也是没有难度,各行各业,包括一些个人,也积极拥抱互联网时代的到来,也可以说是互联网时代的到来把人们都给包在互联网之中。从刚开始的政府办公,国家企业的开头使用,到如今的老百姓都能用上,别说那些普通企业了。计算机就是有这样的魅力,互联网被称为浪潮不是浪得虚名的。采用计算机技术,开发一些软件,实现软件所在的目的,这是一个常理,这个基础的常理缩短了地域之间的联系,提高了地域竞争水准,减低了人力成本和数据存储成本。本课题研究的疫情打卡健康评测系统,也是采用了计算机技术,该系统能够提高疫情打卡健康评测信息数据的检索速度,使用起来非常的方便。
1.2 目的和意义
在疫情打卡健康评测系统实际操作中,使用者会发现使用起来相当的方便,并且对数据的管理者来讲,也能及时的获得自己想要的数据,对整个数据的所有者能提供强大的帮助,疫情打卡健康评测系统从操作者的角度出发,不管是在数据的接收以及传递,以及处理结果,都有一个很明显的要求,对有效数据的处理,并且形成集合,并且对有效数据集合进行固定化处理,可以得到更有效的数据,有了疫情打卡健康评测系统,让管理层不至于把大量的人力和财力资源消耗在数据处理整合方面,完全可以让不知疲倦的计算机来进行,不仅投入减低,并且产出也不少。互联网时代就是如此,顺之者昌,响应互联网时代,不至于说可以乘风破浪,起码可以降低直接淘汰出局的几率。疫情打卡健康评测系统的出现是顺应时代的。
1.3 论文结构安排
疫情打卡健康评测系统的论文结构将从6个章节进行阐述。具体结构安排如下:
第1章:本章节对本课题的选题动因,本课题的研究目的和意义进行说明。
第2章:本章节对本课题需要运用的环境和技术进行说明。
第3章:本章节对本课题性能,功能进行分析,对系统开发的经济,技术等条件是否可行进行说明。
第4章:本章节对本课题具体的功能进行设计,同时也对系统的数据库进行E-R图设计以及数据表设计。
第5章:本章节对实现的功能的运行效果图进行展示,同时对系统的功能进行说明。
第6章:本章节对系统功能上的测试进行说明,对测试的结果进行分析。
第2章 开发环境与技术
疫情打卡健康评测系统需要提前对功能进行调查分析,并且根据分析结果进行技术上的辩证,可以选择更合理的开发技术以及开发工具。
2.1 Tomcat 简介
只要学习Java Web项目就不得不学习Tomcat。Tomcat是一种免费的开源的一种Java Web项目的容器,完美继承了 Apache服务器的特性,并且里面添加可以自动化运行的Java Web组件,让Java Web项目可以完全的运行到Tomcat里面。对于特大型项目来讲,直接用Tomcat会造成启动变慢,处理有限等,所以对项目进行了前后端分离技术,但是对于需要称不上特大型的项目来讲,普通的大中型项目用Tomcat作为Java Web项目的运行容器是完全够资格的。最重要的是Tomcat完全跟着Java EE,每一次Java EE的升级,Tomcat都会有着对应的版本出现,版本更新速度是非常快的。更新速度快,代表着有技术方面的支持,值得用户使用的,让用户更加信赖Tomcat产品。
2.2 Eclipse简介
Eclipse这款开发工具最最重要的特点就是免费,不管是用来开发任何的东西,哪怕用来教学或者是生产,只要是能带了商业价值的生产都可以免费使用,这一点对于IDEA或者MyEclipse来讲,是非常的具有前瞻性的。免费的也许有很多不足,但是就是因为免费,所以很多人愿意贡献自己的力量,让这款免费的工具可以拥有更多的插件,用起来更加的舒心。可以这么说,Eclipse就是Java语言开发行业的鼻祖,只要是学过Java的人,对Eclipse没有不熟悉的。Eclipse操作起来非常的方便,可以不用安装,直接解压了就可以使用,并且可以在不同的操作系统上面都可以安装到对应的版本。Eclipse是真的不要钱,免费,下载就能用,这么多年以来长期占领着Java开发市场的半壁江山。Eclipse可以在官网上进行捐款,捐款可以支持Eclipse进一步发展,也可以不捐款直接使用,一切随心,不会强求。Eclipse真的是一款良心Java生产工具。
2.3 Navicat简介
Navicat是一款管理数据库的软件。众所周知,所有的数据库只是以特定的存放格式进行存放的,访问也需要特定的接口以及语句进行访问。如果访问数据库都用各种命令,不仅仅是开发效率上会大大的降低,并且看起来也不舒服,对于某些数据或者数据库来讲这样并不友好,如何对数据库进行友好的访问到现在为止,不同的数据库厂商都推出了适合自己数据库的管理工具,但是有一点就是,数据库厂商推出之后,只要能用就行,并没有符合人体工程学,所有的数据库厂商推出的数据库管理工具都是免费的,所以并没有对于数据库管理工具进行过多的优化,用起来相当的不友好,并且各个数据库工具是不能通用的,这一点数据库厂商肯定不会去做匹配其他数据库的管理工具,所以Navicat就应运而生,可以采用Navicat管理各种各样的数据库,可以同时访问各种数据库并且通过不同的连接进行访问,还可以访问不同电脑的数据库,页面操作简单,美观大方,用起来很好用,并且占用电脑资源很小,很适合作为替代其他数据库厂商推出的数据库管理工具使用。
第3章 系统分析
通过对系统的功能进行具体分析,可以参考已经发表过的具有参考价值的文章作为对比,这样能把功能分析的很透彻,并且也会因为功能的分析而对性能也有大致的了解,并且可以预测性能,实现性能分析的结果。
3.1 可行性分析
系统的设计必须符合正常逻辑,所以设计之处,也需要从其他方面来论证其可行性。
3.1.1 经济可行性
开发疫情打卡健康评测系统,存在经济上面的支持,必须经济上的支持才可以有序进行,比如是否需要额外购买开发工具,购买开发电脑,或者从开发技术上是否是免费开源,达到的效果上面是否支出与收入不匹配,这些都需要进行分析。由于开发本系统,开发技术开源且稳定,电脑用正在使用的电脑就能满足,不需要太多的经济支出就可以达到目的,经济可行性通过。
3.1.2 技术可行性
疫情打卡健康评测系统软件主要用到的一些工具,而这些工具正好在学校就使用过,并且网上有很多免费的并且符合的开发工具,技术方面也学过,并且有图书馆的资源和网络资源可以充分利用。所以在技术角度上面来分析是可以的。
3.1.3 操作可行性
操作方面分为开发过程,实现过程,项目具体操作流程。这些因为都学过,并且有其他的项目流程作为参考。总体实现一般就是用户的登录相关,权限分配,基础数据的变更体现。让不同的角色有不同的操作界面,符合正确角色定位,使用者在操作上面并不会感觉到很突兀,影响操作流程。所以操作方面是可以的。
通过以上不同角度的分析,最后论证分析了可行性是没有问题的,完全可以进行后续步骤。
3.2 系统流程分析
操作逻辑是一个可以用画图工具展示的,因为数据在录入过程中的不可见,只能看到返回结果,所以把流程画成图可以更好的理解其中的顺序。
在系统的各项操作中,其他的录入环节,会对操作者具体操作的每条信息都会提出验证要求,比如不能为空,只能是汉字,以及其他的要求等,这些都在前端需要编写清楚,达到友好提示的目的,有效的帮助操作人员理解操作。具体数据的流程如下面的图所示。当操作员输入信息后,点击提交后台就会接收操作员提交的信息,并且提前编写好的逻辑会继续验证,如果数据合格就存入到数据库里并且返回成功提示,这样一个录入环节就达到了设计要求。
图3.1 添加信息流程图
有时候录入的一些数据可能需要修改,修改就是纠正之前的操作,所以修改数据必须是先把想要修改的数据从数据库里获取出来,然后在这个之上进行修改,修改数据也有相应的操作流程。
图3.2 修改信息流程图
数据的查询是在任何程序上都是一个常规的操作,面对的数据量不一样,想要获取想要的数据时间也不一样,都是尽快的获取自己想要的结果,所以数据查询就需要有个查询条件作为查询关键词,这样可以更好的获取符合关键词的数据。
图3.3 查询信息流程图
3.3 系统性能分析
关于疫情打卡健康评测系统从性能需求方面来分析,主要从五个角度分析。五个角度分别从设计的实用性,设计的操作性,设计的安全性,设计的适应性和维护性这五个角度来进行分析。
首先分析第一点,设计的实用性。本设计的目的就是让管理员可以综合的处理各种基础信息,并且有相应的权限来进行操作,达到数据同步,集中管理的目的,并且可以让用户处理用户相关信息,符合设计的既定目标,达到使用效果。
其次分析第二点,设计的操作性。开发出来的系统必须有操作性,如果操作起来丢三落四,出现各种不符合流程的操作,那么就是不符合设计规则的,设计的操作性必须符合人体工程学使用原则,从上到下,从左到右,让操作起来更加的有逻辑性,不需要不符合逻辑的页面数据体验和操作流程,让设计的操作性体现出来,看到操作界面就会有相应的下一步理解。
再次是安全性,虽然从任何角度来讲,安全性应该放到第一位,但是有些时候安全性是在数据量大并且数据重要的前提下才会对数据的安全性来进行设计,正常的软件使用过程只要数据设计合理,并且目标单一,让黑客不屑于或者付出不成正比的情况下,安全性自然可以稍微降低一点,毕竟面对的使用群体决定了安全性的强度。本设计主要是从毕业设计的角度出发,增加一点数据校验的安全性就行,没必要设置硬件防火墙之类的资源,所以安全性上面也是符合的。
再次是适应性。适应性主要是面对各种平台的操作系统,目前本设计的开发可以使用本人电脑进行开发,服务器可以架设到任何地方,并且有对应的服务器软件版本。而用户方面只需要能上网,有最新版本的浏览器进行支持即可,所以适应性是相当不错的。
最后是分析维护性。这一点只需要维护服务端代码即可,每次服务端代码维护都可以先把服务器停止,然后在开发电脑上进行测试,最后测试无误再在服务器上进行部署,维护性并不会增加多少成本。
3.4 系统功能分析
当设计人员通过参考各种文献以及其他类似项目的调研后,就会对项目具体的功能进行分析,这样有的放矢可以更快的设计程序的功能。
疫情打卡健康评测系统的操作者有管理员,分析的管理员功能将使用用例图进行展示。图3.4展示了管理员用例图。管理员审核学生返校申请信息,管理学生居家,学生打卡,学生留言,试卷,试题以及学生考试信息等。
图3.4 管理员用例图
疫情打卡健康评测系统的操作者有学生,分析的学生的功能将使用用例图进行展示。图3.5展示了学生用例图。学生选择试卷进行考试,查看考试得分信息,添加学生返校申请信息,添加并管理打卡和居家信息。
图3.5 学生用例图
第4章 系统设计
在系统设计环境,业务的处理逻辑和数据的设计逻辑虽然是重中之重,但是这些都是用户看不见摸不着的,用户也只是能看到部署好的项目运行起来的结果,所以用户对界面布局以及界面功能比较看重。所以说,如今只要是开发网站不仅仅是需要懂一点页面设计就行,也需要懂得UI设计的人群。传统的网页设计其实就是换几个颜色,放几张图片,然后来充实操作页面,让操作页面不至于太单调,但是互联网发展至今,开发也越来越精细化,用户越来越挑剔,还用凑合方式来进行程序开发,已经是属于落后的状态了。
4.1 布局设计原则
布局不是传统的把页面分分类,输入和显示页面,调整调整间距这些笼统的说法了,布局设计也是有一定的原则的。
首先,布局一定要清晰合理。布局的清晰不是说图片清晰或者文字清晰,而是说用户在使用过程中,看到导航的布局,就能明白所有功能模块都可以在导航里寻找,打开一个页面,就能知道重要与不重要的资料,必须与不必须的填写,甚至是输入的格式是什么规格,都可以让用户使用的时候一目了然。因为界面是有限的,所以说布局是相当重要的一点设计原则。
其次,布局的体现要符合大众审美,比如说导航,尽量都是网页的上方或者左侧。如果把导航放到网页下方或者右方,这些代码都是可以实现,但是不符合正常人的思维定向。现代人的读写习惯都是从上而下,从左到右的阅读方式,人们身体和心灵已经习惯了这种方式,如果布局到其他方向首先用户会感到新颖,但是却不会买账,因为操作几遍后就会不习惯。
最后,布局也要考虑这个软件是用来做什么的,常用这个软件的人员的年龄划分,性别划分,以及职业划分。划分了使用人群,就可以对背景进行调色填充,如果是长时间用电脑的人群尽量设计的有护眼功能,不至于看一会眼睛就受不了,尽量要区分长时间使用和短时间使用的背景,这一点很重要。
综上所述,系统设计需要考虑方方面面,布局设计也是需要精细化考虑,系统设计需要考虑太多,但是实现却不能弄得操作上太复杂,系统设计尽量的要满足用户需要,提高用户满意度。
4.2 功能结构设计
在基于系统功能分析的基础之上,开始对系统的详细功能进行设计,最终将使用结构图的形式对设计的结果进行展示。
管理员具备的详细功能将参照最终的设计结果,即图4.1所示的管理员功能结构图。其中管理员审核学生返校申请信息,管理学生居家,学生打卡,学生留言,试卷,试题以及学生考试信息等。
图4.1 管理员功能结构图
学生具备的详细功能将参照最终的设计结果,即图4.2所示的学生功能结构图。其中学生选择试卷进行考试,查看考试得分信息,添加学生返校申请信息,添加并管理打卡和居家信息。
图4.2 学生功能结构图
4.3 数据库设计
数据库的选用方面肯定要选一个市场反应比较好,性价比比较高的数据库,不能凭空想象数据库,要结合程序设计的需求来选择对应的数据库。目前来讲,市面上常用的关系型数据库足够达到需求。
4.3.1 数据库E-R图设计
想好更好的设计出数据库使用效果,那么就要对数据的存放格式以及存放关系作出调查和梳理,所以通过分析E-R图之间的数据实体关系是最好不过的。而设计数据库E-R图是有下面几点好处:
第一点:数据的冗余是一件很恐怖的事情,所以要对有些数据进行冗余筛选;
第二点:防止内存溢出,数据量太大,需要提前做好预测并且设定好规则;
第三点:数据库一定要完整,非完整数据也只是数据垃圾而已,没有任何作用;
第四点:提高数据检索性能;
这节主要是描述对系统的E-R模型的设计,数据存储格式的判断,实现的方法,用户的需要,这些都要统一,不能想当然。并且各个模型中间的关系尤其要突出。
(1)把学生返校申请具备的属性通过属性图进行展示,绘制的属性图见图4.4。
图4.4 学生返校申请实体属性图
(2)把学生具备的属性通过属性图进行展示,绘制的属性图见图4.5。
图4.5 学生实体属性图
(3)把打卡具备的属性通过属性图进行展示,绘制的属性图见图4.6。
图4.6 打卡实体属性图
(4)把管理员具备的属性通过属性图进行展示,绘制的属性图见图4.7。
图4.7 管理员实体属性图
(5)上述实体间关系见图4.8。
图4.8 实体间关系E-R图
4.3.2 数据库表结构设计
数据库设计必须符合规范,那就是三大范式,这样能确保数据的合理:
第一范式:保证表之间的字段关系不存在混淆的描述,必须描述准确,并且单一,不能分解;
第二范式:在上述的满足条件上,主键的设计必须要在固定的列上,不能忽前忽后;
第三范式:继续满足上个条件,保证每个字段都可以根据主键获取到,并且在一个数据表里体现。
所以说,三个范式是一脉相承的,不是说零碎的,从第一个范式上就会发现,第一个永远是基础,后面的设定就是后者的实现必须在前面范式的基础之上的要求,这些设计可以最大化的减少数据冗余,提高数据库运行效率。
表4.1 打卡表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
yonghu_id | 学生 | int(11) | 是 |
daka_photo | 打卡照片 | varchar(200) | 是 |
daka_content | 打卡备注 | text | 是 |
insert_time | 打卡日期 | date | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.2 试卷表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(20) | 否 |
exampaper_name | 试卷名称 | varchar(200) | 否 |
exampaper_date | 考试时长(分钟) | int(11) | 否 |
exampaper_myscore | 试卷总分数 | int(20) | 否 |
exampaper_types | 试卷状态 | int(11) | 否 |
exampaper_delete | 逻辑删除(0代表未删除 1代表已删除) | int(255) | 是 |
create_time | 创建时间 | timestamp | 否 |
表4.3 试题表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(20) | 否 |
exampaper_id | 所属试卷id(外键) | int(20) | 否 |
examquestion_name | 试题名称 | varchar(200) | 否 |
examquestion_options | 选项,json字符串 | longtext | 是 |
examquestion_score | 分值 | int(20) | 是 |
examquestion_answer | 正确答案 | varchar(200) | 是 |
examquestion_analysis | 答案解析 | longtext | 是 |
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) | 否 |
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) | 否 |
yonghu_id | 学生 | int(11) | 是 |
fanxiaoshenqing_uuid_number | 申请编号 | varchar(200) | 是 |
insert_time | 申请时间 | timestamp | 是 |
fanxiaoshenqing_time | 申请返校日期 | date | 是 |
jiankangma_photo | 健康码 | varchar(200) | 是 |
xingchengma_photo | 行程码 | varchar(200) | 是 |
hesuanbaogao_photo | 核酸报告 | varchar(200) | 是 |
fanxiaoshenqing_content | 申请理由 | text | 是 |
fanxiaoshenqing_yesno_types | 审核状态 | int(11) | 是 |
fanxiaoshenqing_yesno_text | 审核意见 | text | 是 |
update_time | 审核时间 | timestamp | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.8 留言板表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
yonghu_id | 学生 | int(11) | 是 |
liuyan_name | 留言标题 | varchar(200) | 是 |
liuyan_text | 留言内容 | text | 是 |
insert_time | 留言时间 | timestamp | 是 |
reply_text | 回复内容 | text | 是 |
update_time | 回复时间 | timestamp | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.9 资讯信息表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
news_name | 资讯名称 | varchar(200) | 是 |
news_photo | 资讯图片 | varchar(200) | 是 |
news_types | 资讯类型 | int(11) | 否 |
insert_time | 资讯发布时间 | timestamp | 是 |
news_content | 资讯详情 | text | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.10 管理员表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | bigint(20) | 否 |
username | 用户名 | varchar(100) | 否 |
password | 密码 | varchar(100) | 否 |
role | 角色 | varchar(100) | 是 |
addtime | 新增时间 | timestamp | 否 |
表4.11 居家表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
yonghu_id | 学生 | int(11) | 是 |
xueshengjujia_zhuangtai_types | 居家状态 | int(11) | 是 |
jujia_time | 居家日期 | date | 是 |
xueshengjujia_address | 居家位置 | varchar(200) | 是 |
xueshengjujia_content | 居家备注 | text | 是 |
create_time | 创建时间 | timestamp | 是 |
表4.12 学生表
字段 | 注释 | 类型 | 空 |
---|---|---|---|
id (主键) | 主键 | int(11) | 否 |
username | 账户 | varchar(200) | 是 |
password | 密码 | varchar(200) | 是 |
yonghu_name | 学生姓名 | varchar(200) | 是 |
yonghu_phone | 学生手机号 | varchar(200) | 是 |
yonghu_id_number | 学生身份证号 | varchar(200) | 是 |
yonghu_photo | 学生头像 | varchar(200) | 是 |
sex_types | 性别 | int(11) | 是 |
yonghu_email | 电子邮箱 | varchar(200) | 是 |
create_time | 创建时间 | timestamp | 是 |
第5章 系统实现
下面主要是对系统实现的功能进行描述,一般在系统实现阶段只算是一个粗略的功能实现,可能符合开发人员的设计预期,但是对于具体使用者来讲还是需要其他人进行发现的,所以这个环节是很有必要进行描述的。
5.1 管理员功能实现
5.1.1 学生返校申请管理
实现学生返校申请管理功能,其界面运行的效果图见图5.1。在该界面,管理员修改,删除学生返校申请信息,审核学生返校申请信息,学生返校申请信息包括健康码,行程码,核酸报告等信息。
图5.1 学生返校申请管理界面
5.1.2 试卷管理
实现试卷管理功能,其界面运行的效果图见图5.2。在该界面,管理员对试卷的考试时长,试卷总分等信息进行添加,修改,管理员查询试卷需要在查询框中编辑试卷名称即可查询。
图5.2 试卷管理界面
5.1.3 试题管理
实现试题管理功能,其界面运行的效果图见图5.3。在该界面,管理员负责新增多选题,判断题,单选题等信息,以及对各种试题进行排序,可以更改,删除试题信息等。
图5.3 试题管理界面
5.1.4 留言板管理
实现留言板管理功能,其界面运行的效果图见图5.4。在该界面,管理员除了需要回复留言之外,还可以查询留言内容,删除留言等。
图5.4 留言板管理界面
5.1.5 考试管理
实现考试管理功能,其界面运行的效果图见图5.5。在该界面,管理员对学生的答题情况以及学生答题试卷所得总分信息进行查看。
图5.5 考试管理界面
5.2 学生功能实现
5.2.1 试卷表
实现试卷表功能,其界面运行的效果图见图5.6。在该界面,学生查看试卷名称,试卷总分信息,学生点击考试按钮,即可对相应试卷进行线上答题。
图5.6 试卷表界面
5.2.2 在线考试
实现在线考试功能,其界面运行的效果图见图5.7。在该界面,学生需要在规定时间内回答完试卷的试题,然后上交答卷。
图5.7 在线考试界面
5.2.3 打卡管理
实现打卡管理功能,其界面运行的效果图见图5.8。在该界面,学生每天登记打卡日期以及打卡照片等信息,能够查询,修改打卡信息。
图5.8 打卡管理界面
5.2.4 居家管理
实现居家管理功能,其界面运行的效果图见图5.9。在该界面,学生登记居家状态,居家日期,居家位置等信息,查询,修改居家信息等。
图5.9 居家管理界面
5.2.5 学生返校申请管理
实现学生返校申请管理功能,其界面运行的效果图见图5.10。在该界面,学生登记健康码,行程码,核酸检测报告等信息,查看管理员对学生返校申请的审核情况。
图5.10 学生返校申请管理界面
java">ConfigController.java
package com.controller;import java.util.Arrays;
import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import com.annotation.IgnoreAuth;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.ConfigEntity;
import com.service.ConfigService;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.ValidatorUtils;/*** 登录相关*/
@RequestMapping("config")
@RestController
public class ConfigController{@Autowiredprivate ConfigService configService;/*** 列表*/@RequestMapping("/page")public R page(@RequestParam Map<String, Object> params,ConfigEntity config){EntityWrapper<ConfigEntity> ew = new EntityWrapper<ConfigEntity>();PageUtils page = configService.queryPage(params);return R.ok().put("data", page);}/*** 列表*/@IgnoreAuth@RequestMapping("/list")public R list(@RequestParam Map<String, Object> params,ConfigEntity config){EntityWrapper<ConfigEntity> ew = new EntityWrapper<ConfigEntity>();PageUtils page = configService.queryPage(params);return R.ok().put("data", page);}/*** 信息*/@RequestMapping("/info/{id}")public R info(@PathVariable("id") String id){ConfigEntity config = configService.selectById(id);return R.ok().put("data", config);}/*** 详情*/@IgnoreAuth@RequestMapping("/detail/{id}")public R detail(@PathVariable("id") String id){ConfigEntity config = configService.selectById(id);return R.ok().put("data", config);}/*** 根据name获取信息*/@RequestMapping("/info")public R infoByName(@RequestParam String name){ConfigEntity config = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));return R.ok().put("data", config);}/*** 保存*/@PostMapping("/save")public R save(@RequestBody ConfigEntity config){
// ValidatorUtils.validateEntity(config);configService.insert(config);return R.ok();}/*** 修改*/@RequestMapping("/update")public R update(@RequestBody ConfigEntity config){
// ValidatorUtils.validateEntity(config);configService.updateById(config);//全部更新return R.ok();}/*** 删除*/@RequestMapping("/delete")public R delete(@RequestBody Long[] ids){configService.deleteBatchIds(Arrays.asList(ids));return R.ok();}
}
java">ExampaperController.java
package com.controller;import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.JSONObject;
import java.util.*;
import org.springframework.beans.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import com.service.TokenService;
import com.utils.*;
import java.lang.reflect.InvocationTargetException;import com.service.DictionaryService;
import org.apache.commons.lang3.StringUtils;
import com.annotation.IgnoreAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.entity.*;
import com.entity.view.*;
import com.service.*;
import com.utils.PageUtils;
import com.utils.R;
import com.alibaba.fastjson.*;/*** 试卷表* 后端接口* @author* @email
*/
@RestController
@Controller
@RequestMapping("/exampaper")
public class ExampaperController {private static final Logger logger = LoggerFactory.getLogger(ExampaperController.class);@Autowiredprivate ExampaperService exampaperService;@Autowiredprivate TokenService tokenService;@Autowiredprivate DictionaryService dictionaryService;//级联表service@Autowiredprivate YonghuService yonghuService;/*** 后端列表*/@RequestMapping("/page")public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));String role = String.valueOf(request.getSession().getAttribute("role"));if(false)return R.error(511,"永不会进入");else if("学生".equals(role))params.put("yonghuId",request.getSession().getAttribute("userId"));params.put("exampaperDeleteStart",1);params.put("exampaperDeleteEnd",1);if(params.get("orderBy")==null || params.get("orderBy")==""){params.put("orderBy","id");}PageUtils page = exampaperService.queryPage(params);//字典表数据转换List<ExampaperView> list =(List<ExampaperView>)page.getList();for(ExampaperView c:list){//修改对应字典表字段dictionaryService.dictionaryConvert(c, request);}return R.ok().put("data", page);}/*** 后端详情*/@RequestMapping("/info/{id}")public R info(@PathVariable("id") Long id, HttpServletRequest request){logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);ExampaperEntity exampaper = exampaperService.selectById(id);if(exampaper !=null){//entity转viewExampaperView view = new ExampaperView();BeanUtils.copyProperties( exampaper , view );//把实体数据重构到view中//修改对应字典表字段dictionaryService.dictionaryConvert(view, request);return R.ok().put("data", view);}else {return R.error(511,"查不到数据");}}/*** 后端保存*/@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,"永远不会进入");Wrapper<ExampaperEntity> queryWrapper = new EntityWrapper<ExampaperEntity>().eq("exampaper_name", exampaper.getExampaperName()).eq("exampaper_date", exampaper.getExampaperDate()).eq("exampaper_myscore", exampaper.getExampaperMyscore()).eq("exampaper_types", exampaper.getExampaperTypes()).eq("exampaper_delete", exampaper.getExampaperDelete());logger.info("sql语句:"+queryWrapper.getSqlSegment());ExampaperEntity exampaperEntity = exampaperService.selectOne(queryWrapper);if(exampaperEntity==null){exampaper.setExampaperDelete(1);exampaper.setCreateTime(new Date());exampaperService.insert(exampaper);return R.ok();}else {return R.error(511,"表中有相同数据");}}/*** 后端修改*/@RequestMapping("/update")public R update(@RequestBody ExampaperEntity exampaper, HttpServletRequest request){logger.debug("update方法:,,Controller:{},,exampaper:{}",this.getClass().getName(),exampaper.toString());String role = String.valueOf(request.getSession().getAttribute("role"));
// if(false)
// return R.error(511,"永远不会进入");//根据字段查询是否有相同数据Wrapper<ExampaperEntity> queryWrapper = new EntityWrapper<ExampaperEntity>().notIn("id",exampaper.getId()).andNew().eq("exampaper_name", exampaper.getExampaperName()).eq("exampaper_date", exampaper.getExampaperDate()).eq("exampaper_myscore", exampaper.getExampaperMyscore()).eq("exampaper_types", exampaper.getExampaperTypes()).eq("exampaper_delete", exampaper.getExampaperDelete());logger.info("sql语句:"+queryWrapper.getSqlSegment());ExampaperEntity exampaperEntity = exampaperService.selectOne(queryWrapper);if(exampaperEntity==null){exampaperService.updateById(exampaper);//根据id更新return R.ok();}else {return R.error(511,"表中有相同数据");}}/*** 删除*/@RequestMapping("/delete")public R delete(@RequestBody Integer[] ids){logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());ArrayList<ExampaperEntity> list = new ArrayList<>();for(Integer id:ids){ExampaperEntity exampaperEntity = new ExampaperEntity();exampaperEntity.setId(id);exampaperEntity.setExampaperDelete(2);list.add(exampaperEntity);}if(list != null && list.size() >0){exampaperService.updateBatchById(list);}return R.ok();}/*** 批量上传*/@RequestMapping("/batchInsert")public R save( String fileName, HttpServletRequest request){logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);Integer yonghuId = Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId")));SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");try {List<ExampaperEntity> exampaperList = new ArrayList<>();//上传的东西Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段Date date = new Date();int lastIndexOf = fileName.lastIndexOf(".");if(lastIndexOf == -1){return R.error(511,"该文件没有后缀");}else{String suffix = fileName.substring(lastIndexOf);if(!".xls".equals(suffix)){return R.error(511,"只支持后缀为xls的excel文件");}else{URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName);//获取文件路径File file = new File(resource.getFile());if(!file.exists()){return R.error(511,"找不到上传文件,请联系管理员");}else{List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件dataList.remove(0);//删除第一行,因为第一行是提示for(List<String> data:dataList){//循环ExampaperEntity exampaperEntity = new ExampaperEntity();
// exampaperEntity.setExampaperName(data.get(0)); //试卷名称 要改的
// exampaperEntity.setExampaperDate(Integer.valueOf(data.get(0))); //考试时长(分钟) 要改的
// exampaperEntity.setExampaperMyscore(Integer.valueOf(data.get(0))); //试卷总分数 要改的
// exampaperEntity.setExampaperTypes(Integer.valueOf(data.get(0))); //试卷状态 要改的
// exampaperEntity.setExampaperDelete(1);//逻辑删除字段
// exampaperEntity.setCreateTime(date);//时间exampaperList.add(exampaperEntity);//把要查询是否重复的字段放入map中}//查询是否重复exampaperService.insertBatch(exampaperList);return R.ok();}}}}catch (Exception e){e.printStackTrace();return R.error(511,"批量插入数据异常,请联系管理员");}}/*** 前端列表*/@IgnoreAuth@RequestMapping("/list")public R list(@RequestParam Map<String, Object> params, HttpServletRequest request){logger.debug("list方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));// 没有指定排序字段就默认id倒序if(StringUtil.isEmpty(String.valueOf(params.get("orderBy")))){params.put("orderBy","id");}PageUtils page = exampaperService.queryPage(params);//字典表数据转换List<ExampaperView> list =(List<ExampaperView>)page.getList();for(ExampaperView c:list)dictionaryService.dictionaryConvert(c, request); //修改对应字典表字段return R.ok().put("data", page);}/*** 前端详情*/@RequestMapping("/detail/{id}")public R detail(@PathVariable("id") Long id, HttpServletRequest request){logger.debug("detail方法:,,Controller:{},,id:{}",this.getClass().getName(),id);ExampaperEntity exampaper = exampaperService.selectById(id);if(exampaper !=null){//entity转viewExampaperView view = new ExampaperView();BeanUtils.copyProperties( exampaper , view );//把实体数据重构到view中//修改对应字典表字段dictionaryService.dictionaryConvert(view, request);return R.ok().put("data", view);}else {return R.error(511,"查不到数据");}}/*** 前端保存*/@RequestMapping("/add")public R add(@RequestBody ExampaperEntity exampaper, HttpServletRequest request){logger.debug("add方法:,,Controller:{},,exampaper:{}",this.getClass().getName(),exampaper.toString());Wrapper<ExampaperEntity> queryWrapper = new EntityWrapper<ExampaperEntity>().eq("exampaper_name", exampaper.getExampaperName()).eq("exampaper_date", exampaper.getExampaperDate()).eq("exampaper_myscore", exampaper.getExampaperMyscore()).eq("exampaper_types", exampaper.getExampaperTypes()).eq("exampaper_delete", exampaper.getExampaperDelete());logger.info("sql语句:"+queryWrapper.getSqlSegment());ExampaperEntity exampaperEntity = exampaperService.selectOne(queryWrapper);if(exampaperEntity==null){exampaper.setExampaperDelete(1);exampaper.setCreateTime(new Date());exampaperService.insert(exampaper);return R.ok();}else {return R.error(511,"表中有相同数据");}}}
java">XueshengjujiaController.java
package com.controller;import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.JSONObject;
import java.util.*;
import org.springframework.beans.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import com.service.TokenService;
import com.utils.*;
import java.lang.reflect.InvocationTargetException;import com.service.DictionaryService;
import org.apache.commons.lang3.StringUtils;
import com.annotation.IgnoreAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.entity.*;
import com.entity.view.*;
import com.service.*;
import com.utils.PageUtils;
import com.utils.R;
import com.alibaba.fastjson.*;/*** 居家* 后端接口* @author* @email
*/
@RestController
@Controller
@RequestMapping("/xueshengjujia")
public class XueshengjujiaController {private static final Logger logger = LoggerFactory.getLogger(XueshengjujiaController.class);@Autowiredprivate XueshengjujiaService xueshengjujiaService;@Autowiredprivate TokenService tokenService;@Autowiredprivate DictionaryService dictionaryService;//级联表service@Autowiredprivate YonghuService yonghuService;/*** 后端列表*/@RequestMapping("/page")public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));String role = String.valueOf(request.getSession().getAttribute("role"));if(false)return R.error(511,"永不会进入");else if("学生".equals(role))params.put("yonghuId",request.getSession().getAttribute("userId"));if(params.get("orderBy")==null || params.get("orderBy")==""){params.put("orderBy","id");}PageUtils page = xueshengjujiaService.queryPage(params);//字典表数据转换List<XueshengjujiaView> list =(List<XueshengjujiaView>)page.getList();for(XueshengjujiaView c:list){//修改对应字典表字段dictionaryService.dictionaryConvert(c, request);}return R.ok().put("data", page);}/*** 后端详情*/@RequestMapping("/info/{id}")public R info(@PathVariable("id") Long id, HttpServletRequest request){logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);XueshengjujiaEntity xueshengjujia = xueshengjujiaService.selectById(id);if(xueshengjujia !=null){//entity转viewXueshengjujiaView view = new XueshengjujiaView();BeanUtils.copyProperties( xueshengjujia , view );//把实体数据重构到view中//级联表YonghuEntity yonghu = yonghuService.selectById(xueshengjujia.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,"查不到数据");}}/*** 后端保存*/@RequestMapping("/save")public R save(@RequestBody XueshengjujiaEntity xueshengjujia, HttpServletRequest request){logger.debug("save方法:,,Controller:{},,xueshengjujia:{}",this.getClass().getName(),xueshengjujia.toString());String role = String.valueOf(request.getSession().getAttribute("role"));if(false)return R.error(511,"永远不会进入");else if("学生".equals(role))xueshengjujia.setYonghuId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));Wrapper<XueshengjujiaEntity> queryWrapper = new EntityWrapper<XueshengjujiaEntity>().eq("yonghu_id", xueshengjujia.getYonghuId()).eq("xueshengjujia_zhuangtai_types", xueshengjujia.getXueshengjujiaZhuangtaiTypes()).eq("jujia_time", new SimpleDateFormat("yyyy-MM-dd").format(xueshengjujia.getJujiaTime())).eq("xueshengjujia_address", xueshengjujia.getXueshengjujiaAddress());logger.info("sql语句:"+queryWrapper.getSqlSegment());XueshengjujiaEntity xueshengjujiaEntity = xueshengjujiaService.selectOne(queryWrapper);if(xueshengjujiaEntity==null){xueshengjujia.setCreateTime(new Date());xueshengjujiaService.insert(xueshengjujia);return R.ok();}else {return R.error(511,"表中有相同数据");}}/*** 后端修改*/@RequestMapping("/update")public R update(@RequestBody XueshengjujiaEntity xueshengjujia, HttpServletRequest request){logger.debug("update方法:,,Controller:{},,xueshengjujia:{}",this.getClass().getName(),xueshengjujia.toString());String role = String.valueOf(request.getSession().getAttribute("role"));
// if(false)
// return R.error(511,"永远不会进入");
// else if("学生".equals(role))
// xueshengjujia.setYonghuId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));//根据字段查询是否有相同数据Wrapper<XueshengjujiaEntity> queryWrapper = new EntityWrapper<XueshengjujiaEntity>().notIn("id",xueshengjujia.getId()).andNew().eq("yonghu_id", xueshengjujia.getYonghuId()).eq("xueshengjujia_zhuangtai_types", xueshengjujia.getXueshengjujiaZhuangtaiTypes()).eq("jujia_time", new SimpleDateFormat("yyyy-MM-dd").format(xueshengjujia.getJujiaTime())).eq("xueshengjujia_address", xueshengjujia.getXueshengjujiaAddress());logger.info("sql语句:"+queryWrapper.getSqlSegment());XueshengjujiaEntity xueshengjujiaEntity = xueshengjujiaService.selectOne(queryWrapper);if(xueshengjujiaEntity==null){xueshengjujiaService.updateById(xueshengjujia);//根据id更新return R.ok();}else {return R.error(511,"表中有相同数据");}}/*** 删除*/@RequestMapping("/delete")public R delete(@RequestBody Integer[] ids){logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());xueshengjujiaService.deleteBatchIds(Arrays.asList(ids));return R.ok();}/*** 批量上传*/@RequestMapping("/batchInsert")public R save( String fileName, HttpServletRequest request){logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);Integer yonghuId = Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId")));SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");try {List<XueshengjujiaEntity> xueshengjujiaList = new ArrayList<>();//上传的东西Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段Date date = new Date();int lastIndexOf = fileName.lastIndexOf(".");if(lastIndexOf == -1){return R.error(511,"该文件没有后缀");}else{String suffix = fileName.substring(lastIndexOf);if(!".xls".equals(suffix)){return R.error(511,"只支持后缀为xls的excel文件");}else{URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName);//获取文件路径File file = new File(resource.getFile());if(!file.exists()){return R.error(511,"找不到上传文件,请联系管理员");}else{List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件dataList.remove(0);//删除第一行,因为第一行是提示for(List<String> data:dataList){//循环XueshengjujiaEntity xueshengjujiaEntity = new XueshengjujiaEntity();
// xueshengjujiaEntity.setYonghuId(Integer.valueOf(data.get(0))); //学生 要改的
// xueshengjujiaEntity.setXueshengjujiaZhuangtaiTypes(Integer.valueOf(data.get(0))); //居家状态 要改的
// xueshengjujiaEntity.setJujiaTime(sdf.parse(data.get(0))); //居家日期 要改的
// xueshengjujiaEntity.setXueshengjujiaAddress(data.get(0)); //居家位置 要改的
// xueshengjujiaEntity.setXueshengjujiaContent("");//详情和图片
// xueshengjujiaEntity.setCreateTime(date);//时间xueshengjujiaList.add(xueshengjujiaEntity);//把要查询是否重复的字段放入map中}//查询是否重复xueshengjujiaService.insertBatch(xueshengjujiaList);return R.ok();}}}}catch (Exception e){e.printStackTrace();return R.error(511,"批量插入数据异常,请联系管理员");}}/*** 前端列表*/@IgnoreAuth@RequestMapping("/list")public R list(@RequestParam Map<String, Object> params, HttpServletRequest request){logger.debug("list方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));// 没有指定排序字段就默认id倒序if(StringUtil.isEmpty(String.valueOf(params.get("orderBy")))){params.put("orderBy","id");}PageUtils page = xueshengjujiaService.queryPage(params);//字典表数据转换List<XueshengjujiaView> list =(List<XueshengjujiaView>)page.getList();for(XueshengjujiaView c:list)dictionaryService.dictionaryConvert(c, request); //修改对应字典表字段return R.ok().put("data", page);}/*** 前端详情*/@RequestMapping("/detail/{id}")public R detail(@PathVariable("id") Long id, HttpServletRequest request){logger.debug("detail方法:,,Controller:{},,id:{}",this.getClass().getName(),id);XueshengjujiaEntity xueshengjujia = xueshengjujiaService.selectById(id);if(xueshengjujia !=null){//entity转viewXueshengjujiaView view = new XueshengjujiaView();BeanUtils.copyProperties( xueshengjujia , view );//把实体数据重构到view中//级联表YonghuEntity yonghu = yonghuService.selectById(xueshengjujia.getYonghuId());if(yonghu != null){BeanUtils.copyProperties( yonghu , view ,new String[]{ "id", "createDate"});//把级联的数据添加到view中,并排除id和创建时间字段view.setYonghuId(yonghu.getId());}//修改对应字典表字段dictionaryService.dictionaryConvert(view, request);return R.ok().put("data", view);}else {return R.error(511,"查不到数据");}}/*** 前端保存*/@RequestMapping("/add")public R add(@RequestBody XueshengjujiaEntity xueshengjujia, HttpServletRequest request){logger.debug("add方法:,,Controller:{},,xueshengjujia:{}",this.getClass().getName(),xueshengjujia.toString());Wrapper<XueshengjujiaEntity> queryWrapper = new EntityWrapper<XueshengjujiaEntity>().eq("yonghu_id", xueshengjujia.getYonghuId()).eq("xueshengjujia_zhuangtai_types", xueshengjujia.getXueshengjujiaZhuangtaiTypes()).eq("xueshengjujia_address", xueshengjujia.getXueshengjujiaAddress());logger.info("sql语句:"+queryWrapper.getSqlSegment());XueshengjujiaEntity xueshengjujiaEntity = xueshengjujiaService.selectOne(queryWrapper);if(xueshengjujiaEntity==null){xueshengjujia.setCreateTime(new Date());xueshengjujiaService.insert(xueshengjujia);return R.ok();}else {return R.error(511,"表中有相同数据");}}}