需求:营收趋势图。需要按年,按月,按日。按年,后方选择日历 起始年-结束年。例如start2013
end 2023
按月,后方选择月份 起始月-结束月。例如start 2022-10 end 2023-07。
按日,后方选择日 起始日-结束日。例如 start 2023-06-15 end 2023-07-11。
先来用sql统计。sql统计出有的年月日。理想的是,没有的年月日补充时间,数据为0,没有的数据用java补充即可。
展示对象
查询对象
改造成动态sql。根据type。分组不一样。
<select id="chart" resultType="com.xxxx.TaxiOrderChartVO"
parameterType="com.xxxx.TaxiOrderChartQuery">
select
count(distinct user_id) as useNum,
count(id) as orderNum,
<if test="type=='YEAR'">
YEAR(create_time) as type
</if>
<if test="type=='MONTH'">
DATE_FORMAT(create_time,'%Y-%m') as type
</if>
<if test="type=='DAY'">
DATE_FORMAT(create_time,'%Y-%m-%d') as type
</if>
from cz_taxi_orders
<where>
<if test="type=='YEAR'">
<if test="start != null and start != '' && end != null and end != ''">
YEAR(create_time) BETWEEN #{start} and #{end}
</if>
</if>
<if test="type=='MONTH'">
<if test="start != null and start != '' && end != null and end != ''">
DATE_FORMAT(create_time,'%Y-%m') BETWEEN #{start} and #{end}
</if>
</if>
<if test="type=='DAY'">
<if test="start != null and start != '' && end != null and end != ''">
DATE_FORMAT(create_time,'%Y-%m-%d') BETWEEN #{start} and #{end}
</if>
</if>
</where>
group by type
</select>
Java代码
@Override
public R chart(TaxiOrderChartQuery query) throws ParseException {
List<TaxiOrderChartVO> list = taxiOrderMapper.chart(query);
//年 yyyy
List<TaxiOrderChartVO> list1 = new ArrayList<>();
//月 yyyy-MM
List<TaxiOrderChartVO> list2 = new ArrayList<>();
//日 yyyy-MM-dd
List<TaxiOrderChartVO> list3 = new ArrayList<>();
//按年统计,没有的年份补充0
if (query.getType().equals("YEAR")){
Integer end = Integer.valueOf(query.getEnd());
Integer start = Integer.valueOf(query.getStart());
for (int i = start; i <= end; i++) {
TaxiOrderChartVO vo = new TaxiOrderChartVO();
boolean flag = false;
for (TaxiOrderChartVO chartVO : list) {
if (chartVO.getType().equals(String.valueOf(i))){
flag = true;
vo.setOrderNum(chartVO.getOrderNum());
vo.setUseNum(chartVO.getUseNum());
vo.setType(chartVO.getType());
}
}
if (!flag){
vo.setUseNum(0);
vo.setType(String.valueOf(i));
vo.setOrderNum(0);
}
list1.add(vo);
}
return R.ok(list1);
}
//按月统计,2023-01至2023-12,没有的部分补充0
if (query.getType().equals("MONTH")){
List<String> monthBetweenDate = DateUtils.getMonthBetweenDate(query.getStart(), query.getEnd());
for (String month : monthBetweenDate) {
TaxiOrderChartVO vo = new TaxiOrderChartVO();
boolean flag = false;
for (TaxiOrderChartVO chartVO : list) {
if (chartVO.getType().equals(month)){
flag = true;
vo.setOrderNum(chartVO.getOrderNum());
vo.setUseNum(chartVO.getUseNum());
vo.setType(chartVO.getType());
}
}
if (!flag){
vo.setUseNum(0);
vo.setType(month);
vo.setOrderNum(0);
}
list2.add(vo);
}
return R.ok(list2);
}
//按日统计,2023-01-12至2023-02-10,没有的部分补充0
if (query.getType().equals("DAY")){
List<String> dayBetweenDate = DateUtils.getDayBetweenDate(query.getStart(), query.getEnd());
for (String day : dayBetweenDate) {
TaxiOrderChartVO vo = new TaxiOrderChartVO();
boolean flag = false;
for (TaxiOrderChartVO chartVO : list) {
if (chartVO.getType().equals(day)){
flag = true;
vo.setOrderNum(chartVO.getOrderNum());
vo.setUseNum(chartVO.getUseNum());
vo.setType(chartVO.getType());
}
}
if (!flag){
vo.setUseNum(0);
vo.setType(day);
vo.setOrderNum(0);
}
list3.add(vo);
}
return R.ok(list3);
}
return R.ok(list);
}
月,日工具类
package com.zyx.common.utils;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author zyx
* @date 2023/4/13 15:20
*/
public class DateUtils {
/**
* 获取两个日期之间的所有月份 (年月)
* @param startTime
* @param endTime
* @return:list
*/
public static List<String> getMonthBetweenDate(String startTime, String endTime) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
// 声明保存日期集合
List<String> list = new ArrayList<>();
try {
// 转化成日期类型
Date startDate = sdf.parse(startTime);
Date endDate = sdf.parse(endTime);
//用Calendar 进行日期比较判断
Calendar calendar = Calendar.getInstance();
while (startDate.getTime() <= endDate.getTime()) {
// 把日期添加到集合
list.add(sdf.format(startDate));
// 设置日期
calendar.setTime(startDate);
//把月数增加 1
calendar.add(Calendar.MONTH, 1);
// 获取增加后的日期
startDate = calendar.getTime();
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 获取两个日期之间的所有天数 (年月日)
* @param startTime
* @param endTime
* @return:list
*/
public static List<String> getDayBetweenDate(String startTime, String endTime) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 声明保存日期集合
List<String> list = new ArrayList<>();
try {
// 转化成日期类型
Date startDate = sdf.parse(startTime);
Date endDate = sdf.parse(endTime);
//用Calendar 进行日期比较判断
Calendar calendar = Calendar.getInstance();
while (startDate.getTime() <= endDate.getTime()) {
// 把日期添加到集合
list.add(sdf.format(startDate));
// 设置日期
calendar.setTime(startDate);
//把天数增加 1
calendar.add(Calendar.DATE, 1);
// 获取增加后的日期
startDate = calendar.getTime();
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
访问接口文档。测试效果。可以实现,接下来就是和前端沟通按年传YEAR,按月传MONTH,按日传DAY即可。