37.后台系统-预约统计
# 需求分析
统计医院每天的预约情况,通过图表的形式展示,统计的数据都来自订单模块,在该模块封装好数据,在统计模块通过feign的形式获取数据,在实际的生成环境中,有很多种各式统计,数据来源于各个服务模块,需要一个统计模块来专门管理
# 集成ECharts
提示
ECharts的简单入门
- name: 🚀 ECharts
desc: '简单入门'
link: /pages/613bc7/
bgColor: '#DFEEE7'
textColor: '#2A3344'
2
3
4
5
安装到yygh-admin
项目中
npm install --save echarts@4.1.0
# 获取医院每天平台预约数据 service-order
# 添加实体 model
在 model
中添加统计结果的实体类
package com.stt.yygh.vo.order;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "OrderCountVo")
public class OrderCountVo {
@ApiModelProperty(value = "安排日期")
private String reserveDate;
@ApiModelProperty(value = "预约单数")
private Integer count;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
添加对应的查询类
package com.stt.yygh.vo.order;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "OrderCountQueryVo")
public class OrderCountQueryVo {
@ApiModelProperty(value = "医院编号")
private String hoscode;
@ApiModelProperty(value = "医院名称")
private String hosname;
@ApiModelProperty(value = "安排日期")
private String reserveDateBegin;
private String reserveDateEnd;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 添加mapper接口
修改 service-order
中的 OrderInfoMapper
类
package com.stt.yygh.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.stt.yygh.model.order.OrderInfo;
import com.stt.yygh.vo.order.OrderCountQueryVo;
import com.stt.yygh.vo.order.OrderCountVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface OrderInfoMapper extends BaseMapper<OrderInfo> {
List<OrderCountVo> selectOrderCount(@Param("vo") OrderCountQueryVo orderCountQueryVo);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 创建xml文件
添加对应的xml文件,创建com.stt.yygh.order.mapper.xml
包,并创建OrderInfoMapper.xml
文件,内容如下
针对不同的查询条件获取不同的统计结果
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.stt.yygh.order.mapper.OrderInfoMapper">
<select id="selectOrderCount" resultType="com.stt.yygh.vo.order.OrderCountVo">
select reserve_date as reserveDate, count(reserve_date) as count
from order_info
<where>
<if test="vo.hosname != null and vo.hosname != ''">
and hosname like CONCAT('%',#{vo.hosname},'%')
</if>
<if test="vo.reserveDateBegin != null and vo.reserveDateBegin != ''">
and reserve_date >= #{vo.reserveDateBegin}
</if>
<if test="vo.reserveDateEnd != null and vo.reserveDateEnd != ''">
and reserve_date <= #{vo.reserveDateEnd}
</if>
and is_deleted = 0
</where>
group by reserve_date
order by reserve_date
</select>
</mapper>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 修改mapper-locations配置
添加application.properties配置,需要配置xml解析的路径,用于mybatis-plus识别
mybatis-plus.mapper-locations=classpath:com/stt/yygh/order/mapper/xml/*.xml
# 添加service接口与实现
在OrderService类添加接口
package com.stt.yygh.order.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.stt.yygh.model.order.OrderInfo;
import com.stt.yygh.vo.order.OrderCountQueryVo;
import com.stt.yygh.vo.order.OrderQueryVo;
import java.util.Map;
public interface OrderService extends IService<OrderInfo> {
...
// 订单统计
Map<String, Object> getCountMap(OrderCountQueryVo orderCountQueryVo);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
对应实现
依据项目示例,从数据库中获取了统计数据,然后解析处理x轴和y轴数据给前端;如果直接给统计数据如 List<OrderCountVo>
的json形式让,前端自我解析成x和y轴,其实避免了后端和前端统计展示框架要求的数据耦合,前端后期如果要更换统计展示框架时,可能需要后端再做业务数据的转换
package com.stt.yygh.order.service.impl;
...
@Service
public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderService {
...
@Override
public Map<String, Object> getCountMap(OrderCountQueryVo orderCountQueryVo) {
List<OrderCountVo> orderCountVoList = baseMapper.selectOrderCount(orderCountQueryVo);
Map<String, Object> re = new HashMap<>(2);
//日期列表 x轴
re.put("dateList", orderCountVoList.stream()
.map(OrderCountVo::getReserveDate)
.collect(Collectors.toList()));
//统计列表 y轴
re.put("countList", orderCountVoList.stream()
.map(OrderCountVo::getCount)
.collect(Collectors.toList()));
return re;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 添加controller方法
在OrderApiController
类添加方法
package com.stt.yygh.order.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stt.yygh.common.result.Result;
import com.stt.yygh.common.utils.AuthContextHolder;
import com.stt.yygh.enums.OrderStatusEnum;
import com.stt.yygh.model.order.OrderInfo;
import com.stt.yygh.order.service.OrderService;
import com.stt.yygh.vo.order.OrderCountQueryVo;
import com.stt.yygh.vo.order.OrderQueryVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Api(tags = "订单接口")
@RestController
@RequestMapping("/api/order/orderInfo")
public class OrderApiController {
@Autowired
private OrderService service;
...
@ApiOperation(value = "获取订单统计数据")
@PostMapping("inner/getCountMap")
public Map<String, Object> getCountMap(@RequestBody OrderCountQueryVo orderCountQueryVo) {
return service.getCountMap(orderCountQueryVo);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 修改父pom文件
修改 yygh-server的pom文件
由于mybatis的自定义sql写在xml文件中,因此打包需要包含,否则会报错
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<modules>
<module>common</module>
<module>model</module>
<module>service</module>
<module>service-client</module>
<module>service-gateway</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.stt.yygh</groupId>
<artifactId>yygh_parent</artifactId>
<version>0.0.1</version>
<name>yygh_parent</name>
<packaging>pom</packaging>
<description>尚医通</description>
<properties>
...
</properties>
<!--配置dependencyManagement锁定依赖的版本-->
<dependencyManagement>
...
</dependencyManagement>
<!-- 项目打包时会将java目录中的*.xml文件也进行打包 -->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 创建模块service-order-client
由于order的统计信息可以被其他模块获取得到,因此需要添加一个外部调用的依赖
创建同service-user-client
# 修改pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>service-client</artifactId>
<groupId>com.stt.yygh</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-order-client</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>service-order-client</name>
<description>service-order-client</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 添加controller方法
package com.stt.yygh.order.client;
import com.stt.yygh.vo.order.OrderCountQueryVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.Map;
@Component
@FeignClient(value = "service-order")
public interface OrderFeignClient {
/**
* 获取订单统计数据
*/
@PostMapping("/api/order/orderInfo/inner/getCountMap")
Map<String, Object> getCountMap(@RequestBody OrderCountQueryVo orderCountQueryVo);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 搭建 service-statistics
搭建方式同service-user,该服务调用service-order进行统一的统计管理
# 配置pom
修改pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>service</artifactId>
<groupId>com.stt.yygh</groupId>
<version>0.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>1.0</version>
<artifactId>service-statistics</artifactId>
<packaging>jar</packaging>
<name>service-statistics</name>
<description>service-statistics</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.stt.yygh</groupId>
<artifactId>service-order-client</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 添加配置文件
创建application.properties文件
# 服务端口
server.port=8208
# 服务名
spring.application.name=service-statistics
# 环境设置:dev、test、prod
spring.profiles.active=dev
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=localhost:8848
2
3
4
5
6
7
8
9
# 添加启动类
创建 ServiceStatisticsApplication
类,注意 EnableFeignClients
注解的扫描包配置
package com.stt.yygh.statistics;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
@EnableDiscoveryClient
//取消数据源自动配置
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableFeignClients(basePackages = {"com.stt"})
@ComponentScan(basePackages = {"com.stt"})
public class ServiceStatisticsApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceStatisticsApplication.class, args);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 添加controller
package com.stt.yygh.statistics.controller;
import com.stt.yygh.common.result.Result;
import com.stt.yygh.order.client.OrderFeignClient;
import com.stt.yygh.vo.order.OrderCountQueryVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "统计管理接口")
@RestController
@RequestMapping("/admin/statistics")
public class StatisticsController {
@Autowired
private OrderFeignClient orderFeignClient;
@ApiOperation(value = "获取订单统计数据")
@GetMapping("getCountMap")
public Result getCountMap(@ApiParam(name = "orderCountQueryVo", value = "查询对象") OrderCountQueryVo orderCountQueryVo) {
return Result.ok(orderFeignClient.getCountMap(orderCountQueryVo));
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 添加网关配置 service-gateway
在service-gateway
的application.properties
中增加对应路由配置
spring.cloud.gateway.routes[7].id=service-statistics
spring.cloud.gateway.routes[7].uri=lb://service-statistics
spring.cloud.gateway.routes[7].predicates= Path=/*/statistics/**
2
3
# 前端实现 yygh-admin
# 封装api请求
创建/api/statistics.js
import request from '@/utils/request'
const api_name = '/admin/statistics'
export default {
getCountMap(searchObj) {
return request({
url: `${api_name}/getCountMap`,
method: 'get',
params: searchObj
})
}
}
2
3
4
5
6
7
8
9
10
11
12
13
# 创建页面组件
创建/views/statistics/order/index.vue组件
<template>
<div class="app-container">
<!--表单-->
<el-form :inline="true" class="demo-form-inline">
<el-form-item>
<el-input v-model="searchObj.hosname" placeholder="点击输入医院名称"/>
</el-form-item>
<el-form-item>
<el-date-picker v-model="searchObj.reserveDateBegin" type="date" placeholder="选择开始日期"
value-format="yyyy-MM-dd"/>
</el-form-item>
<el-form-item>
<el-date-picker v-model="searchObj.reserveDateEnd" type="date" placeholder="选择截止日期" value-format="yyyy-MM-dd"/>
</el-form-item>
<el-button :disabled="btnDisabled" type="primary" icon="el-icon-search" @click="showChart()">查询</el-button>
</el-form>
<div class="chart-container">
<div id="chart" ref="chart" class="chart" style="height:500px;width:100%"/>
</div>
</div>
</template>
<script>
import echarts from 'echarts'
import statisticsApi from '@/api/statistics'
export default {
data() {
return {
searchObj: {
hosname: '',
reserveDateBegin: '',
reserveDateEnd: ''
},
btnDisabled: false,
chart: null,
title: '',
xData: [], // x轴数据
yData: [] // y轴数据
}
},
methods: {
// 初始化图表数据
showChart() {
statisticsApi.getCountMap(this.searchObj).then(res => {
this.yData = res.data.countList
this.xData = res.data.dateList
this.setChartData()
})
},
setChartData() {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('chart'))
// 指定图表的配置项和数据
var option = {
title: {
text: this.title + '挂号量统计'
},
tooltip: {},
legend: {
data: [this.title]
},
xAxis: {
data: this.xData
},
yAxis: {
minInterval: 1
},
series: [{
name: this.title,
type: 'line',
data: this.yData
}]
}
// 使用刚指定的配置项和数据显示图表
myChart.setOption(option)
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# 添加路由
在 src/router/index.js 文件添加路由
{
path: '/statistics',
component: Layout,
redirect: '/statistics/order/index',
name: 'BasesInfo',
meta: { title: '统计管理', icon: 'table' },
alwaysShow: true,
children: [
{
path: 'order/index',
name: '预约统计',
component: () => import('@/views/statistics/order/index'),
meta: { title: '预约统计' }
}
]
},
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16