《苍穹外卖-day11》
0. 今日总结
- 完成了营业额统计功能开发
- 完成了用户统计功能开发
- 完成了订单统计功能开发
- 完成了销量排名top统计功能开发
1. 营业额统计
1.1 需求分析和设计
业务规则
营业额指订单状态为已完成的订单金额合计
基于可视化报表的折线图展示营业额数据,x轴为日期,轴为营业额
根据时间选择区间,展示每天的营业额数据
接口设计
1.2 代码开发
VO设计
controller
- 用TurnoverReportVO接收数据
- 用LocalDate接收前端传来的begin和end,表示统计的开始日期和结束日期,并用DateTimeFormat注解将日期转换为固定的格式
- 调用service层接口,将begin和end传入,并进行查询
service
- 创建List集合,泛型为LocalDate,用于存放日期数据
- 通过循环以及plusDays方法对begin递增1天,并将每天的数据add到dateList集合中
- 创建List集合,泛型为Double,用于存放营业额
- 遍历date,逐天统计
- 调用LocalDateTime.of方法,获取对应date的开始时间和结束时间
- 创建Map集合,用于一次性将begin,end,status传给Mapper
- 调用mapper层接口,查询begin-end内每一天的营业额之和
- 判断,若营业为空,则置为0,否则为查询的值
- 将营业额add到turnoverList中
- 返回一个新的TurnoverReportVO对象,设置dateList和turnoverList值,按前端的要求,用","分隔并将值用apache的StringUtils工具类的join转化为字符串
mapper
根据开始时间和结束时间以及状态值查询营业额
1.3 功能测试
2. 用户统计
2.1 需求分析
2.2 代码开发
VO设计
思路和营业额统计完全相同,不赘述代码
2.3 功能测试
3. 订单统计
3.1 需求分析
业务规则
- 有效订单指状态为“已完成”的订单
- 基于可视化报表的折线图展示订单数据,x轴为日期,Y轴为订单数量
- 根据时间选择区间,展示每天的订单总数和有效订单数
- 展示所选时间区间内的有效订单数、总订单数、订单完成率,订单完成率=有效订单数/总订单数*100%
接口设计
3.2 代码开发
VO接口设计
controller
- 接收日期数据
- 将日期传给service层,并返回orderReportVO对象
service
publicOrderReportVOorderReport(LocalDatebegin,LocalDateend){//封装日期集合List<LocalDate>dateTimeList=newArrayList<>();dateTimeList.add(begin);while(!begin.equals(end)){begin=begin.plusDays(1);dateTimeList.add(begin);}//查询每天订单数据doubleorderCompletionRate;//有效订单率List<Double>totalOrdersList=newArrayList<>();//订单数列表List<Double>totalCompletionOrdersList=newArrayList<>();//有效订单数列表doubletotalOrders=0;//订单总数doubletotalCompletionOrders=0;//有效订单总数for(LocalDatedate:dateTimeList){doubletotalOrder;//订单总数doubletotalCompletionOrder;//有效订单总数LocalDateTimebeginTime=LocalDateTime.of(date,LocalTime.MIN);LocalDateTimeendTime=LocalDateTime.of(date,LocalTime.MAX);Mapmap=newHashMap();map.put("begin",beginTime);map.put("end",endTime);map.put("status",null);totalOrder=orderMapper.getByBeginAndEnd(map);//查询订单总数map.put("status",Orders.COMPLETED);totalCompletionOrder=orderMapper.getByBeginAndEnd(map);//查询有效订单数totalOrdersList.add(totalOrder);totalCompletionOrdersList.add(totalCompletionOrder);totalOrders+=totalOrder;totalCompletionOrders+=totalCompletionOrder;}orderCompletionRate=totalCompletionOrders/totalOrders;returnOrderReportVO.builder().dateList(StringUtils.join(dateTimeList,",")).totalOrderCount((int)totalOrders).validOrderCount((int)totalCompletionOrders).orderCountList(StringUtils.join(totalOrdersList,",")).validOrderCountList(StringUtils.join(totalCompletionOrdersList,",")).orderCompletionRate(orderCompletionRate).build();}- 封装日期集合
- 查询每天订单数据
- 查询status = null的数据,表示订单总数,并添加到list集合
- 查询status = 5的数据,表示有效订单总数,并添加到list集合
- 累加到时间段内订单总数和时间段内有效订单总数
- 计算有效订单率
mapper
统计时间段内对应status的数据
3.3 功能测试
4. 销量排名Top10
4.1 需求分析
业务规则
- 根据时间选择区间,展示销量前10的商品(包括菜品和套餐)
- 基于可视化报表的柱状图降序展示商品销量
- 此处的销量为商品销售的份数
接口设计
4.2 代码开发
VO接口设计
controller
- 接收日期数据
- 将日期传给service层,并返回SalesTop10ReportVO对象
service
多表查询,获取订单数和订单名称
利用Stream流和StringUtils将数据转换为String类型的数据
StringnameList=StringUtils.join(goodsSalesDTOList.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList()),",");- goodsSalesDTOList.stream()获取Stream流
- .map(GoodsSalesDTO::getName),转换流中的数据类型,转换为getName的返回值类型
- 通过collect收集流,转化为list类型
mapper
多表查询,根据名字和总数分组并排序