外卖项目day14(day11)---数据统计


Apache ECharts

大家可以看我这篇文章:
Apache ECharts-CSDN博客
营业额统计

产品原型

接口设计


新建admin/ReportController
/*** 数据统计相关接口*/
@RestController
@RequestMapping("/admin/report")
@Api(tags = "数据统计相关接口")
@Slf4j
public class ReportController {@Autowiredprivate ReportService reportService;/*** 营业额统计* @param begin* @param end* @return*/@GetMapping("/turnoverStatistics")@ApiOperation("营业额统计")public Result<TurnoverReportVO> turnoverStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("营业额数据统计:{},{}",begin,end);return Result.success(reportService.getTurnoverStatistics(begin,end));}}
新建ReportService
public interface ReportService {/*** 统计指定时间区间内的营业额数据* @param begin* @param end* @return*/TurnoverReportVO getTurnoverStatistics(LocalDate begin,LocalDate end);
}
ReportServiceImpl
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {@Autowiredprivate OrderMapper orderMapper;/*** 统计指定时间区间内的营业额数据* @param begin* @param end* @return*/public TurnoverReportVO getTurnoverStatistics(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);}//存放每天的营业额List<Double> turnoverList = new ArrayList<>();for (LocalDate date : dateList) {//查询date日期对应的营业额数据,营业额是指,状态为"已完成"的订单金额合计LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);//select sum(amount) from orders where order_time > beginTime and order_time < endTime and status = 5Map map = new HashMap();map.put("begin",beginTime);map.put("end",endTime);map.put("status", Orders.COMPLETED);Double turnover = orderMapper.sumByMap(map);turnover = turnover == null ? 0.0 : turnover;turnoverList.add(turnover);}//封装返回结果return TurnoverReportVO.builder().dateList(StringUtils.join(dateList,",")).turnoverList(StringUtils.join(turnoverList,",")).build();}
}
OrderMapper
/*** 根据动态条件统计营业额数据* @param map* @return*/Double sumByMap(Map map);
OrderMapper.xml
<select id="sumByMap" resultType="java.lang.Double">select sum(amount) from 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>
功能测试:


用户统计

产品原型
接口设计

ReportController
/*** 用户统计* @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);return Result.success(reportService.getUserStatistics(begin,end));}
ReportService
/*** 统计指定时间区间内的用户数据* @param begin* @param end* @return*/UserReportVO getUserStatistics(LocalDate begin, LocalDate end);
ReportServiceImpl
/*** 统计指定时间区间内的用户数据* @param begin* @param end* @return*/public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {//存放从being 到 end之间的每天对应的日期List<LocalDate> dateList = new ArrayList<>();dateList.add(begin);while (!begin.equals(end)) {begin = begin.plusDays(1);dateList.add(begin);}//存放每天的新增用户数量 select count(id) from user where create_time < ? and create_time > ?List<Integer> newUserList = new ArrayList<>();//存放每天的总用户数量 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
/*** 根据动态条件统计营业额数据* @param map* @return*/Double sumByMap(Map map);
UserMapper.xml
<select id="countByMap" resultType="java.lang.Integer">select count(id) from user<where><if test="begin != null">and create_time > #{begin}</if><if test="end != null">and create_time < #{end}</if></where></select>
功能测试:

订单统计

产品原型

接口设计



ReportController
/*** 订单统计* @param begin* @param end* @return*/@GetMapping("/ordersStatistics")@ApiOperation("订单统计")public Result<OrderReportVO> ordersStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("用户数据统计:{},{}",begin,end);return Result.success(reportService.getOrderStatistics(begin,end));}
ReportService
/*** 统计指定时间区间内的订单数据* @param begin* @param end* @return*/OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end);
ReportServiceImpl
/*** 统计指定时间区间内的订单数据* @param begin* @param end* @return*/public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) {//存放从being 到 end之间的每天对应的日期List<LocalDate> dateList = new ArrayList<>();dateList.add(begin);while (!begin.equals(end)) {begin = begin.plusDays(1);dateList.add(begin);}//存放每天的订单总数List<Integer> orderCountList = new ArrayList<>();//存放每天的有效订单数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;}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
/*** 根据动态条件统计订单数量* @param map* @return*/Integer countByMap(Map map);
UserMapper.xml
<select id="countByMap" resultType="java.lang.Integer">select count(id) from 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

产品原型

接口设计


ReportController
/*** 销量排名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);return Result.success(reportService.getSalesTop10(begin,end));}
ReportService
/*** 统计指定时间区间内的销量排名前10* @param begin* @param end* @return*/SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end);
ReportServiceImpl
/*** 统计指定时间区间内的销量排名前10* @param begin* @param end* @return*/public SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end) {LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);List<GoodsSalesDTO> salesTop10 = orderMapper.getSalesTop10(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
/*** 统计指定时间区间销量排名前十* @param begin* @param end* @return*/List<GoodsSalesDTO> getSalesTop10(LocalDateTime begin,LocalDateTime end);
UserMapper.xml
<select id="getSalesTop10" resultType="com.sky.dto.GoodsSalesDTO">SELECT name,SUM(od.number) number from order_detail od,orders o where 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 0,10</select>
功能测试:


相关文章:
外卖项目day14(day11)---数据统计
Apache ECharts 大家可以看我这篇文章: Apache ECharts-CSDN博客 营业额统计 产品原型 接口设计 新建admin/ReportController /*** 数据统计相关接口*/ RestController RequestMapping("/admin/report") Api(tags "数据统计相关接口") Slf…...
养猫科普!牙口不好的猫咪怎么选粮?好吃易消化主食罐推荐
我家的猫猫已经九岁了,已经是一位老奶奶了,她的牙口不太好。对于她来说,膨化猫粮过于硬,很难咀嚼,所以我为她准备了质地柔软的主食罐头。哪种主食罐头更适合牙口不好的猫咪呢?下面,我就来分享一…...
力扣刷题之3143.正方形中的最多点数
题干描述 给你一个二维数组 points 和一个字符串 s ,其中 points[i] 表示第 i 个点的坐标,s[i] 表示第 i 个点的 标签 。 如果一个正方形的中心在 (0, 0) ,所有边都平行于坐标轴,且正方形内 不 存在标签相同的两个点,…...
【更新2022】省级经济高质量发展指标体系测度 含代码 2000-2022
重磅更新!【章汕】制作“省级经济高质量发展指标体系测度 含代码”,市面上有这个版本的数据,但其内容非常不全面,个别指标有误,没有stata和代码,即使有代码小白也很容易报错;没有权重、宽面板等…...
缓冲流练习
练习1:拷贝文件 四种方式拷贝文件,并统计各自用时。 字节流的基本流:一次读写一个字节 字节流的基本流:一次读写一个字节数组 字节缓冲流:一次读写一个字节 字节缓冲流:一次读写一个字节数组 这里我只使用了…...
自己履行很多的话语,依旧按照这个方式进行生活
《明朝那些事儿》最后一段讲述了徐霞客的故事,作者当年明月通过徐霞客的生平表达了一种人生哲学。在书的结尾,当年明月写道:"成功只有一个——按照自己的方式,去度过人生",这句话被用作《明朝那些事儿》的结…...
交通预测数据文件梳理:METR-LA
文章目录 前言一、adj_METR-LA.pkl文件读取子文件1读取子文件2读取子文件3 二、METR-LA.h5文件 前言 最近做的实验比较多,对于交通预测数据的各种文件和文件中的数据格式理解愈加混乱,因此打算重新做一遍梳理来加深实验数据集的理解,本文章作…...
按钮类控件
目录 1.Push Button 代码示例: 带有图标的按钮 代码示例: 带有快捷键的按钮 代码示例: 按钮的重复触发 2.Radio Buttion 代码示例: 选择性别 代码示例: click, press, release, toggled 的区别 代码示例: 单选框分组 3.3 Check Box 代码示例: 获取复选按钮的取值 1.Pu…...
opencascade AIS_ViewController源码学习 视图控制、包含鼠标事件等
opencascade AIS_ViewController 前言 用于在GUI和渲染线程之间处理视图器事件的辅助结构。 该类实现了以下功能: 缓存存储用户输入状态(鼠标、触摸和键盘)。 将鼠标/多点触控输入映射到视图相机操作(平移、旋转、缩放࿰…...
拉削基础知识——拉床的类型及特点
拉床是所有机械加工工具中最简单的一种,由拉削工具、夹具、驱动装置和支撑架组成。拉削加工可获得较高的尺寸精度和较小的表面粗糙度,生产率较高,适用于大批量生产。拉床按其结构主要分为卧式和立式。应用领域和功能可分为液压拉床、自动拉床…...
docker-compose笔记
docker 目前docker官网已经无法登录,但是还可以从清华镜像站(https://mirrors.tuna.tsinghua.edu.cn/docker-ce/)下载。 使用方法可以参考早期文章《docker笔记》 docker-compose 可以从Github下载不同版本的二进制文件,例如do…...
C# 自定义控件无法加载
问题 在做winform开发时自己定义了一个控件,控件在工具箱中显示了,但是拖动到窗体设计器时会提示未能加载工具箱项xxx,将从工具箱中将其删除,如下图所示: 点击确定后,控件会从工具箱中移除。 解决方法 将 生成>…...
avl树自实现(带图),探讨平衡因子与旋转
引子: 在此之前,我们学过了搜索二叉树,这种树,在如果数据有序或接近有序的情况下,二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下,而且普通搜索二叉树无法有…...
Elasticsearch 的DSL查询,聚合查询与多维度数据统计
文章目录 搜索聚合高阶概念 搜索 即从一个索引下按照特定的字段或关键词搜索出符合用户预期的一个或者一堆cocument,然后根据文档的相关度得分,在返回的结果集里并根据得分对这些文档进行一定的排序。 聚合 根据业务需求,对文档中的某个或…...
【如何高效处理前端常见问题:策略与实践】
在快速发展的Web开发领域,前端作为用户与应用程序直接交互的界面,其重要性不言而喻。然而,随着技术的不断演进和项目的复杂化,前端开发者在日常工作中难免会遇到各种挑战和问题。本文旨在深入探讨前端开发中常见的问题类型&#x…...
聊聊前端 JavaScript 的扩展运算符 “...“ 的使用场景
前言 在 JavaScript 中,... 被称为 “扩展运算符” 或 “剩余参数运算符”。 扩展运算符是在 ES6(ECMAScript 2015)中被引入的,目的是为了提高语言的表达能力和代码的可读性。 根据上下文不同,它主要用在数组、对象…...
华为续签了,但我准备离职了
离职华为 今天在牛客网看到一篇帖子,名为《华为续签了,但我准备离职了》。 讲得挺真诚,可能也是一类毕业进华为的同学的心声。 贴主提到,当年自己还是应届毕业的时候,手握多个 offer,最终选的华为ÿ…...
RocketMQ 的认证与授权机制
Apache RocketMQ 是一个高性能、高吞吐量、分布式的消息中间件,广泛应用于异步通信、应用解耦、流量削峰等场景。在企业级应用中,消息安全尤为重要,本文将深入探讨 RocketMQ 的认证与授权机制,帮助开发者和系统管理员更好地理解和…...
【设计模式】六大原则-上
首先什么是设计模式? 相信刚上大学的你和我一样,在学习这门课的时候根本不了解这些设计原则和模式有什么用处,反而不如隔壁的C更有意思,至少还能弹出一个小黑框,给我个hello world。 如何你和我一样也是这么想…...
CRC16循环冗余校验
代码: #include<stdio.h> #include <stdint.h>#define uchar unsigned char #define uint unsigned int static const uint8_t auchCRCHi[] { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x0…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
ThreadLocal 源码
ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...
