苍穹外卖(数据统计-图形报表)
数据统计(图形报表)
营业额统计
接口设计
代码开发
设计对应的VO
创建ReportController
创建ReportService接口,声明getTurnover方法
创建ReportServiceImpl实现类,实现getTurnover方法
在OrderMapper接口声明sumByMap方法
在OrderMapper.xml文件中编写动态SQL
功能测试
用户统计
接口设计
代码开发
设计VO
在ReportController中创建userStatistics方法
在ReportService接口中声明getUserStatistics方法
在ReportServiceImpl实现类中实现getUserStatistics方法
在UserMapper接口中声明countByMap方法
在UserMapper.xml文件中编写动态SQL
功能测试
订单统计
接口设计
代码开发
设计VO
在ReportController中根据订单统计接口创建orderStatistics方法
在ReportService接口中声明getOrderStatistics方法
在ReportServiceImpl实现类中实现getOrderStatistics方法
在OrderMapper接口中声明countByMap方法
在OrderMapper.xml文件中编写动态SQL
功能测试
销量排名Top10
接口设计
代码开发
设计VO
在ReportController中根据销量排名接口创建top10方法
在ReportService接口中声明getSalesTop10方法
在ReportServiceImpl实现类中实现getSalesTop10方法
在OrderMapper接口中声明getSalesTop10方法
在OrderMapper.xml文件中编写动态SQL
功能测试
营业额统计
接口设计
代码开发
设计对应的VO
初始代码已提供
创建ReportController
创建ReportService接口,声明getTurnover方法
创建ReportServiceImpl实现类,实现getTurnover方法
在OrderMapper接口声明sumByMap方法
/*** 根据动态条件统计营业额数据* @param map* @return*/Double sumByMap(Map map);
在OrderMapper.xml文件中编写动态SQL
功能测试
用户统计
接口设计
代码开发
设计VO
初始代码已提供
在ReportController中创建userStatistics方法
/*** 用户统计* @param begin* @param end* @return*/@GetMapping("/userStatistics")@ApiOperation("用户统计")public Result<UserReportVO> userStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {log.info("用户数据统计, begin:{}, end:{}", begin, end);return Result.success(reportService.getUserStatistics(begin, end));}
在ReportService接口中声明getUserStatistics方法
/*** 统计指定时间区间内的用户数据* @param begin* @param end* @return*/UserReportVO getUserStatistics(LocalDate begin, LocalDate end);
在ReportServiceImpl实现类中实现getUserStatistics方法
需要注入userMapper对象
/*** 统计指定时间区间内的用户数据* @param begin* @param end* @return*/@Overridepublic UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {//当前集合用于存放从begin到end的每一天的日期List<LocalDate> dateList=new ArrayList<>();dateList.add(begin);while (!begin.equals(end)){begin=begin.plusDays(1);dateList.add(begin);}//当前集合用于存放从begin到end的每一天的新增用户数 select count(id) from user where create_time<? and create_time>?List<Integer> newUserList=new ArrayList<>();//当前集合用于存放从begin到end的每一天的总用户数 select count(id) from user where create_time<=?List<Integer> totalUserList=new ArrayList<>();for (LocalDate date : dateList) {LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);Map map = new HashMap();map.put("end", endTime);//总用户数量Integer totalUser = userMapper.countByMap(map);//新增用户数量map.put("begin", beginTime);Integer newUser = userMapper.countByMap(map);totalUserList.add(totalUser);newUserList.add(newUser);}return UserReportVO.builder().dateList(StringUtils.join(dateList, ",")).totalUserList(StringUtils.join(totalUserList, ",")).newUserList(StringUtils.join(newUserList, ",")).build();}
在UserMapper接口中声明countByMap方法
/*** 根据动态条件统计用户数量* @param map* @return*/Integer countByMap(Map map);
在UserMapper.xml文件中编写动态SQL
<select id="countByMap" resultType="java.lang.Integer">select count(id) from sky_take_out.user<where><if test="begin != null">and create_time >= #{begin}</if><if test="end != null">and create_time <= #{end}</if></where></select>
功能测试
订单统计
接口设计
代码开发
设计VO
初始代码以提供
package com.sky.vo;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderReportVO implements Serializable {//日期,以逗号分隔,例如:2022-10-01,2022-10-02,2022-10-03private String dateList;//每日订单数,以逗号分隔,例如:260,210,215private String orderCountList;//每日有效订单数,以逗号分隔,例如:20,21,10private String validOrderCountList;//订单总数private Integer totalOrderCount;//有效订单数private Integer validOrderCount;//订单完成率private Double orderCompletionRate;}
在ReportController中根据订单统计接口创建orderStatistics方法
ctrl+n可以直接搜索类
/*** 订单统计** @param begin* @param end* @return*/@GetMapping("/ordersStatistics")@ApiOperation("订单统计")public Result<OrderReportVO> orderStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {log.info("订单数据统计, begin:{}, end:{}", begin, end);return Result.success(reportService.getOrderStatistics(begin, end));}
在ReportService接口中声明getOrderStatistics方法
/*** 统计指定时间区间内的订单数据* @param begin* @param end* @return*/OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end);
在ReportServiceImpl实现类中实现getOrderStatistics方法
这里将查询每一天的订单总数和有效数量的代码单独提取到了getOrderCount方法中
/*** 统计指定时间区间内的订单数据** @param begin* @param end* @return*/@Overridepublic OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) {//当前集合用于存放从begin到end的每一天的日期List<LocalDate> dateList = new ArrayList<>();dateList.add(begin);while (!begin.equals(end)) {begin = begin.plusDays(1);dateList.add(begin);}//当前集合用于存放从begin到end的每一天的订单总数List<Integer> orderCountList = new ArrayList<>();//当前集合用于存放从begin到end的每一天的有效订单数List<Integer> validOrderCountList = new ArrayList<>();//遍历dateList,获取每一天的有效订单数、订单总数for (LocalDate date : dateList) {//查询每天的订单总数select count(id) from orders where order_time>? and order_time<?LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);Integer orderCount = getOrderCount(beginTime, endTime, null);//查询每天的有效订单数select count(id) from orders where order_time>? and order_time<? and status=5Integer validOrderCount = getOrderCount(beginTime, endTime, Orders.COMPLETED);orderCountList.add(orderCount);validOrderCountList.add(validOrderCount);}//计算时间区间内的订单总数Integer totalOrderCount = orderCountList.stream().reduce(Integer::sum).get();//计算时间区间内的有效订单数Integer validOrderCount = validOrderCountList.stream().reduce(Integer::sum).get();//计算有效订单率Double orderCompletionRate = 0.0;if (totalOrderCount != 0) {orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount * 100;}return OrderReportVO.builder().dateList(StringUtils.join(dateList, ",")).orderCountList(StringUtils.join(orderCountList, ",")).validOrderCountList(StringUtils.join(validOrderCountList, ",")).totalOrderCount(totalOrderCount).validOrderCount(validOrderCount).orderCompletionRate(orderCompletionRate).build();}/*** 根据条件统计订单数量** @param begin* @param end* @param status* @return*/private Integer getOrderCount(LocalDateTime begin, LocalDateTime end, Integer status) {Map map = new HashMap();map.put("begin", begin);map.put("end", end);map.put("status", status);return orderMapper.countByMap(map);}
在OrderMapper接口中声明countByMap方法
/*** 根据动态条件统计订单数量* @param map* @return*/Integer countByMap(Map map);
在OrderMapper.xml文件中编写动态SQL
<select id="countByMap" resultType="java.lang.Integer">select count(id) from sky_take_out.orders<where><if test="begin != null">and order_time > #{begin}</if><if test="end != null">and order_time < #{end}</if><if test="status != null">and status = #{status}</if></where></select>
功能测试
销量排名Top10
接口设计
代码开发
设计VO
初始代码已提供
package com.sky.vo;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SalesTop10ReportVO implements Serializable {//商品名称列表,以逗号分隔,例如:鱼香肉丝,宫保鸡丁,水煮鱼private String nameList;//销量列表,以逗号分隔,例如:260,215,200private String numberList;}
在ReportController中根据销量排名接口创建top10方法
/*** 销售Top10* @param begin* @param end* @return*/@GetMapping("/top10")@ApiOperation("销售Top10")public Result<SalesTop10ReportVO> top10(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {log.info("销售Top10数据统计, begin:{}, end:{}", begin, end);return Result.success(reportService.getSalesTop10(begin, end));}
在ReportService接口中声明getSalesTop10方法
/*** 统计指定时间区间内的销售排行榜top10* @param begin* @param end* @return*/SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end);
在ReportServiceImpl实现类中实现getSalesTop10方法
/*** 统计指定时间区间内的销售排行榜top10* @param begin* @param end* @return*/@Overridepublic SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end) {LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);List<GoodsSalesDTO> salesTop10 = orderMapper.getSaleTop10(beginTime, endTime);List<String> names = salesTop10.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());String nameList = StringUtils.join(names, ",");List<Integer> numbers = salesTop10.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());String numberList = StringUtils.join(numbers, ",");//封装返回结果数据return SalesTop10ReportVO.builder().nameList(nameList).numberList(numberList).build();}
在OrderMapper接口中声明getSalesTop10方法
/*** 统计指定时间区间内的销量排名前10* @param begin* @param end* @return*/List<GoodsSalesDTO> getSaleTop10(LocalDateTime begin,LocalDateTime end);
在OrderMapper.xml文件中编写动态SQL
<select id="getSaleTop10" resultType="com.sky.dto.GoodsSalesDTO">select od.name,sum(od.number) numberfrom sky_take_out.order_detail od,sky_take_out.orders owhere od.order_id = o.id and o.status=5<if test="begin != null">and o.order_time > #{begin}</if><if test="end != null">and o.order_time < #{end}</if>group by od.nameorder by number desclimit 10</select>