最近做到后台统计功能,有一个需求:需要把数据库的统计信息每天凌晨1点将数据库的一些统计信息写入到另一个表statistics中,因此使用到了定时任务。在管理端需要图表展示,使用到了echarts,记录一下。
StatisticsController
@RestController
@RequestMapping("/mallservice/statistics")
@CrossOrigin
public class StatisticsController {
@Autowired
private StatisticsService statisticsService;
//查询某日的注册人数、订单数、商品数存到daily表中
@PostMapping(value = "/createRegistCount/{day}")
public R createStatisticsCountByDay(@PathVariable("day") String day) {
this.statisticsService.createStatisticsCountByDay(day);
return R.ok();
}
//获取echart数据
@GetMapping("getEchartsDatas/{type}/{begin}/{end}")
public R getEchartsDatas(@PathVariable String type,
@PathVariable String begin,
@PathVariable String end) {
Map<String, Object> map = this.statisticsService.getEchatsDatas(type, begin, end);
return R.ok().data("map", map);
}
}
StatisticsServiceImpl
@Service
public class StatisticsServiceImpl extends ServiceImpl<StatisticsMapper, Statistics> implements StatisticsService {
@Autowired
private UserMapper userMapper;
@Autowired
private ProductMapper productMapper;
@Autowired
private OrderMapper orderMapper;
@Override
public void createRegistCountByDay(String day) {
//先删除同一天的
QueryWrapper<Statistics> wrapper = new QueryWrapper<>();
wrapper.eq("date_calculated", day);
this.baseMapper.delete(wrapper);
//先查询出有多少注册数
Integer registCount = userMapper.queryRegistCountByDay(day);
Integer orderCount = orderMapper.queryOrderCountByDay(day);
Integer productCount = productMapper.queryProductCountByDay(day);
Statistics daily = new Statistics();
daily.setDateCalculated(day);
daily.setRegisterNum(registCount);
daily.setOrderNum(orderCount);
daily.setProductNum(productCount);
//再写入到数据库中
this.baseMapper.insert(daily);
}
/*生成echarts需要的数据*/
@Override
public Map<String, Object> getEchatsDatas(String type, String begin, String end) {
QueryWrapper<Statistics> wrapper = new QueryWrapper<>();
wrapper.between("date_calculated", begin, end);
wrapper.select("date_calculated", type);
wrapper.orderByAsc("date_calculated");
List<Statistics> dailyList = this.baseMapper.selectList(wrapper);
ArrayList<String> dateDatas = new ArrayList<>();//日期
ArrayList<Integer> countDatas = new ArrayList<>();
for (int i = 0; i < dailyList.size(); i++) {
Statistics daily = dailyList.get(i);
dateDatas.add(daily.getDateCalculated());
if ("register_num".equals(type)) {
countDatas.add(daily.getRegisterNum());
} else if ("order_num".equals(type)) {
countDatas.add(daily.getOrderNum());
} else if ("product_num".equals(type)) {
countDatas.add(daily.getProductNum());
}
}
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("dateList", dateDatas);
hashMap.put("countList", countDatas);
return hashMap;
}
}
定时任务StaScheduled :
@Component
public class StaScheduled {
@Autowired
private StatisticsService statisticsService;
//每天的凌晨1点将前一天的数据加到statistic表中
@Scheduled(cron = "0 0 1 * * ?")
public void taskStaMethod() {
Date date = DateUtil.addDays(new Date(), -1);
String formatDate = DateUtil.formatDate(date);
statisticsService.createRegistCountByDay(formatDate);
}
}
前端页面展示:
完整前端代码:
<template>
<div class="app-container">
<el-form :inline="true" class="demo-form-inline">
<el-form-item >
<el-select v-model="searchObj.type" clearable="" placeholder="请选择">
<el-option label="订单数量" value="order_num"></el-option>
<el-option label="商品数量" value="product_num"></el-option>
<el-option label="用户注册数量" value="register_num"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="searchObj.begin"
type="date"
placeholder="选择起始日期"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="searchObj.end"
type="date"
placeholder="选择截止日期"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
<div id="chart" style="width: 900px;height:400px;"></div>
</div>
</template>
<script>
import statistic from '@/api/statistic/statistic'
import echarts from 'echarts'
export default {
data() {
return{
searchObj: {
type: '',
begin: "",
end: ''
},
dateList: [],
countList: []
}
},
methods: {
onSubmit(){
statistic.getEchartsDatas(this.searchObj.type,this.searchObj.begin,this.searchObj.end).then(res =>{
this.dateList = res.data.map.dateList;
this.countList = res.data.map.countList;
this.setChart();
})
},
//ECharts图表展示部分
setChart(){
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('chart'));
// 指定图表的配置项和数据
var option = {
xAxis: {
type: 'category',
data: this.dateList
},
yAxis: {
type: 'value'
},
series: [{
data: this.countList,
type: 'line'
}],
title: {
text: this.getTitle,
left: 'center'
},
tooltip: {
trigger: 'axis'
},
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
},
computed: {
getTitle(){
if(this.searchObj.type === "order_num"){
this.title = this.searchObj.begin + '~'+ this.searchObj.end + "订单数量情况"
return this.title;
}else if(this.searchObj.type === "register_num"){
this.title = this.searchObj.begin + '~'+ this.searchObj.end + "用户注册数量情况"
return this.title;
}else if(this.searchObj.type === "product_num"){
this.title = this.searchObj.begin + '~'+ this.searchObj.end + "上架商品数量情况"
return this.title;
}
}
}
}
</script>
<style scoped>
</style>
最后附上DateUtils工具类:
public class DateUtil {
private static final String dateFormat = "yyyy-MM-dd";
/**
* 格式化日期
*
* @param date
* @return
*/
public static String formatDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
return sdf.format(date);
}
/**
* 在日期date上增加amount天 。
*
* @param date 处理的日期,非null
* @param amount 要加的天数,可能为负数
*/
public static Date addDays(Date date, int amount) {
Calendar now =Calendar.getInstance();
now.setTime(date);
now.set(Calendar.DATE,now.get(Calendar.DATE)+amount);
return now.getTime();
}
public static void main(String[] args) {
System.out.println(DateUtil.formatDate(new Date()));
System.out.println(DateUtil.formatDate(DateUtil.addDays(new Date(), -1)));
}
}
欢迎关注公众号Java技术大本营,会不定期分享BAT面试资料等福利。