苍穹外卖day11

发布时间:2026/5/17 1:52:22

苍穹外卖day11 概述项目步入尾声进行商家数据统计开发分为营业额统计用户统计订单统计销量排名导航栏的内容为查询选定时间内的的数据统计右上角的数据导出为下一天的内容数据导出后形成的图表由Apache的Echarts生成是开发中常用的数据统计图表工具营业额统计方法接口文档与需求分析前端传入起始时间与终止时间统计这个期间内已完成的订单金额总和Controller接收前端传入的日期用DateTimeFormat定义日期的格式/** * 营业额统计 * param begin * param end * return */GetMapping(/turnoverStatistics)ApiOperation(营业额统计)publicResultTurnoverReportVOturnoverStatistics(DateTimeFormat(patternyyyy-MM-dd)LocalDatebegin,DateTimeFormat(patternyyyy-MM-dd)LocalDateend){returnResult.success(reportService.getTurnoverStatistics(begin,end));}Service实现类/** * 营业额统计 * param begin * param end * return */publicTurnoverReportVOgetTurnoverStatistics(LocalDatebegin,LocalDateend){//当前集合用于存放从begin到end每天的日期ListLocalDatedateListnewArrayList();dateList.add(begin);while(!begin.equals(end)){beginbegin.plusDays(1);dateList.add(begin);}ListDoubleturnoverListnewArrayList();for(LocalDatedate:dateList){LocalDateTimebeginTimeLocalDateTime.of(date,LocalTime.MIN);LocalDateTimeendTimeLocalDateTime.of(date,LocalTime.MAX);MapmapnewHashMap();map.put(begin,beginTime);map.put(end,endTime);map.put(status,Orders.COMPLETED);DoubleturnoverorderMapper.sumByMap(map);turnoverturnovernull?0.0:turnover;turnoverList.add(turnover);}returnTurnoverReportVO.builder().dateList(StringUtils.join(dateList,,)).turnoverList(StringUtils.join(turnoverList,,)).build();}观察表中的数据x轴为日期y轴为营业额每天的日期与营业额都需要进行统计故需要先获取begin到end的每一天使用LocalDate的plusDays增加天数遍历每一天并将时间对象存入日期集合准备查表统计数据观察order表可得知其中存的日期都是LocalDateTime类型包含每一天的时分秒所以需要统计每一天营业额之前先要进行转型使用LocalDateTime.of(LocalDateTime.of(date, LocalTime.MAX/MIN);)分别设置每一天的开始和结束时间查表后返回double类型营业额进行非空判断后存入集合与日期集合一一对应按照String类型返回给前端使用StringUtils提供的join方法将集合转为字符串用“”连接MapperselectidsumByMapparameterTypemapresultTypejava.lang.Doubleselect sum(amount) from orderswhereiftestbegin ! nulland order_timegt;#{begin}/ififtestend !nulland order_timelt;#{end}/ififteststatus !nulland status#{status}/if/where/select用户统计接口文档与需求分析根据产品原型我们需要统计出用户选定时间范围内新增用户数量以及用户总数量Controller/** * 用户量统计 * param begin * param end * return */GetMapping(/userStatistics)publicResultUserReportVOuserStatistics(DateTimeFormat(patternyyyy-MM-dd)LocalDatebegin,DateTimeFormat(patternyyyy-MM-dd)LocalDateend){log.info(用户数据统计:{} {},begin,end);returnResult.success(reportService.getUserStatistics(begin,end));}Service实现类/** * 用户量统计 * param begin * param end * return */publicUserReportVOgetUserStatistics(LocalDatebegin,LocalDateend){//当前集合用于存放从begin到end每天的日期ListLocalDatedateListnewArrayList();dateList.add(begin);while(!begin.equals(end)){beginbegin.plusDays(1);dateList.add(begin);}ListIntegernewUserListnewArrayList();ListIntegertotalUserListnewArrayList();for(LocalDatedate:dateList){LocalDateTimebeginTimeLocalDateTime.of(date,LocalTime.MIN);LocalDateTimeendTimeLocalDateTime.of(date,LocalTime.MAX);MapmapnewHashMap();map.put(end,endTime);IntegertotalUserNumberuserMapper.countByMap(map);map.put(begin,beginTime);IntegernewUserNumberuserMapper.countByMap(map);totalUserList.add(totalUserNumber);newUserList.add(newUserNumber);}returnUserReportVO.builder().dateList(StringUtils.join(dateList,,)).totalUserList(StringUtils.join(totalUserList,,)).newUserList(StringUtils.join(newUserList,,)).build();}第一步四个统计功能都一样将日期放入集合进行总人数和新增人数的统计创建两个集合分别记录与日期对应的总人数和新增人数转型日期为日期时间类型以便通过比较查表将end放入map后直接统计便可得出到end为止的总用户再添加begin可得出选定时间内新增用户这样实现了代码复用解耦一举两得封装为VO对象返回给前端MapperselectidcountByMapparameterTypemapresultTypejava.lang.Integerselect count(id) from userwhereiftestbegin!nulland create_timegt;#{begin}/ififtestend!nulland create_timelt;#{end}/if/where/select此处需要注意的就是大于小于序号的使用订单数据统计接口文档与需求分析通过产品原型可以看出此时不仅需要订单数量和日期还需要已完成的订单与总订单数量进行除法统计出订单完成率Controller/** * 订单数据统计 * param begin * param end * return */GetMapping(/ordersStatistics)ApiOperation(订单统计)publicResultOrderReportVOorderStatistics(DateTimeFormat(patternyyyy-MM-dd)LocalDatebegin,DateTimeFormat(patternyyyy-MM-dd)LocalDateend){log.info(订单数据统计:{} {},begin,end);returnResult.success(reportService.getOrderStatistics(begin,end));}Service实现类/** * 订单数据统计 * * param begin * param end * return */publicOrderReportVOgetOrderStatistics(LocalDatebegin,LocalDateend){ListLocalDatedateListnewArrayList();dateList.add(begin);while(!begin.equals(end)){beginbegin.plusDays(1);dateList.add(begin);}ListIntegerorderCountListnewArrayList();ListIntegervalidCountListnewArrayList();for(LocalDatedate:dateList){//查询每天的订单数量LocalDateTimebeginTimeLocalDateTime.of(begin,LocalTime.MIN);LocalDateTimeendTimeLocalDateTime.of(end,LocalTime.MAX);orderCountList.add(getOrderCount(beginTime,endTime,null));//查询每天有效订单validCountList.add(getOrderCount(beginTime,endTime,Orders.COMPLETED));}//计算当前日期内的订单数量IntegertotalOrderCountorderCountList.stream().reduce(Integer::sum).get();//计算当前日期内已完成的订单数量IntegervalidOrderCountvalidCountList.stream().reduce(Integer::sum).get();DoublecompleteRate0.0;if(totalOrderCount!0){completeRatevalidOrderCount.doubleValue()/totalOrderCount;}returnOrderReportVO.builder().dateList(StringUtils.join(dateList,,)).orderCountList(StringUtils.join(orderCountList,,)).validOrderCountList(StringUtils.join(validCountList,,)).totalOrderCount(totalOrderCount).validOrderCount(validOrderCount).orderCompletionRate(completeRate).build();}//获取每天订单数量privateIntegergetOrderCount(LocalDateTimebegin,LocalDateTimeend,Integerstatus){MapmapnewHashMap();map.put(begin,begin);map.put(end,end);map.put(status,status);returnorderMapper.countByMap(map);}获取日期集合通过调用getOrderCount获取每天的订单数量以及完成的订单数量并装入集合中使用stream流的reduce方法对流中的集合的元素进行归约相除获得订单完成率封装返回前端MapperselectidcountByMapresultTypejava.lang.Integerselect count(id) from orderswhereiftestbegin ! nulland order_timegt;#{begin}/ififtestend !nulland order_timelt;#{end}/ififteststatus !nulland status#{status}/if/where/select销量top10统计接口文档与需求分析观察产品原型图表是罗列了各个菜品以及其销量因此需要菜品姓名集合以及其对应数量的集合ControllerGetMapping(/top10)ApiOperation(销量统计)publicResultSalesTop10ReportVOsalesTop10Statistics(DateTimeFormat(patternyyyy-MM-dd)LocalDatebegin,DateTimeFormat(patternyyyy-MM-dd)LocalDateend){log.info(销量top10统计:{} {},begin,end);returnResult.success(reportService.getSalesTop10Statistics(begin,end));}Service实现类/** * 统计销量top10 * param begin * param end * return */publicSalesTop10ReportVOgetSalesTop10Statistics(LocalDatebegin,LocalDateend){LocalDateTimebeginTimeLocalDateTime.of(begin,LocalTime.MIN);LocalDateTimeendTimeLocalDateTime.of(end,LocalTime.MAX);//获取销量tops名称数量列表ListGoodsSalesDTOsalesToporderMapper.getSalesTop(beginTime,endTime);ListStringnamessalesTop.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());StringnameListStringUtils.join(names,,);ListIntegernumberssalesTop.stream().map(GoodsSalesDTO::getNumber).toList();StringnumberListStringUtils.join(numbers,,);//封装到VO中returnSalesTop10ReportVO.builder().nameList(nameList).numberList(numberList).build();}将时间转型并查表获取销量top10的菜品集合使用stream流的map方法将集合中的元素映射为GoodsSalesDTO使用静态方法获取名字随后collect封装为集合把集合转为符合前端要求的字符串获取订单销量操作如上MapperselectidgetSalesTopresultTypecom.sky.dto.GoodsSalesDTOselect od.name,sum(od.number) number from order_detail od,orders o where od.order_ido.id and status5iftestbegin!nulland o.order_timegt;#{begin}/ififtestend!nulland o.order_timelt;#{end}/ifgroup by od.name order by number desc limit 0,10/select倒叙查询在时间范围内数量最多的前十个菜品总结进行了数据的统计进一步完善了项目熟悉了数据统计的流程

相关新闻