基于springboot实现的高校健康上报系统

高校健康上报系统设计与实现 0, 大作业讲解视频在根目录下 1, 项目介绍 在全国人民共同抗击新冠肺炎疫情的严峻形势下,为使高校师生健康信息及时汇报

本文包含相关资料包-----> 点击直达获取<-------

高校健康上报系统设计与实现

0. 大作业讲解视频在根目录下

1. 项目介绍

在全国人民共同抗击新冠肺炎疫情的严峻形势下,为使高校师生健康信息及时汇报,便于了解健康状况,做好高校师生内部疫情防控和管理工作,特别设计开发高校健康上报系统。

2. 需求分析

2.1 前端界面功能模块

  1. 界面美观、简洁、主题统一;
  2. 调研国内相关系统界面的输入信息,设计前端各信息录入项目;
  3. 有防止用户重复提交的功能;
  4. 有加速渲染前端界面的设计。

2.2 后端管理端功能

  1. 使用 Vue + ElementUI 实现管理后台各个功能界面;
  2. 界面简洁,主题统一;
  3. 管理员账号管理模块;
  4. 使用Spring Security安全框架实现认证、访问控制;
  5. 账号管理模块,可以锁定账号;
  6. 有解决系统高并发问题的设计;
  7. 提供大数据报表并导出Excel表格,相关人员通过报表可以一目了然查看相关信息;
  8. 所有列表可以进行综合查询,特别是时间字段,并可以排序;
  9. 所有列表可以导出excel文件或者pdf文件;
  10. 接入莞工中央认证
  11. 后台登录使用自定义图形验证码

3. 数据库设计

3.1 中央认证表

注:该表保存通过中央认证登录的用户信息【用于填写健康上报表单前的登录认证】

3.2 管理员表

3.3 健康上报表

4. 前端设计

使用技术栈:Vue + ElementUI + axios + VueX + Echart

4.1 健康上报表单设计

健康上报表单代码仓库:https://gitee.com/alizipeng/health-system-front

4.2 中台管理系统设计

中台管理系统代码仓库:https://gitee.com/alizipeng/health-system-middle

5. 后端设计

5.1 技术方案

(1)开发框架:Spring Boot、Mybatis-plus

(2)项目构建工具:Maven

(3)权限控制:Spring Security。用于对登录的用户认证授权,进行访问控制。

(4)数据缓存/NoSQL:Redis。用于缓存常用数据,如省份数据等;以及做一些NoSQL查询;使用Redis防止消息重复消费

(5)消息队列:RabbitMQ。用于异步导出查询数据,将数据导出与主业务进行 解耦 。可将数据导出模块单独部署,当数据量很大时,可以防止导出模块与主业务模块抢夺服务器资源。同时使用了 延时队列 来删除过期的导出文件。

(6)数据导出:利用MyBatis的动态SQL功能,首先传入参数生成完整SQL,再把SQL发送到队列中,等待消费者进行消费。

5.2 多模块项目结构

5.3 权限模块设计

5.3.1 中央认证安全配置

```java package com.health.central_authentication.config;

import com.health.central_authentication.filter.DGUTCheckTokenFilter; import com.health.central_authentication.handler.DGUTAccessDeniedHandler; import com.health.central_authentication.handler.DGUTAuthenticationEntryPoint; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

/* * 莞工中央认证安全配置 * @author: zipeng Li * 2021/6/14 19:53 / @Configuration @Order(99) public class DGUTSecurityConfig extends WebSecurityConfigurerAdapter { @Resource private DGUTAccessDeniedHandler dgutAccessDeniedHandler; @Resource private DGUTAuthenticationEntryPoint dgutAuthenticationEntryPoint; @Resource private DGUTCheckTokenFilter dgutCheckTokenFilter;

/**
 * 配置权限资源
 * @param http
 * @throws Exception
 */
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        // 只拦截检查'/api/user/**'的请求
        .antMatcher("/api/user/**").authorizeRequests().anyRequest().hasAuthority("USER")
        .and().csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
            .exceptionHandling()
            .authenticationEntryPoint(dgutAuthenticationEntryPoint)
            .accessDeniedHandler(dgutAccessDeniedHandler);
    http.addFilterBefore(dgutCheckTokenFilter, UsernamePasswordAuthenticationFilter.class);
}

} ```

5.3.2 后台登录安全配置

```java package com.health.admin.config;

import com.health.admin.filter.CheckTokenFilter; import com.health.admin.handler.*; import com.health.security.impl.AdminDetailsService; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

/* * 后台管理系统安全配置 * @author: zipeng Li * 2021/6/13 12:58 / @Configuration @Order(100) public class AdminSecurityConfig extends WebSecurityConfigurerAdapter { @Resource private AdminDetailsService adminDetailsService; @Resource private LoginSuccessHandler loginSuccessHandler; @Resource private LoginFailureHandler loginFailureHandler; @Resource private AdminAuthenticationEntryPoint adminAuthenticationEntryPoint; @Resource private AdminAccessDeniedHandler adminAccessDeniedHandler; @Resource private AdminLogoutSuccessHandler adminLogoutSuccessHandler; @Resource private CheckTokenFilter checkTokenFilter; @Value("${system.admin.login-url}") private String loginUrl; @Value("${system.admin.logout-url}") private String logoutUrl;

@Bean
public PasswordEncoder passwordEncoder() {
    // 明文+随机盐值》加密存储
    return new BCryptPasswordEncoder();
}


/**
 * 配置权限资源
 * @param http
 * @throws Exception
 */
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        // 只拦截检查'/api/admin/**'的请求
        .antMatcher("/api/admin/**").authorizeRequests()
            .antMatchers(loginUrl, "/api/admin/image","/api/admin/testMq").permitAll()
            .anyRequest().hasAuthority("ADMIN")
        .and().formLogin()
            .loginProcessingUrl(loginUrl)
            // 自定义的登录验证成功或失败后的去向
            .successHandler(loginSuccessHandler)
            .failureHandler(loginFailureHandler)
        .and().logout()
            .logoutUrl(logoutUrl)
            .logoutSuccessHandler(adminLogoutSuccessHandler)
            // 禁用csrf防御机制(跨域请求伪造),这么做在测试和开发会比较方便。
        .and().csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
            .exceptionHandling()
            .authenticationEntryPoint(adminAuthenticationEntryPoint)
            .accessDeniedHandler(adminAccessDeniedHandler);
    http.addFilterBefore(checkTokenFilter, UsernamePasswordAuthenticationFilter.class);
}

/**
 * 配置认证处理器
 * 自定义的UserDetailsService
 * @param auth
 * @throws Exception
 */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(adminDetailsService);
}

} ```

5.4 数据导出模块设计

5.4.1 消息队列部分设计

分为两个消费者:

DataStatsTaskReceiver 的功能为 1. 执行SQL并导出Excel文件,然后把文件上传到七牛云中,再将任务状态更新为成功,客户端便可下载文件; 2. 成功导出文件后,会给文件设置一个有效期,过期之后将从七牛云删除。具体实现为发送延时消息到延迟队列中。

DelayTaskReceiver 为延迟队列的消费者,功能为接收 DataStatsTaskReceiver 发送过来的文件ID,等到有效期到达之后,会对文件进行删除。具体实现为使用了RabbitMQ延时队列插件。

DataStatsTaskReceiver 实现: ```java @RabbitListener(queues = DataStatsTaskQueueConstants.STATS_TASK_QUEUE_NAME) public void handler(Message message, Channel channel) throws IOException { DataStatsTask dataStatsTask = (DataStatsTask) message.getPayload(); MessageHeaders headers = message.getHeaders(); Long tag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG); String msgId = (String) headers.get("spring_returned_message_correlation"); logger.info("Received Task:{}",dataStatsTask.toString()); // 设置唯一消息id,防止重复消费 if (redisTemplate.opsForHash().entries("stats_task_log").containsKey(msgId)) { //redis 中包含该 key,说明该消息已经被消费过 logger.info(msgId + ":消息已经被消费"); channel.basicAck(tag, false);//确认消息已消费 return; } String sql = dataStatsTask.getSql(); String key = dataStatsTask.getTaskId(); // 在redis中设置该任务的状态 redisTemplate.opsForHash().put("export_task",dataStatsTask.getTaskId(),"processing"); if(dbUtil.extractToExcel(sql,path,key)){ String local = path+key; String url = QiNiuUtil.upload(local,key); if(url==null){ redisTemplate.opsForHash().delete("export_task",dataStatsTask.getTaskId()); return; } redisTemplate.opsForHash().put("export_task",dataStatsTask.getTaskId(),url); // 发送延时任务 sendDelayTask(key,dataStatsTask.getExpired()); } } /* * 发送延时任务,msg为id,delayTime为文件有效期 / public void sendDelayTask(String msg,Integer delayTime){ rabbitTemplate.convertAndSend(DelayDeleteQueueConstants.DELAY_DELETE_EXCHANGE_NAME, DelayDeleteQueueConstants.DELAY_DELETE_ROUTING_KEY_NAME, msg, a ->{ a.getMessageProperties().setDelay(delayTime); return a; }); }

`DelayTaskReceiver`配置: java @Configuration public class DelayedRabbitMQConfig {

@Bean
public Queue immediateQueue() {
    return new Queue(DelayDeleteQueueConstants.DELAY_DELETE_QUEUE_NAME);
}

@Bean
public CustomExchange customExchange() {
    Map<String, Object> args = new HashMap<>();
    args.put("x-delayed-type", "direct");
    return new CustomExchange(DelayDeleteQueueConstants.DELAY_DELETE_EXCHANGE_NAME,
            "x-delayed-message", true, false, args);
}

@Bean
public Binding bindingNotify(@Qualifier("immediateQueue") Queue queue,
                             @Qualifier("customExchange") CustomExchange customExchange) {
    return BindingBuilder.bind(queue).to(customExchange)
            .with(DelayDeleteQueueConstants.DELAY_DELETE_ROUTING_KEY_NAME).noargs();
}

}

`DelayTaskReceiver`实现: java @RabbitListener(queues = DelayDeleteQueueConstants.DELAY_DELETE_QUEUE_NAME) public void handler(Message message, Channel channel) throws IOException { String taskId = String.valueOf(message.getPayload()); logger.debug("delete expired task:{}",taskId); QiNiuUtil.deleteFile(taskId); redisTemplate.opsForHash().delete("export_task",taskId); } ```

5.4.2 数据导出工具类

执行SQL,然后导出为Excel,会自动添加表头 ```java

public boolean extractToExcel(String sql,String path,String fileName){ try { ResultSet resultSet = execute(sql); ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); List > ret = new ArrayList<>(); List header = new ArrayList<>(); int colCount = resultSetMetaData.getColumnCount(); for(int i=1;i<=colCount;i++) header.add(resultSetMetaData.getColumnName(i)); // 添加表头 ret.add(header); while (resultSet.next()){ List row = new ArrayList<>(); for(int i=1;i<=colCount;i++) row.add(resultSet.getObject(i)); ret.add(row); } DataToExcel.ToExcel(ret,path,fileName); } catch (SQLException throwables) { throwables.printStackTrace(); return false; } return true; } 以下为生成SQL代码: java / * 运行期获取MyBatis执行的SQL及参数 * * @param id Mapper xml 文件里的select Id * @param obj 参数 * @param sqlSessionFactory * @return / public static String getMyBatisSql(String id, Object obj, SqlSessionFactory sqlSessionFactory) { MappedStatement ms = sqlSessionFactory.getConfiguration().getMappedStatement(id); BoundSql boundSql = ms.getBoundSql(obj); String sql = boundSql.getSql(); List parameterMappings = boundSql.getParameterMappings(); if (parameterMappings != null) { Object[] parameterArray = new Object[parameterMappings.size()]; ParameterMapping parameterMapping = null; Object value = null; Object parameterObject = null; MetaObject metaObject = null; PropertyTokenizer prop = null; String propertyName = null; String[] names = null; for (int i = 0; i < parameterMappings.size(); i++) { parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() != ParameterMode.OUT) { propertyName = parameterMapping.getProperty(); names = propertyName.split("\."); if (propertyName.indexOf(".") != -1 && names.length == 2) { parameterObject = boundSql.getAdditionalParameter(names[0]); propertyName = names[1]; } else if (propertyName.indexOf(".") != -1 && names.length == 3) { parameterObject = boundSql.getAdditionalParameter(names[0]); // map if (parameterObject instanceof Map) { parameterObject = ((Map) parameterObject).get(names[1]); } propertyName = names[2]; } else { parameterObject = boundSql.getAdditionalParameter(propertyName); } if (null == parameterObject) { parameterObject = getFieldValueByFieldName(propertyName, obj); } prop = new PropertyTokenizer(propertyName); if (parameterObject == null) { value = null; } else if (ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass())) { value = parameterObject; } else if (boundSql.hasAdditionalParameter(propertyName)) { value = boundSql.getAdditionalParameter(propertyName); } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) { value = boundSql.getAdditionalParameter(prop.getName()); } else { value = metaObject == null ? null : metaObject.getValue(propertyName); } parameterArray[i] = value; } parameterObject = null; } int i = 0; while (sql.indexOf("?") != -1) { if (null == parameterArray[i]) { throw new RuntimeException("mybatis获取sql异常"); } if (parameterArray[i] instanceof String) { sql = sql.replaceFirst("\?", "'" + parameterArray[i].toString() + "'"); } else { sql = sql.replaceFirst("\?", parameterArray[i].toString()); } i++; } int index; StringBuilder sb = new StringBuilder(); for (String s : sql.split("\n")) { index = s.indexOf("--"); if (-1 == index) { index = s.length(); } sb.append(s.substring(0, index).replace("\t", " ").trim()).append(" "); } return sb.toString().replaceAll("(\r?\n(\s \r?\n)+)", " ").replaceAll("\n", " ").replaceAll("\r", " ").replaceAll(" ", " ").replaceAll(" ", " ").replaceAll(" ", " ");

    }
    return sql;
}

Controller调用代码: java @GetMapping("/stats/temperature") public ResultVo getStatsTemperature(@RequestParam("temperature")float temperature, @RequestParam("time")String time) { SqlSessionFactory sqlSessionFactory = null; try { sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("stats-mybatis.xml")); } catch (IOException e) { e.printStackTrace(); return ResultUtils.error("Server error"); } TemperStatsParam sParam = new TemperStatsParam(); sParam.setTemperature(temperature); sParam.setTime(time); String sql = MybatisSQLUtil.getMyBatisSql("StatsMapper.getTemperStats", sParam, sqlSessionFactory); DataStatsTask dataStatsTask = new DataStatsTask(UUID.randomUUID().toString()+".xls", sql,60000); sendDataStatsTask(dataStatsTask); return ResultUtils.success(dataStatsTask.getTaskId()); } ``` Mapper:

5.5 公共模块设计

5.6 实体类

5.7 DAO层

5.8 Service层

5.9 接口层

5.10 中央认证设计

```java package com.health.central_authentication;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.health.security.CentralAuthenticationToken; import com.health.security.Student; import com.health.security.StudentService; import com.health.util.JwtUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.json.JacksonJsonParser; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.WebAttributes; import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Map;

/* * @author: zipeng Li * 2021/6/14 16:42 / @Slf4j @RestController public class CentralAuthenticationController { private static final String appid = "javaee"; private static final String appSecret = "b3b52e43ccfd"; private static final RestTemplate rest = new RestTemplate(); private static final JacksonJsonParser jsonParser = new JacksonJsonParser(); private static final String GetAccessTokenURL = "https://cas.dgut.edu.cn/ssoapi/v2/checkToken"; private static final String GetInfoURL = "https://cas.dgut.edu.cn/oauth/getUserInfo";

@Resource
private StudentService studentService;

@GetMapping("/api/central/login")
public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 重定向到中央认证
    response.sendRedirect("https://cas.dgut.edu.cn?appid=" + appid);
}

@GetMapping("/login/dgut")
public void callBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 新建未认证的 authentication
    String token = request.getParameter("token");
    CentralAuthenticationToken centralAuthenticationToken = new CentralAuthenticationToken(token);
    try {
        centralAuthenticationToken = authenticate(centralAuthenticationToken);
    } catch (AuthenticationException e) {
        // 如果校验失败providerManager会抛异常,在catch里作异常处理。
        response.sendRedirect("https://cas.dgut.edu.cn?appid=" + appid);
        return;
    }
    // 校验成功,执行后面的流程:
    SecurityContextHolder.getContext().setAuthentication(centralAuthenticationToken);
    // 移除之前认证时的错误信息
    request.getSession().removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);

    // 生产token返回
    JwtUtils jwtUtils = new JwtUtils();
    String res = jwtUtils.generateTokenByCentralAuthenticationToken(centralAuthenticationToken);
    log.info(res);
    response.sendRedirect("http://localhost:8081?token=" + res);
}

private CentralAuthenticationToken authenticate(Authentication authentication) throws AuthenticationException {
    // 1.强转 未认证的CentralAuthenticationToken
    CentralAuthenticationToken authenticationToken = (CentralAuthenticationToken) authentication;
    // 2.向中央认证服务器发送请求获取 openid 和 access_token
    LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
    map.add("token", authenticationToken.getToken());
    map.add("appid", appid);
    map.add("appsecret", appSecret);
    Map<String, Object> stringObjectMap = jsonParser.parseMap(rest.postForObject(GetAccessTokenURL, map, String.class));
    String accessToken = (String) stringObjectMap.get("access_token");
    String openid = (String) stringObjectMap.get("openid");
    // 3.向中央认证服务器发送请求获取个人信息
    map.clear();
    map.add("access_token", accessToken);
    map.add("openid", openid);
    Map<String, Object> objectMap = jsonParser.parseMap(rest.postForObject(GetInfoURL, map, String.class));
    // 4.认证成功,重新生产 authentication
    Student student = new Student();
    student.setUsername((String)objectMap.get("username"));
    student.setName((String)objectMap.get("name"));
    student.setWxOpenid((String)objectMap.get("wx_openid"));
    student.setFacultyTitle((String)objectMap.get("faculty_title"));
    student.setOpenid((String)objectMap.get("openid"));
    // 5. 判断数据库是否已经存在该用户
    QueryWrapper<Student> wrapper = new QueryWrapper<>();
    wrapper.lambda().eq(Student::getUsername, student.getUsername());
    studentService.saveOrUpdate(student, wrapper);

    return new CentralAuthenticationToken(student, AuthorityUtils.createAuthorityList("USER"));
}

} ```

5.11 其他核心接口设计

5.11.1 后台管理相关

```java /* * 管理员控制器 * @author: zipeng Li * 2021/6/13 15:50 / @Slf4j @RestController @RequestMapping("/api/admin") public class AdminController { @Resource private DefaultKaptcha defaultKaptcha; @Resource private AdminService adminService; @Resource private StudentService studentService; @Resource private ReportFormService reportFormService; @Resource private PasswordEncoder passwordEncoder; @Autowired StringRedisTemplate redisTemplate;

@Autowired
RabbitTemplate rabbitTemplate;

@GetMapping("/stats/temperature")
public ResultVo getStatsTemperature(@RequestParam("temperature")float temperature,
                                    @RequestParam("time")String time)  {
    SqlSessionFactory sqlSessionFactory = null;
    try {
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("stats-mybatis.xml"));
    } catch (IOException e) {
        e.printStackTrace();
        return ResultUtils.error("Server error");
    }
    TemperStatsParam sParam = new TemperStatsParam();
    sParam.setTemperature(temperature);
    sParam.setTime(time);
    String sql = MybatisSQLUtil.getMyBatisSql("StatsMapper.getTemperStats", sParam, sqlSessionFactory);
    DataStatsTask dataStatsTask = new DataStatsTask(UUID.randomUUID().toString()+".xls",
            sql,60000);
    sendDataStatsTask(dataStatsTask);
    return ResultUtils.success(dataStatsTask.getTaskId());
}

@GetMapping("/stats/region")
public ResultVo getStatsTemperature(@RequestParam("country")String country,
                                    @RequestParam(value = "province",required = false)String province,
                                    @RequestParam(value = "district",required = false)String district)  {
    SqlSessionFactory sqlSessionFactory = null;
    try {
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("stats-mybatis.xml"));
    } catch (IOException e) {
        e.printStackTrace();
        return ResultUtils.error("Server error");
    }
    RegionStatsParam sParam = new RegionStatsParam();
    sParam.setCountry(country);
    sParam.setProvince(province);
    sParam.setDistrict(district);
    String sql = MybatisSQLUtil.getMyBatisSql("StatsMapper.getRegionStats", sParam, sqlSessionFactory);
    DataStatsTask dataStatsTask = new DataStatsTask(UUID.randomUUID().toString()+".xls",
            sql,60000);
    sendDataStatsTask(dataStatsTask);
    return ResultUtils.success(dataStatsTask.getTaskId());
}

@GetMapping("/stats/task")
public ResultVo getStatsFileId(@RequestParam("id")String id){
    String url = String.valueOf(redisTemplate.opsForHash().get("export_task",id));
    log.info(url);
    if(url.equals("null"))
        return ResultUtils.error("任务不存在");
    else if(url.equals("process"))
        return ResultUtils.error("任务导出中");
    else
        return ResultUtils.success("导出成功,请在10分钟内下载",url);
}

/**
 * 后台登录,获取图形验证码
 * @param request
 * @param response
 * @throws IOException
 */
@RequestMapping("image")
public void imageCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
    //设置页面缓存方式   不缓存,不存储
    response.setHeader("Cache-Control","no-store, no-cache");
    //设置以图片的形式响应
    response.setContentType("image/jpeg");
    //1.获取验证码字符
    String text = defaultKaptcha.createText();
    log.info("获取验证码:" + text);
    //2.存储到session中
    request.getSession().setAttribute("code",text);
    //3.生成验证码图片
    BufferedImage image = defaultKaptcha.createImage(text);
    //4.输出给前端
    ServletOutputStream out = response.getOutputStream();
    ImageIO.write(image,"jpg",out);
    if(out != null){
        out.close();
    }
}

/**
 * 添加管理员
 * @param admin
 * @return
 */
@PostMapping("add-admin")
public ResultVo addAdmin(@RequestBody Admin admin){
    // 检查权限
    Admin principal =(Admin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    if(! "1".equals(principal.getIsAdmin())){
        return ResultUtils.error("无此操作权限");
    }
    //查询用户是否存在
    Admin one = adminService.getAdminByUserName(admin.getUsername());
    if(one != null){
        return ResultUtils.error("用户名已经存在!");
    }
    //加密用户密码
    String pwd = passwordEncoder.encode(admin.getPassword());
    admin.setPassword(pwd);
    boolean b = adminService.save(admin);
    if(b){
        return ResultUtils.success("新增管理员成功");
    }else{
        return ResultUtils.error("新增管理员失败");
    }
}

/**
 * 管理员锁定
 * @param lockAdmin
 * @return
 */
@PostMapping("lock-admin")
public ResultVo LockAdmin(@RequestBody LockAdmin lockAdmin){
    // 检查权限
    Admin principal =(Admin) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    if(! "1".equals(principal.getIsAdmin())){
        return ResultUtils.error("无此操作权限", CodeStatus.NO_AUTH);
    }
    // 检查是否存在该用户
    Admin admin = adminService.getById(lockAdmin.getId());
    if (admin == null) {
        return ResultUtils.error("不存在该用户", CodeStatus.ERROR_CODE);
    }
    // 锁定用户
    admin.setAccountNonLocked(lockAdmin.isLock());
    adminService.saveOrUpdate(admin);
    return ResultUtils.success(lockAdmin.isLock()?"解锁成功":"锁定成功");
}

/**
 * 管理员列表
 * @param parm
 * @return
 */
@PostMapping("list")
public ResultVo getList(@RequestBody ParmVo parm){
    IPage<Admin> page = new Page<>();
    page.setCurrent(parm.getStartIndex());
    page.setSize(parm.getPageSize());

    IPage<Admin> adminIPage = adminService.page(page);
    return ResultUtils.success("查询成功", adminIPage);
}

/**
 * 用户列表
 * @param parm
 * @return
 */
@PostMapping("student-list")
public ResultVo getStudentList(@RequestBody ParmVo parm){
    IPage<Student> page = new Page<>();
    page.setCurrent(parm.getStartIndex());
    page.setSize(parm.getPageSize());

    IPage<Student> adminIPage = studentService.page(page);
    return ResultUtils.success("查询成功", adminIPage);
}

void sendDataStatsTask(DataStatsTask dataStatsTask) {
    rabbitTemplate.convertAndSend(DataStatsTaskQueueConstants.STATS_TASK_EXCHANGE_NAME,
            DataStatsTaskQueueConstants.STATS_TASK_ROUTING_KEY_NAME, dataStatsTask, a -> {
                a.getMessageProperties().setCorrelationId(dataStatsTask.getTaskId());
                return a;
            });
}
/**
 * 获取填报列表
 * @param parmVo
 * @return
 */
@PostMapping("report-list")
public ResultVo reportList(@RequestBody ParmVo parmVo){

    IPage<ReportForm> page = new Page<>();
    page.setCurrent(parmVo.getStartIndex());
    page.setSize(parmVo.getPageSize());

    IPage<ReportForm> adminIPage = reportFormService.page(page);
    return ResultUtils.success("查询成功", adminIPage);
}

/**
 * 获取表单详情
 * @param id
 * @return
 */
@GetMapping("report-detail")
public ResultVo reportDetail(@RequestParam Long id){
    ReportForm reportForm = reportFormService.getById(id);
    Student student = studentService.getById(reportForm.getCentralAuthenticationId());

    HashMap<String, Object> map = new HashMap<>();
    map.put("reportForm", reportForm);
    map.put("student", student);

    return ResultUtils.success("查询成功", map);
}

/**
 * 获取统计数据
 * @return
 */
@GetMapping("statistical-data")
public ResultVo reportDetail(){
    // 获取用户人数
    Integer studentNumber = studentService.list().size();
    // 获取管理员人数
    Integer adminNumber = adminService.list().size();
    // 获取今日填报人数
    Integer dayRecord = reportFormService.getDayRecords();
    // 获取风险人数
    Integer dangerNumber = reportFormService.getDangerNumber();

    HashMap<Object, Object> map = new HashMap<>(4);
    map.put("studentNumber", studentNumber);
    map.put("adminNumber", adminNumber);
    map.put("dayRecord", dayRecord);
    map.put("dangerNumber", dangerNumber);

    return ResultUtils.success("获取统计信息", map);

}

}

```

5.11.2 表单相关

```java /* * @author: zipeng Li * 2021/6/16 11:48 / @Slf4j @RestController @RequestMapping("/api/user") public class StudentController {

@GetMapping("student-info")
public ResultVo studentInfo(){
    CentralAuthenticationToken authentication = (CentralAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
    return ResultUtils.success("获取用户信息成功", authentication.getStudent());
}

}

/* * @author: zipeng Li * 2021/6/20 16:53 / @Slf4j @RestController @RequestMapping("/api/user") public class reportController { @Resource private ReportFormService reportFormService;

/**
 * 提交表单
 * @param reportForm
 * @return
 */
@PostMapping("report-form")
public ResultVo reportForm(@RequestBody ReportForm reportForm){
    // 判断当前用户是否已经提交
    CentralAuthenticationToken authentication = (CentralAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
    Student student = authentication.getStudent();

    ReportForm one = reportFormService.getDayRecord(student.getId());
    if (one != null) return ResultUtils.error("当日已经打卡,勿重复提交");

    // 保存数据库
    reportForm.setCentralAuthenticationId(student.getId());
    reportForm.setName(student.getName());
    reportFormService.save(reportForm);
    return ResultUtils.success("打卡成功");
}

/**
 * 判断今天是否提交成功
 * @return
 */
@PostMapping("check-report")
public ResultVo checkReport(){
    // 判断当前用户是否已经提交
    CentralAuthenticationToken authentication = (CentralAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
    Student student = authentication.getStudent();
    ReportForm one = reportFormService.getDayRecord(student.getId());
    if (one != null) return ResultUtils.success("您今天已经提交成功啦", true);
    return ResultUtils.success("您今天还没提交哦", false);
}

} ```

5.11.3

参考文献

  • 基于Web的智能校园的研究和应用(武汉理工大学·刘玲)
  • 基于微服务的健康管理平台的研究与设计(北京邮电大学·陈乾)
  • 基于SSH技术的新生报到信息平台的设计与实现(大连海事大学·柴怡霖)
  • 基于UML的教务管理系统分析与设计(南京理工大学·陈芬)
  • 基于Java EE平台的个人健康信息管理系统设计与实现(南京邮电大学·贾顺贺)
  • 基于Spring框架的短信通道系统的设计与实现(北京邮电大学·刘林华)
  • 基于ssh2架构的科研管理系统研究与实现(电子科技大学·龚强)
  • 在线学习过程管理系统软件设计与实现(北京邮电大学·王嘉康)
  • 基于混合MVC框架的校园网单点登录系统的设计与实现(电子科技大学·张蓉)
  • 基于微服务的校园应用门户网站的设计与实现(黑龙江大学·云岩)
  • 基于Spring Boot的校园轻博客系统的设计与实现(华中科技大学·邓笑)
  • 学生综合信息管理平台的设计与实现(吉林大学·刘铁刚)
  • 基于SSH技术的新生报到信息平台的设计与实现(大连海事大学·柴怡霖)
  • 基于微服务架构的校园网系统的设计与实现(安徽建筑大学·马红国)
  • 基于微服务的健康管理平台的研究与设计(北京邮电大学·陈乾)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:毕设客栈 ,原文地址:https://m.bishedaima.com/yuanma/35681.html

相关推荐

发表回复

登录后才能评论