# test5 **Repository Path**: yu-zhiguang/test5 ## Basic Information - **Project Name**: test5 - **Description**: 高校健康上报系统 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2021-07-04 - **Last Updated**: 2022-12-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

高校健康上报系统

### **一、项目介绍** ​ 在全国人民共共同抗击新型冠状病毒疫情的严峻形势下,为了让高校师生健康信息上报,方便地了解高校师生的身体健康情况,做好高校内部的疫情防控工作与管理,很多高校都自建了健康上报系统。 ​ 本项目就是自主设计与实现一个健康上报系统,分为健康上报与健康信息管理后台。 ### **二、条件和环境** 1. JDK 8 2. Maven 3. IntelliJ IDEA 4. mybatis-plus 5. 腾讯007防水墙 6. layui 和layuimini 7. Echarts ### **三、实现结果** 健康上报 1. 登录过程 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0706/065213_2e209404_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0709/065901_325e954c_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0706/065310_8325e224_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0706/065355_d72ffa21_8879583.png "屏幕截图.png") 这里有了防止重复打卡提交。 2. 管理员注册 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/194611_8f80712f_8879583.png "屏幕截图.png") ![image-20210712194650269](C:\Users\Professor Yu.ZG\AppData\Roaming\Typora\typora-user-images\image-20210712194650269.png) 注册成功,但需要超级管理员的审核,默认注册的管理员都是停用状态。 ![image-20210712194707752](C:\Users\Professor Yu.ZG\AppData\Roaming\Typora\typora-user-images\image-20210712194707752.png) 3. 健康上报系统后台登录 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0709/070100_2001d7d6_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0709/070926_f1fdac00_8879583.png "屏幕截图.png") 登录有分为超级管理员与普通管理员:(区别就是超级管理员能管理普通管理员的信息) ![输入图片说明](https://images.gitee.com/uploads/images/2021/0706/065446_99017ded_8879583.png "屏幕截图.png") 用户增删改查: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/195205_d7440bc5_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/195323_86bc64aa_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/195406_5e01eca0_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/195518_1ffeba0f_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/195518_1ffeba0f_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/195554_73487630_8879583.png "屏幕截图.png") 删除直接点删除,弹框确认就可以删除了。 查的话就是:模糊查询,序号、账号、密码都可以一起查,这个用mybatis-plus就很好。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/195902_db15e695_8879583.png "屏幕截图.png") 还有分页功能,用IPage,还有layui工具集会识别。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200100_1f95c1d1_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200135_be0931eb_8879583.png "屏幕截图.png") 这是超级管理员的,普通管理员就没有用户信息。 接下来就是各个功能展示: 每个报表都能导出Excel表格,可以查询,和排序。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200230_0a7333e3_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200243_4d76bf3d_8879583.png "屏幕截图.png") 这是Echart的图表,可以很好呈现师生当天打卡的情况。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200423_fa2e4abc_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200512_36325588_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200522_1afebfd3_8879583.png "屏幕截图.png") 这个图表就是一周时间的打卡每天情况:会不断的更新。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200538_a37f5d88_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200555_6450897d_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/200609_6125b161_8879583.png "屏幕截图.png") 所有表都能添加删除修改查询。在健康记录里可以输入温度范围查询,如: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/201457_97c21bc9_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/201415_6a4d7875_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/201433_90b06201_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/201443_c515b6ea_8879583.png "屏幕截图.png") 排序:可以根据序号,学号,温度等,如: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/201626_c8c6119e_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/201645_c444fa9a_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/201741_b54d1f0b_8879583.png "屏幕截图.png") 导出Excel、CSV文件,如: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/201828_16f683e9_8879583.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/202039_52781005_8879583.png "屏幕截图.png") ### **四、实现代码** 代码结构 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/202333_a41e4245_8879583.png "屏幕截图.png") 静态资源: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/202443_e9720860_8879583.png "屏幕截图.png") 业务代码: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0712/202541_d0d73c42_8879583.png "屏幕截图.png") 相关依赖: ``` com.baomidou mybatis-plus-boot-starter 3.3.1.tmp org.springframework.boot spring-boot-starter-thymeleaf org.springframework spring-context-support org.springframework.boot spring-boot-starter-web mysql mysql-connector-java runtime com.alibaba fastjson 1.2.51 org.apache.httpcomponents httpclient 4.5.12 com.auth0 java-jwt 3.4.0 org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test ``` 主要代码:(因为mybatis-plus,只要mapper 有extends BaseMapper,可以不用写sql) 以StudentHealth为例: 实现首页表格显示: ``` @Override public DataVO findData(Integer page, Integer limit) { DataVO dataVO = new DataVO(); dataVO.setCode(0); dataVO.setMsg(""); //分页 IPage healthIPage = new Page<>(page,limit); IPage result = studentHealthMapper.selectPage(healthIPage,null); dataVO.setCount(result.getTotal()); //Long类型 List studentHealthList = result.getRecords(); List studentHealthVOList = new ArrayList<>(); for (StudentHealth studentHealth : studentHealthList){ StudentHealthVO studentHealthVO = new StudentHealthVO(); BeanUtils.copyProperties(studentHealth, studentHealthVO); studentHealthVOList.add(studentHealthVO); } dataVO.setData(studentHealthVOList); return dataVO; } ``` 添加: ``` @Override public Integer addStudentHealth(StudentHealth studentHealth) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper .eq("username",studentHealth.getSusername()) .eq("name",studentHealth.getSname()); Student student = studentMapper.selectOne(queryWrapper); if(student != null){ studentHealth.setSid(student.getSid()); studentHealthMapper.insert(studentHealth); return 1; }else return 0; } ``` 修改删除: ``` @Override public void updateStudentHealth(StudentHealth studentHealth) { studentHealthMapper.updateById(studentHealth); } @Override public void deleteStudentHealthByHid(Integer hid) { studentHealthMapper.deleteById(hid); } ``` 查询: ``` @Override public DataVO searchStudentHealth(Integer page, Integer limit, StudentHealth studentHealth, Float maxTemperature) { DataVO dataVO = new DataVO(); dataVO.setCode(0); dataVO.setMsg(""); if(studentHealth.getSusername()==null) studentHealth.setSusername(""); if(studentHealth.getSname()==null) studentHealth.setSname(""); if(studentHealth.getDate()==null) studentHealth.setDate(""); if(studentHealth.getArea()==null) studentHealth.setArea(""); //分页 IPage healthIPage = new Page<>(page,limit); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper .like("susername",studentHealth.getSusername()) .like("sname",studentHealth.getSname()) .like("Date",studentHealth.getDate()) .like("Area",studentHealth.getArea()); if(studentHealth.getHid()!=null){ queryWrapper .eq("hid",studentHealth.getHid()); } if(studentHealth.getSid()!=null){ queryWrapper .eq("sid",studentHealth.getSid()); } if(studentHealth.getTemperature()!=null&&maxTemperature!=null){ queryWrapper .between("temperature",studentHealth.getTemperature(),maxTemperature); }else if(studentHealth.getTemperature()!=null&&maxTemperature==null){ queryWrapper .ge("temperature",studentHealth.getTemperature()); }else if(studentHealth.getTemperature()==null&&maxTemperature!=null){ queryWrapper .le("temperature",maxTemperature); } IPage result = studentHealthMapper.selectPage(healthIPage,queryWrapper); dataVO.setCount(result.getTotal()); //Long类型 List studentHealthList = result.getRecords(); List studentHealthVOList = new ArrayList<>(); for (StudentHealth studentHealth1 : studentHealthList){ StudentHealthVO studentHealthVO = new StudentHealthVO(); BeanUtils.copyProperties(studentHealth1, studentHealthVO); studentHealthVOList.add(studentHealthVO); } dataVO.setData(studentHealthVOList); return dataVO; } ``` 腾讯007防水墙: ``` public class TCaptchaVerify { private static final String APP_ID = "这个是ID"; private static final String APP_SECRET = "这个是密钥"; private static final String VERIFY_URI = "https://ssl.captcha.qq.com/ticket/verify?aid=%s&AppSecretKey=%s&Ticket=%s&Randstr=%s&UserIP=%s"; public static int verifyTicket(String ticket, String rand, String userIp) { CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpGet; CloseableHttpResponse response = null; try { httpGet = new HttpGet(String.format(VERIFY_URI, APP_ID, APP_SECRET, URLEncoder.encode(ticket, "UTF-8"), URLEncoder.encode(rand, "UTF-8"), URLEncoder.encode(userIp, "UTF-8") )); response = httpclient.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { String res = EntityUtils.toString(entity); System.out.println(res); // 临时输出 JSONObject result = JSON.parseObject(res); // 返回码 int code = result.getInteger("response"); // 恶意等级 int evilLevel = result.getInteger("evil_level"); System.out.println(result); if (code == 1) return evilLevel; /*return code;*/ } } catch (java.io.IOException e) { // 忽略 } finally { try { response.close(); } catch (Exception ignore) { } } return -1; } } ``` HTML: ``` var captcha1 = new TencentCaptcha('2038374610', function(res) { console.log(res); if(res.ret === 0){ console.log(res.ret); $.ajax({ url: "/checkLogin", type: "POST", data:{ "ticket":res.ticket, "randstr":res.randstr }, success: function (data) { console.log("11"); if (data.result ===0) { document.getElementById("form1").submit(); /*into();//验证成功,登录验证*/ }else{ layer.msg("验证失败,请重新验证!"); // alert("验证失败,请重新验证!"); console.log("33"); } } }) }else if(res.ret===2){ layer.msg("验证已关闭,验证成功才能登录系统!"); /*alert("验证已关闭,验证成功才能登录系统!");*/ console.log("44"); } }); captcha1.show(); ``` 分页拦截器: ``` @Configuration public class MybatisPlusConfig { @Bean//分页拦截器 public PaginationInterceptor paginationInterceptor(){ return new PaginationInterceptor(); } } ``` 每天凌晨更新用户打卡状态为未打卡: ``` @Component @Service public class setClockScheduled { @Autowired private StudentMapper studentMapper; @Autowired private TeacherMapper teacherMapper; @Scheduled(cron = "0 0 0 * * ?")//每天凌晨更新clock为未打卡 public void setNotClockSchduled(){ System.out.println(new Date()); List studentList = studentMapper.selectList(null); List teacherList = teacherMapper.selectList(null); for (Student student: studentList) { student.setClock("未打卡"); studentMapper.updateById(student); }for (Teacher teacher: teacherList) { teacher.setClock("未打卡"); teacherMapper.updateById(teacher); } } } ``` 其中一周打卡情况图表: ``` ECharts
``` 实现: ``` @Override public BarVO getBarVO() { Date d=new Date(); SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd"); QueryWrapper queryWrapper1 = new QueryWrapper<>(); QueryWrapper queryWrapper2 = new QueryWrapper<>(); BarVO barVO = new BarVO(); List dateList = new ArrayList<>(); List studentClock = new ArrayList<>(); List studentNotClock = new ArrayList<>(); List teacherClock = new ArrayList<>(); List teacherNotClock = new ArrayList<>(); for (int i=6;i>=0;i--){ dateList.add(df.format(new Date(d.getTime() - (long)i * 24 * 60 * 60 * 1000))); } barVO.setDate(dateList); //学生打卡情况(一周) for (String dateStr:dateList) { queryWrapper1= queryWrapper1.eq("date",dateStr); queryWrapper2= queryWrapper2.eq("date",dateStr); Integer countStudentClock = studentHealthMapper.selectCount(queryWrapper1); Integer countStudentNotClock = studentMapper.selectCount(null)-countStudentClock; Integer countTeacherClock = teacherHealthMapper.selectCount(queryWrapper2); Integer countTeacherNotClock = teacherMapper.selectCount(null)-countTeacherClock; studentClock.add(countStudentClock); studentNotClock.add(countStudentNotClock); teacherClock.add(countTeacherClock); teacherNotClock.add(countTeacherNotClock); queryWrapper1=new QueryWrapper<>(); queryWrapper2=new QueryWrapper<>(); } barVO.setStudentClock(studentClock); barVO.setStudentNotClock(studentNotClock); barVO.setTeacherClock(teacherClock); barVO.setTeacherNotClock(teacherNotClock); return barVO; } ```