# springboot-lab5
**Repository Path**: liusibo61/springboot-lab5
## Basic Information
- **Project Name**: springboot-lab5
- **Description**: springboot实验五:疫情健康打卡及后台管理项目-后端代码
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 4
- **Forks**: 0
- **Created**: 2021-06-18
- **Last Updated**: 2024-01-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 疫情健康打卡及后台管理系统设计与实现
`学校`:东莞理工学院
`学院`:网络空间安全学院
`课程名称`:企业级开发框架专题
`指导老师`:黎志雄
`小组组名`:四弦翼声如裂帛
`班级`:18级软件卓越2班
`组长`:刘思博(201841412219)`组员`:郑沛淋(201841412228)
## 一、项目介绍及分工
一个每日健康打卡以及后台管理系统
系统部署地址(https和http):
https://8.129.221.181/#/
http://8.129.221.181/#/
管理员测试账号:
学工号:201841412219
密码:123
普通用户测试账号:
学工号:201841412213
密码:123
学工号:201841412221
密码:123
......
**技术栈:Spring Boot后端 + Spring Security权限框架 + MyBatis-Plus持久层 + Vue前端 + docker-compose部署**
分工:
1. 数据库设计:刘思博、郑沛淋
2. 后端:刘思博
3. 前端:刘思博
4. docker-compose部署:刘思博
6. 测试/其他:郑沛淋
## 二、Spring Security核心配置
```java
//所有的访问请求都要被 认证/登录
http.authorizeRequests()
//放行登录接口和注册接口
.antMatchers("/login","/user/register","/user/modifyPersonalInformation").permitAll()
.anyRequest()
.authenticated()
.and()
.logout().permitAll()
//注销处理方案(设置客户端Header中的token为空串)
.addLogoutHandler(myLogoutHandler)
//注销成功处理方案(给前端回显json处理结果)
.logoutSuccessHandler(myLogoutSuccessHandler)
//登出之后删除cookie中的内容(不使用session后可以不管cookie了)
.deleteCookies("JSESSIONID")
.and()
// 设置表单登陆相关配置
.formLogin()
//登录表单form中action的地址,也就是处理认证请求的路径
.loginProcessingUrl("/login")
//登录表单form中用户名输入框input的name名,不修改的话默认是username
.usernameParameter("username")
//登录表单form中密码输入框input的name名,不修改的话默认是password
.passwordParameter("password")
//登录成功处理方案
.successHandler(myAuthenticationSuccessHandler)
//登录失败处理方案
.failureHandler(myAuthenticationFailureHandler)
.and()
.exceptionHandling()
//未登录访问资源的处理提示
.authenticationEntryPoint(myAuthenticationEntryPoint)
//已登录,访问资源权限不足的处理提示
.accessDeniedHandler(myAccessDeniedHandler)
.and()
//自定义登录认证过滤器,前后端分离从requestBody拿参数,就要自定义一个UsernamePasswordAuthenticationFilter
.addFilter(new MyLoginFilter(authenticationManager()))
//会话管理 (session管理)
.sessionManagement()
//使用session
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
```
## 三、普通用户端
### 业务功能
注册、登录、填写体温进行当日打卡、修改个人信息
### 注册
注册提交接入腾讯防水墙的图形验证码,图形验证先进行前端验证,前端验证成功后拿到响应的随机串randStr和票据ticket,和表单信息一起传入后端注册接口,后端进行randStr和ticket的后端校验,校验成功后才操作数据库进行该用户的注册。
注册api部分展示:
### 登录
由于和管理员后台登录共用一个登录接口,所以都接入了图形验证码验证,在自定义的**UsernamePasswordAuthenticationFilter**中取到随机串randStr和票据ticket做api校验,校验成功提取出参数username和password继续执行登录逻辑,否则校验失败直接返回json给前端。
拦截登录api的自定义UsernamePasswordAuthenticationFilter部分展示:
### 打卡
后端定时任务:每天凌晨3点插入第二天的所有打卡数据,其中是否提交字段默认为0,表示未提交。当用户第二天从页面提交打卡信息时,将是否提交字段设置为1,表示今日已经提交。
表单信息进行自动填充,用户只需修改当日体温,进行提交,其他字段无法修改。
当日提交后,打卡页面就会变成锁定状态,提示今日已经打卡。当然后端的打卡接口也进行了一次判断,防止用户绕过前端限制进行重复打卡提交。
前端调用api进行表单自动填充和判断今日是否已经提交:
后端提交打卡api:
### 修改个人信息
修改个人信息api:
## 四、管理员端
### 业务功能
1.打卡功能和修改个人信息功能与普通用户相同。
2.查看当日打卡饼图:管理员可以查看当日打卡和未打卡人数的饼状图。
3.后台账号管理:对普通用户的账号进行封禁和解封;导出Excel(纯前端操作)。
4.后台打卡数据管理:根据日期查看打卡数据/查看全部打卡数据;未打卡筛选(基于当前表格);异常体温筛选(基于当前表格);根据学号进行模糊查询(基于当前表格);导出Excel(纯前端操作)
### 查看当日打卡饼图
Vue前端导入E-charts,制作饼图
统计图表(饼图)的后端api:
### 账号封禁和解封
管理员无法封禁管理员账号,只能封禁和解封普通用户的账号。
后端api:
封禁账号:
解封账号:
### 打卡记录管理
#### (a)根据日期查询打卡记录api
#### (b)根据学号模糊查询api
#### (c)体温异常筛选api(未打卡筛选类似)
#### (d)导出Excel(前端方式)
这里由于没有做分页查询,所以采用了比较灵活方便的前端方式的Excel导出。但如果做了分页查询的话,由于不能一次性拿到所有数据,就需要进行后端的Excel导出了。
前端导入第三方xlsx库和file-saver库,对前端页面的表格数据进行Excel文件的导出。
参考文章:https://mp.weixin.qq.com/s?__biz=MzA3MzU2NzA2MA==&mid=2247483910&idx=1&sn=f1a2e8e8679adfa5523240cfc52424a6&chksm=9f0c5c3da87bd52bea99fbe74e2815d831f0d701d0253d6667321a6e175a28b4766640f795da&scene=178&cur_album_id=1890522425000280064#rd
#### (e)导出Excel(后端方式)
由于后期还有空闲时间,就简单增加了后端方式的Excel导出,导出当日的打卡数据。
使用的是阿里巴巴的EasyExcel,下面是vo类配置和后端的接口api截图:
前端axios请求截图:
导出效果截图:
#### (f)打卡数据分页
由于后期还有空闲时间,就简单增加了后端分页,对所有的打卡记录进行分页(以前的打卡记录至今日的打卡记录)
分页效果截图:
后端api截图:
## 五、数据库
### 重要表结构和对应实体类
#### (a)用户表
用户实体类
#### (b)打卡记录表
打卡记录实体类
## 六、docker容器部署
### Dockerfile
编写Dockerfile构建自己的应用镜像 lab5:latest
在Dockerfile所在目录,执行命令:docker build -t lab5:latest .
应用镜像构建成功
### docker-compose.yml
在docker-compose.yml所在目录,执行命令:docker-compose up -d
访问效果截图(我个人申请的SSL证书属于自签SSL证书:由于不是CA机构签发,没有按照规定的CA/B认证,所以浏览器中显示不安全。):
### nginx容器配置和SSL配置
前端Vue项目build后部署到nginx容器中,nginx配置反向代理解决跨域,同时nginx配置了SSL证书,监听443端口,下面为nginx的配置文件:
nginx监听80端口的配置
nginx监听443端口的配置(配置SSL)
### mysql容器初始化配置
将数据库初始化的sql文件放在docker-compose.yml中映射的目录下
## 七、总结
系统采用前后端分离的方案进行编写,前端都是根据后端返回的json数据进行相对应的路由跳转和数据回显。在权限问题上,后端要进行严格的权限校验,而前端要根据后端的返回结果进行友好的提示跳转。腾讯防水墙的图形验证码在前端判断一次,在后端还要判断一次,否则就会形同虚设。
在解决跨域问题时,开发环境下,通过前端的vue.config.js中配置proxy代理来解决跨域,但是到了build打包投入到生产环境时,这个配置就失效了。这时通过配置nginx的反向代理,并将打包好的Vue项目丢入nginx默认访问的根目录就可以解决跨域请求的解析。同时,给nginx服务器配置了SSL证书并监听443端口,但在浏览器中我的SSL证书并不被浏览器信任。
在进行docker部署时,一开始我的Dockerfile中并没有配置容器内部的时区,导致项目启动起来后时间和东八区的中国时间相差了8个小时,发现了这个bug后,才在Dockerfile配置了时区为中国的时区。还有后端Excel导出,在开发环境下正常,但一旦构建镜像部署到容器后就出错了,网上一查,原来是镜像的系统缺少字体,于是又修改Dockerfile,在 镜像的系统中添加缺少的字体,最后容器启动后,后端才正常导出Excel。应用镜像构建成功后,编写docker-compose.yml文件进行多个关联容器的编排部署,最后执行docker-compose up -d命令,所有容器依次在后台启动起来,一个命令实现一键部署,非常方便。
最后,感谢老师这一学期以来的教学,使我们能够从springboot的底层自动配置原理开始学起,到各种框架的使用,以及最后的大作业体会到一个完整的项目开发和部署的过程,使我受益匪浅。
附:前端代码仓库链接
https://gitee.com/liusibo61/lab5-vue
后端代码仓库链接
https://gitee.com/liusibo61/springboot-lab5