# 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); ``` ## 三、普通用户端 ### 业务功能 注册、登录、填写体温进行当日打卡、修改个人信息 ### 注册 image-20210628110157259 注册提交接入腾讯防水墙的图形验证码,图形验证先进行前端验证,前端验证成功后拿到响应的随机串randStr和票据ticket,和表单信息一起传入后端注册接口,后端进行randStr和ticket的后端校验,校验成功后才操作数据库进行该用户的注册。 注册api部分展示: image-20210628110445121 ### 登录 image-20210628110532691 由于和管理员后台登录共用一个登录接口,所以都接入了图形验证码验证,在自定义的**UsernamePasswordAuthenticationFilter**中取到随机串randStr和票据ticket做api校验,校验成功提取出参数username和password继续执行登录逻辑,否则校验失败直接返回json给前端。 拦截登录api的自定义UsernamePasswordAuthenticationFilter部分展示: image-20210628110824492 ### 打卡 后端定时任务:每天凌晨3点插入第二天的所有打卡数据,其中是否提交字段默认为0,表示未提交。当用户第二天从页面提交打卡信息时,将是否提交字段设置为1,表示今日已经提交。 image-20210628110945413 表单信息进行自动填充,用户只需修改当日体温,进行提交,其他字段无法修改。 当日提交后,打卡页面就会变成锁定状态,提示今日已经打卡。当然后端的打卡接口也进行了一次判断,防止用户绕过前端限制进行重复打卡提交。 image-20210628111109680 前端调用api进行表单自动填充和判断今日是否已经提交: image-20210628111329009 后端提交打卡api: image-20210628111630497 ### 修改个人信息 image-20210628111754356 修改个人信息api: image-20210628111851179 image-20210628112101467 ## 四、管理员端 ### 业务功能 1.打卡功能和修改个人信息功能与普通用户相同。 2.查看当日打卡饼图:管理员可以查看当日打卡和未打卡人数的饼状图。 3.后台账号管理:对普通用户的账号进行封禁和解封;导出Excel(纯前端操作)。 4.后台打卡数据管理:根据日期查看打卡数据/查看全部打卡数据;未打卡筛选(基于当前表格);异常体温筛选(基于当前表格);根据学号进行模糊查询(基于当前表格);导出Excel(纯前端操作) ### 查看当日打卡饼图 Vue前端导入E-charts,制作饼图 image-20210628113431764 统计图表(饼图)的后端api: image-20210628113725814 image-20210628113703647 ### 账号封禁和解封 管理员无法封禁管理员账号,只能封禁和解封普通用户的账号。 image-20210628112345190 后端api: 封禁账号: image-20210628112546958 解封账号: image-20210628112629927 ### 打卡记录管理 image-20210628113922316 #### (a)根据日期查询打卡记录api image-20210628114209831 image-20210628114248800 #### (b)根据学号模糊查询api image-20210628114504401 image-20210628114537208 #### (c)体温异常筛选api(未打卡筛选类似) image-20210628114624163 image-20210628114702080 #### (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 image-20210628114748378 image-20210628114812760 #### (e)导出Excel(后端方式) 由于后期还有空闲时间,就简单增加了后端方式的Excel导出,导出当日的打卡数据。 使用的是阿里巴巴的EasyExcel,下面是vo类配置和后端的接口api截图: image-20210702114611872 image-20210702114739256 前端axios请求截图: image-20210702115050371 导出效果截图: image-20210702114948994 #### (f)打卡数据分页 由于后期还有空闲时间,就简单增加了后端分页,对所有的打卡记录进行分页(以前的打卡记录至今日的打卡记录) 分页效果截图: image-20210702115702579 image-20210702115724145 后端api截图: image-20210702115916051 ## 五、数据库 ### 重要表结构和对应实体类 image-20210702120842181 #### (a)用户表 image-20210628115159946 用户实体类 image-20210628114927442 #### (b)打卡记录表 image-20210628115225054 打卡记录实体类 image-20210628115003260 ## 六、docker容器部署 ### Dockerfile 编写Dockerfile构建自己的应用镜像 lab5:latest image-20210702154818233 在Dockerfile所在目录,执行命令:docker build -t lab5:latest . 应用镜像构建成功 image-20210628120106564 image-20210628120124466 ### docker-compose.yml image-20210628120214509 在docker-compose.yml所在目录,执行命令:docker-compose up -d image-20210628120305370 image-20210628120322813 访问效果截图(我个人申请的SSL证书属于自签SSL证书:由于不是CA机构签发,没有按照规定的CA/B认证,所以浏览器中显示不安全。): image-20210628120428387 ### nginx容器配置和SSL配置 前端Vue项目build后部署到nginx容器中,nginx配置反向代理解决跨域,同时nginx配置了SSL证书,监听443端口,下面为nginx的配置文件: nginx监听80端口的配置 image-20210628120528459 nginx监听443端口的配置(配置SSL) image-20210628120544685 ### mysql容器初始化配置 将数据库初始化的sql文件放在docker-compose.yml中映射的目录下 image-20210628120624257 ## 七、总结 ​ 系统采用前后端分离的方案进行编写,前端都是根据后端返回的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