项目中集成ECharts图表(通过定时任务SpringTask统计每天的订单金额)
项目应用Echarts
①、前端终端安装Echarts
npm install echarts --save
②、src/views创建order目录,在order目录下创建orderStatistics.vue
③、src/router/modules目录下创建order.js,配置路由
const layout = ()=>import('@/layout/index.vue')
const orderStatistics = ()=>import('@/views/order/orderStatistics.vue')
export default[
{
path:'/order',
component:Layout,
name:'order',
meta:{
title:'订单管理',
},
icon:'Operation',
children:[
{
path:'orderStatistics',
name:'orderStatistics',
component:orderStatistics,
meta:{
title:'订单统计',
}
}
],
},
]
④、src/router/index.js中添加订单管理路由
import order from './mudules/order'
//动态菜单
export const asyncRoutes = [...system,...product,...order]
⑤、页面
api/orderInfo.js
import request from '@/utils/request'
const api_name = '/admin/order/orderInfo'
//订单统计
export const GetOrderStatisticsData = searchObj => {
return request({
url:`${api_name}/getOrerStatisticsData`,
method:'get',
params:searchObj,
})
}
<template>
<div ref="orderTotalAmountDiv" style="width:100%;height:100%"></div>
</template>
<script setup>
import {ref,onMounted} from 'vue'
import * as echarts from 'echarts'//导入Echart的图形报表组件
//定义chart数据模型,用来选中div组件
const orderTotalAmountDiv = ref()
//需要在onMounted钩子函数对div区域使用echarts进行初始化
onMounted(()=>{
//基于准备好的dom,初始化echarts实例
var orderTotalAmountChart = echarts.init(orderTotalAmountDiv.value);
//绘制图表
orderTotalAmountChart.setOption({
title:{
text:'订单数据统计'
},
tooltip:{},
xAxis:{
//data:['','','','','','']
data:dateList
},
yAxis:{},
series:[{
name:'订单总金额(万元)',
type:'bar',
//data:[20,40,30,100,50,25]
data:amountList,
}]
});
})
</script>
⑥、统计每天的订单总金额
SELECT o.create_time,SUM(o.total_amount) AS totalAmount
FROM order_info o
GROUP BY DATA_FORMAT(o.o.create_time,'%Y-%m-%d')
ORDER BY DATA_FORMAT(o.o.create_time,'%Y-%m-%d')
每一次展示数据的时候都从订单数据库进行一次统计查询,如果数据量过大,分组查询受到性能影响
所以通过分组结果计算好,写入到一张统计结果表中进行优化
项目启动类添加注解@EnableScheduling开启定时任务
@Component
public class OrderStatisticsTask{
@Autowired
private OrderInfoMapper orderInfoMapper;
@Autowried
private OrderStatisticsMapper orderStatisticsMapper;
//每天凌晨2点,查询前一天统计数据,把统计之后数据添加到统计结果表中
@Scheduled(cron="0 0 2 * * ? ")
public void orderToTalAmountStatistics(){
//获取前一天的日期
String createTime = DateUtil.offsetDay(new Date(),-1).toString(new SimpleDateFormat("yyyy-MM-dd"));
//根据前一天的日期统计前一天的交易金额
OrderStatistics orderStatistics = orderInfoMapper.selectOrderStatistics(createTime);
if(orderStatistics!=null){
orderStatisticsMapper.insert(orderStatistics);
}
}
}
<select id="selectStatisticsByDate" resultType="com.xxx.order.OrderStatistics">
SELECT DATE_FORMAT(o.create_time,'%Y-%m-%d'),
SUM(o.total_amount) AS totalAmount,
COUNT(o.id) AS totalNum
FROM order_info o
WHERE DATE_FORMAT(o.create_time,'%Y-m%-d%')=#{createDate}
GROUP BY DATE_FORMAT(o.create_time,'%Y-m%-d%')
</select>
⑦、用ECharts图标展示
json数组格式——>对应java中的list集合
@RestController
@RequestMapping(value="/admin/order/orderInfo")
public class OrderInfoController{
@Autowired
private OrderInfoService orderInfoService;
@GetMapping("/getOrderStatisticsData")
public Result<OrderStatisticsVo> getOrderStatisticsData(OrderStatisticsDto orderStatisticsDto){
OrderStatisticsVo orderStatisticsVo = orderInfoService.getOrderStatisticsData(orderStatisticsDto);
return Result.build(orderStatisticsVo,ResultCodeEnum.SUCCESS);
}
}
@Service
public class OrderInfoServiceImpl implements OrderInfoService{
@Autowired
private OrderStatisticsMapper orderStatisticsMapper;
@Override
public OrderStatisticsVo getOrderStatisticsData(OrderStatisticsDto orderStatisticsDto){
//根据dto条件查询统计结果数据,返回list集合
List<OrderStatistics> orderStatisticsList = orderStatisticsMapper.selectList(orderStatisticsDto);
//遍历list集合,得到所有日期,把所有日期封装list新集合里面(X轴)
List<String> dateList = orderStatisticsList.stream()
.map(orderStatistics->DateUtil.format(orderStatistics.getOrderDate(),"yyyy-MM-dd"))
.collect(Collectors.toList());
//遍历list集合,得到所有日期对应总金额,把所有日期封装list新集合里面
List<BigDecimal> decimalList = orderStatisticsList.stream().map(OrderStatistics::getTotalAmount)
.collect(Collectors.toList());
//将两个list集合封装到OrderStatisticsVo中
OrderStatisticsVo orderStatisticsVo = new OrderStatisticsVo();
orderStatisticsVo.setDateList(dateList);
orderStatisticsVo.setAmountList(decimalList);
return orderStatisticsVo;
}
}
<select id="selectList" resultMap="orderStatisticsMap">
select <include refid="columns">
from order_statistics
<where>
<if test="createTimeBegin != null and createTimeBegin=''">
and order_date>=#{createTimeBegin}
</if>
<if test="createTimeEnd != null and createTimeEnd != ''">
and order_date <= #{createTimeEnd}
</if>
</where>
order by order_date
</select>
=====================================================================
点击每个图表可以进入代码显示
引入echarts.min.js文件
<script>
var myChart = echarts.init(document.getElementById("main"));
var option = {
//x轴是类目轴(离散数据),必须通过data设置类目数据
xAxis:{
type:'category',
data:['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
},
//y轴是数据轴(连续数据)
yAxis:{
type:'value'
},
//系列列表。每个系列通过type决定自己的图表类型
series:[{
//细娥中的数据内容数组
data:[820,932,901,934,1290,1330,1320],
//折线图
type:'line'
}]
};
myChart.setOption(option);
</script>
<script>
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>
项目中集成ECharts
一、前端:npm install --save echarts@4.1.0
二、后端获取数据接口,每天的数量
SQL
select count(*) as count,reserve_date as reserveDate
from order_info
group by reserve_Date
order by reserve_date
mapper
public interface OrderMapper extends BaseMapper<OrderInfo>{
//查询预约统计数据的方法
List<OrderCountVo> selectOrderCount(@Param("vo") OrderCountQueryVo orderCountQueryVo);
}
<mapper namespace="com.michael.yygh.order.mapper.OrderMapper">
<select id="selectOrderCount" resultType="com.michael.yygh.vo.order.OrderCountVo">
SELECT COUNT(*) AS count,reserve_date AS reserveDate FROM order_info
<where>
<if test="vo.hostname!=null and vo.hosname!=''">
and hosname like CONCAT('%',#{vo.hosname},'%')
</if>
<if test="vo.reserveDateBegin!=nul 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>
模块配置文件application.properties必须添加
mybatis-plus.mapper-locations=classpath:com/michael/yygh/order/mapper/xml/*.xml
依赖文件pom.xml中项目构建打包中必须包含xml
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
Service接口以及实现类
//预约统计
@Override
public Map<String,Object> getCountMap(OrderCountQueryVo orderCountQueryVo){
List<OrderCountVo> orderCountVoList = baseMapper.selectOrderCount(orderCountQueryVo);
//获取X轴需要的日期
List<String> dateList = orderCountVoList.stream().map(OrderCountVo::getReserveDate).collect(Collectors.toList());
//获取y轴需要的数量
List<Integer> countList = orderountVoList.stream().map(OrderCountVo::getCount).collect(Collectors.toList());
Map<String,Object> map = new HashMap<>();
map.put("dateList",dateList);
map.put("countList",countList);
return map;
}
Controller
@ApiOperation(value="获取订单统计数据")
@PostMapping("inner/getCountMap")
public Map<String,Object> getCountMap(@RequestBody OrderCountQueryVo orderCountQueryVo){
return orderService.getCountMap(orderCountQueryVo);
}
远程模块的接口
@FeignClient(value="service-order")
@Repository
public interface OrderFeignClient{
@PostMapping("inner/getCountMap")
public Map<String,Object> getCountMap(@RequestBody OrderCountQueryVo orderCountVo);
}
统计模块对远程调用模块进行调用
@RestController
@RequestMapping("/admin/statistics")
public class StatisticsController{
@Autowired
private OrderFeignClient orderFeignClient;
//获取预约统计数据
@GetMapping("getCountMap")
public Result getCountMap(OrderCountQueryVo orderCountQueryVo){
Map<String,Object> countMap = orderFeignClient.getCountMap(orderCountQueryVo);
return Result.ok(countMap);
}
}