一、基于Springboot MybatisPlus Echarts Mysql实现校园疫情管理系统
【】
该项目基于springboot该框架在疫情背景下实现校园管理,主要涵盖中国疫情确诊分布地图(与腾讯对接)API接口)、中国实时疫情新闻播报、饼图、折线图、柱状图展示疫情数据。系统角色可以添加、删除和检查,并将菜单权限分配给角色,大致分为学生、教师和系级系统管理员。shiro框架实现了不同的角色,可以赋予不同的菜单栏权限,可以完成菜单栏的动态增删,实现动态权限设置。
基于校园疫情数据管理,mybatiplus框架实现了疫情数据的有条件查询和分页的增删改查,实现了拖拽上传excel疫情数据和导出数据。相关功能主要包括疫情数据管理、疫情新闻管理、疫情图表显示管理、学生健康打卡管理、系管理、班级管理、核酸检测管理、疫苗接种管理、学生请假管理等。系统管理主要包括用户管理、角色管理和菜单管理。
在数据库设计中,主要设计了用户与角色之间的多对多实体关系,以及角色与菜单之间的多对多关系设计。其中,学生请假功能设计了详细的审批流程。学生提交审批流程后,教师在部门审批后进行审批节点的状态和审批流程的审批逻辑。
在缓存设计中,中国疫情地图和新闻地图和新闻播报首页主要进行redis为了保证数据缓存redis缓存与mysql每当定时任务触发分析腾讯的数据一致性时API接口数据时,每次更新数据库数据,都要删除一次redis缓存,这样,客户端就可以访问数据库更新最新的缓存数据。
在接口设计中RestFul风格结构使要求路径更简单,更方便传输和获取参数值。参数值直接通过要求路径传输,不会暴露传输方法的参数变量名,接口更安全。
**Java:**JDK1.8
**开发工具:**Idea、Navicat、Maven3.6
**前端框架:**layui框架
**后端框架:**Springboot、MybatisPlus、Shiro、Httpclient爬虫
**数据库:**Mysql5.7及其以上
源码: 讲解地址:https://www.bilibili.com/video/BV1aY411c7d1?share_source=copy_web
1.1 构建springboot项目
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency>
spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/nocv?serverTimezone=UTC&useSSL=false&characterEncoding=utf-8 driver-class-name: com.mysql.jdbc.Driver
1.2 引入Echarts地图
1.官网:https://echarts.apache.org/zh/ 下载JS项目介绍文件 2.查看图例 3.快速使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- 引入刚刚下载的 ECharts 文件 -->
<script src="echarts.js"></script>
</head>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>ECharts</title>
<!-- 引入刚刚下载的 ECharts 文件 -->
<script src="echarts.js"></script>
</head>
<body>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript"> // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main')); // 指定图表的配置项和数据 var option = {
title: {
text: 'ECharts 入门示例' }, tooltip: {
}, legend: {
data: ['销量'] }, xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {
}, series: [ {
name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); </script>
</body>
</html>
:http://www.isqqw.com/
1.3 创建数据库
DROP TABLE IF EXISTS `nocv_data`;
CREATE TABLE `nocv_data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`value` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of nocv_data
-- ----------------------------
INSERT INTO `nocv_data` VALUES ('1', '澳门', '95');
INSERT INTO `nocv_data` VALUES ('2', '香港', '35');
INSERT INTO `nocv_data` VALUES ('3', '台湾', '153');
INSERT INTO `nocv_data` VALUES ('4', '新疆', '56');
INSERT INTO `nocv_data` VALUES ('5', '宁夏', '26');
INSERT INTO `nocv_data` VALUES ('6', '青海', '26');
1.4 编写代码
springboot
contRoller: /query
service:
dao:
entity:
1.5 展示数据
$.ajax({
url: "/query",
dataType: "json",
success: function (data) {
// 某种意义上来说,数组也是object
for (let i in data) {
dataList[i] = data[i];
}
myChart.setOption({
series: [
{
name: "确诊病例",
type: "map",
geoIndex: 0,
data: dataList
}
]
});
}
});
七、中国疫情地图增删改查
7.1 分页配置MybatisPlusConfig
@Configuration
@ConditionalOnClass(value = {
PaginationInterceptor.class})
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
7.2 layui返回的数据格式 DataView
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DataView {
private Integer code = 0;
private String msg = "";
private Long count = 0L;
private Object data;
public DataView(Long count,Object data){
this.count = count;
this.data = data;
}
public DataView(Object data){
this.data = data;
}
}
八、疫情打卡上报管理
8.1 引入静态打卡HTML页面
九、实现拖拽Excel导入疫情数据功能
9.1 引入pom依赖
<!--引入poi-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.0</version>
</dependency>
9.2 引入layui 的拖拽上传Excel组件
* Excel的拖拽或者点击上传
* 1.前台页面发送一个请求,上传文件MutilpartFile HTTP
* 2.Controller,上传文件MutilpartFile 参数
* 3.POI 解析文件,里面的数据一行一行全部解析出来
* 4.每一条数据插入数据库
* 5.mybatiplus 批量saveBatch(list)
<div class="layui-upload-drag" id="test10">
<i class="layui-icon"></i>
<p>点击上传,或将文件拖拽到此处</p>
<div class="layui-hide" id="uploadDemoView">
<hr>
<img src="" alt="上传成功后渲染" style="max-width: 196px">
</div>
</div>
layui.use(['upload','jquery'],function(){
var layer = layui.layer //弹层
,$ = layui.jquery
,upload = layui.upload
//拖拽上传
upload.render({
elem: '#test10'
,url: '/excelImport'
,accept: 'file' //普通文件
,done: function(res){
layer.msg('上传成功');
console.log(res);
}
});
9.2 编写Controller
// Excel数据导入
@RequestMapping(value = "/excelImport", method = RequestMethod.POST)
@ResponseBody
public DataView uploadExcel(@RequestParam("file") MultipartFile file) {
DataView dataView = new DataView();
if (file.isEmpty()) {
dataView.setMsg("文件为空");
return dataView;
}
try {
//根据路径获取这个操作excel的实例
HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());
HSSFSheet sheet = wb.getSheetAt(0);
//实体类集合
List<NocvData> listData = new ArrayList<>();
HSSFRow row = null;
//循环sesheet页中数据从第二行开始,第一行是标题
for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
//获取每一行数据
row = sheet.getRow(i);
NocvData data = new NocvData();
data.setName(row.getCell(0).getStringCellValue());
data.setValue(Integer.valueOf((int) row.getCell(1).getNumericCellValue()));
listData.add(data);
}
//循环展示导入的数据,实际应用中应该校验并存入数据库
indexService.saveBatch(listData);
dataView.setCode(200);
dataView.setMsg("导入成功");
return dataView;
} catch (Exception e) {
e.printStackTrace();
}
dataView.setCode(100);
dataView.setMsg("导入失败");
return dataView;
}
9.4 数据导出Excel功能【中国疫情数据】
1.前端发送请求 /
2.后端查询数据库,封装数据Excel实体
3.返回数据建立输出,写出浏览器文件
// 导出疫情数据
form.on("submit(doExport)",function () {
window.location.href="/excelOutportChina";//这里是接口的地址
})
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doExport"><i class="layui-icon layui-icon-search layui-icon-normal"></i>导出中国疫情数据Excel
</button>
@RequestMapping("/excelOutportChina")
@ResponseBody
public void excelOutportChina(HttpServletResponse response){
response.setCharacterEncoding("UTF-8");
List<NocvData> list = indexService.list();
HSSFWorkbook wb = new HSSFWorkbook();
//2-创建sheet页,设置sheet页的名字
HSSFSheet sheet = wb.createSheet("中国数据表");
//3-创建标题行
HSSFRow titleRow = sheet.createRow(0);
titleRow.createCell(0).setCellValue("城市名称");
titleRow.createCell(1).setCellValue("确诊数量");
//4-遍历将数据集合将数据放到对应的列中
for (NocvData data : list){
HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum()+1);
dataRow.createCell(0).setCellValue(data.getName());
dataRow.createCell(1).setCellValue(data.getValue());
}
// 5.建立输出
OutputStream os = null;
try{
//6-设置Excel的名称
response.setContentType("application/octet-stream;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename="
+ new String("中国疫情数据表".getBytes(),"iso-8859-1") + ".xls");
os = response.getOutputStream();
wb.write(os);
os.flush();
}catch(Exception e){
e.printStackTrace();
} finally {
try {
if(os != null){
os.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
十、对接腾讯API接口实现疫情数据实时更新
十、打开腾讯数据网址腾讯实时疫情
**主页网址:**https://news.qq.com/zt2020/page/feiyan.htm#/global
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-66dqclsu-1655813236195)(C:\Users\15067\AppData\Local\Temp\1654132815620.png)]
**腾讯数据接口:**https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5
**网易数据接口:**https://c.m.163.com/ug/api/wuhan/app/data/list-total
10.1 网络爬虫对接 【腾讯】API接口
<!--httpClient客户端-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
@Component
public class HttpUtils {
@Bean
public String getData() throws IOException {
//请求参数设置
RequestConfig requestConfig = RequestConfig.custom()
//读取目标服务器数据超时时间
.setSocketTimeout(10000)
//连接目标服务器超时时间
.setConnectTimeout(10000)
//从连接池获取连接的超时时间
.setConnectionRequestTimeout(10000)
.build();
CloseableHttpClient httpClient = null;
HttpGet request = null;
CloseableHttpResponse response = null;
try {
//创建HttpClient
httpClient = HttpClients.createDefault();<