苍穹外卖数据可视化

news2024/11/21 1:45:33

文章目录

        • 1、用户统计
        • 2、订单统计
        • 3、销量排名Top10

1、用户统计

所谓用户统计,实际上统计的是用户的数量。通过折线图来展示,上面这根蓝色线代表的是用户总量,下边这根绿色线代表的是新增用户数量,是具体到每一天。所以说用户统计主要统计两个数据,一个是总的用户数量,另外一个是新增用户数量

原型图:

image-20230102213727736

业务规则:

  • 基于可视化报表的折线图展示用户数据,X轴为日期,Y轴为用户数
  • 根据时间选择区间,展示每天的用户总量和新增用户量数据

接口设计

根据上述原型图设计接口。

image-20230102213809414 image-20230102213818334

VO设计

根据用户统计接口的返回结果设计VO

image-20230102211004237
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserReportVO implements Serializable {

    //日期,以逗号分隔,例如:2022-10-01,2022-10-02,2022-10-03
    private String dateList;

    //用户总量,以逗号分隔,例如:200,210,220
    private String totalUserList;

    //新增用户,以逗号分隔,例如:20,21,10
    private String newUserList;

}

根据接口定义,在ReportController中创建userStatistics方法

    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    @ApiOperation("用户统计")
    @GetMapping("/userStatistics")
    public Result<UserReportVO> userStatistics(
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){

        log.info("营业额统计:{},{}",begin,end);

        //调用业务获取用户统计数据
        UserReportVO userReportVO = reportService.getUserStatistics(begin,end);

        return Result.success(userReportVO);
    }

在ReportService接口中声明getUserStatistics方法

    /**
     * 用户统计数据
     * @param begin
     * @param end
     * @return
     */
    UserReportVO getUserStatistics(LocalDate begin, LocalDate end);

在ReportServiceImpl实现类中实现getUserStatistics方法

    /**
     * 用户统计数据
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
        //目标获取用户统计数据:用户每天总数量,每天新增数量 、 每天日期列表

        //获取每天新增用户数量
            //select count(*) from user where create_time >= 当天最小时间 and create_time <= 当天最大时间
        //获取每天用户总数量
            //select count(*) from user where create_time <= 当天最大时间

        //1、根据开始日期与结束日期生成每天日期集合列表
        List<LocalDate> dateList = getDateList(begin, end);


        //2、定义存储每天新增用户 和 每天新增用户集合
        ArrayList<Integer> createUserList = new ArrayList<>();
        ArrayList<Integer> totalUserList = new ArrayList<>();

        //3、遍历日期列表,每天数据
        for (LocalDate date : dateList) {
            //定义每天最大时间和最小时间
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date,LocalTime.MAX);

            //执行sql
            //将参数封装到map里
            Map<String,Object> map = new HashMap<>();

            //查询总用户
            map.put("endTime",endTime);
            Integer totalUser = userMapper.countByMap(map);
            totalUser = totalUser == null ? 0 : totalUser;
            totalUserList.add(totalUser);

            //查询新增用户,只需要再加一个开始条件
            map.put("beginTime",beginTime);
            Integer createUser = userMapper.countByMap(map);
            createUser = createUser == null ? 0 : createUser;
            createUserList.add(createUser);

        }

        //封装返回数据
        return UserReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .totalUserList(StringUtils.join(totalUserList,","))
                .newUserList(StringUtils.join(createUserList,","))
                .build();

    }

在UserMapper接口中声明countByMap方法

	/**
     * 根据动态条件统计用户数量
     * @param map
     * @return
     */
    Integer countByMap(Map map);

在UserMapper.xml文件中编写动态SQL

<select id="countByMap" resultType="java.lang.Integer">
        select count(id) from user
        <where>
            <if test="begin != null">
                and create_time &gt;= #{begin}
            </if>
            <if test="end != null">
                and create_time &lt;= #{end}
            </if>
        </where>
</select>
2、订单统计

订单统计通过一个折现图来展现,折线图上有两根线,这根蓝色的线代表的是订单总数,而下边这根绿色的线代表的是有效订单数,指的就是状态是已完成的订单就属于有效订单,分别反映的是每一天的数据。上面还有3个数字,分别是订单总数、有效订单、订单完成率,它指的是整个时间区间之内总的数据。

原型图:

image-20230107192859270

业务规则:

  • 有效订单指状态为 “已完成” 的订单
  • 基于可视化报表的折线图展示订单数据,X轴为日期,Y轴为订单数量
  • 根据时间选择区间,展示每天的订单总数和有效订单数
  • 展示所选时间区间内的有效订单数、总订单数、订单完成率,订单完成率 = 有效订单数 / 总订单数 * 100%

接口设计

根据上述原型图设计接口。

image-20230107192942872 image-20230107192952958

VO设计

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderReportVO implements Serializable {

    //日期,以逗号分隔,例如:2022-10-01,2022-10-02,2022-10-03
    private String dateList;

    //每日订单数,以逗号分隔,例如:260,210,215
    private String orderCountList;

    //每日有效订单数,以逗号分隔,例如:20,21,10
    private String validOrderCountList;

    //订单总数
    private Integer totalOrderCount;

    //有效订单数
    private Integer validOrderCount;

    //订单完成率
    private Double orderCompletionRate;

}

在ReportController中根据订单统计接口创建orderStatistics方法

    @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);

        //调用业务
        OrderReportVO orderReportVO = reportService.getOrderStatistics(begin,end);

        return Result.success(orderReportVO);

    }

在ReportService中根据订单统计接口

    /**
     * 订单统计数据
     * @param begin
     * @param end
     * @return
     */
    OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end);

实现Service

    /**
     * 订单统计数据
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) {
        //订单统计:日期列表dateList,每天订单数量列表

        //1、根据开始日期与结束日期生成列表
        List<LocalDate> dateList = getDateList(begin, end);
        //2、定义每天订单总数量 List<Integer> orderCountList 和每天有效订单数量列表 List<Integer> validOrderCountList
        List<Integer> orderCountList = new ArrayList<>();
        List<Integer> validOrderCountList = new ArrayList<>();

        //3、遍历日期列表dateList
        for (LocalDate date : dateList) {
            //生成当天最大时间和最小时间
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

            Map<String, Object> map = new HashMap<>();
            //获取当天订单
            map.put("beginTime",beginTime);
            map.put("endTime",endTime);
            Integer orderCount = orderMapper.orderCountByToday(map);
            orderCount = orderCount == null?0:orderCount;
            orderCountList.add(orderCount);

            //获取有效订单
            map.put("status", Orders.COMPLETED);
            Integer validOrder = orderMapper.orderCountByToday(map);
            validOrder = validOrder == null?0:validOrder;
            validOrderCountList.add(validOrder);
        }

        //4、计算所有天订单总数量和有效订单总数量
        Integer totalOrderCount = orderCountList.stream().reduce(Integer::sum).get();
        Integer validOrderCount = validOrderCountList.stream().reduce(Integer::sum).get();

        Double orderCompletionRate = 0.0;
        //5、计算完成率
        if (totalOrderCount != 0){
            orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;
        }


        //6、封装数据返回
        return OrderReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .orderCountList(StringUtils.join(orderCountList,","))
                .validOrderCountList(StringUtils.join(validOrderCountList,","))
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount)
                .orderCompletionRate(orderCompletionRate)
                .build();
    }

mapper层实现

    /**
     * 获取订单数
     * @param map
     * @return
     */
    Integer orderCountByToday(Map<String, Object> map);
<select id="countByMap" resultType="java.lang.Integer">
        select count(id) from orders
        <where>
            <if test="status != null">
                and status = #{status}
            </if>
            <if test="begin != null">
                and order_time &gt;= #{begin}
            </if>
            <if test="end != null">
                and order_time &lt;= #{end}
            </if>
        </where>
</select>
3、销量排名Top10

所谓销量排名,销量指的是商品销售的数量。项目当中的商品主要包含两类:一个是套餐,一个是菜品,所以销量排名其实指的就是菜品和套餐销售的数量排名。通过柱形图来展示销量排名,这些销量是按照降序来排列,并且只需要统计销量排名前十的商品。

原型图:

image-20230107203622747

业务规则:

  • 根据时间选择区间,展示销量前10的商品(包括菜品和套餐)
  • 基于可视化报表的柱状图降序展示商品销量
  • 此处的销量为商品销售的份数

接口设计

据上述原型图设计接口。

image-20230107203720606 image-20230107203730681

VO设计

根据销量排名接口的返回结果设计VO

image-20230107204028895
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SalesTop10ReportVO implements Serializable {

    //商品名称列表,以逗号分隔,例如:鱼香肉丝,宫保鸡丁,水煮鱼
    private String nameList;

    //销量列表,以逗号分隔,例如:260,215,200
    private String numberList;

}

Controller层

在ReportController中根据销量排名接口创建top10方法

    @ApiOperation("销售top10统计")
    @GetMapping("/top10")
    public Result<SalesTop10ReportVO> salesTop10Statistics(
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){

        log.info("销售前10排名{},{}",begin,end);

        SalesTop10ReportVO salesTop10ReportVO = reportService.getSalesTop10(begin,end);

        return Result.success(salesTop10ReportVO);

    }

Service层接口

    /**
     * 销售前10统计
     * @param begin
     * @param end
     * @return
     */
    SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end);

接口实现类

    /**
     * 销售前10统计
     *
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end) {
        //目标:top10统计:商品名称列表 List<String> nameList,每天销量列表List<Integer> numberList
        //获取最大和最小时间
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);

        //查询top商品和销量
        List<GoodsSalesDTO> goodsSalesDTOS = orderMapper.getTop10(beginTime,endTime);

        //获取商品名称列表集合
        List<String> nameList = goodsSalesDTOS.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        //获取销量列表集合
        List<Integer> numberList = goodsSalesDTOS.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());

        return SalesTop10ReportVO.builder()
                .nameList(StringUtils.join(nameList,","))
                .numberList(StringUtils.join(numberList,","))
                .build();
    }

mapper层

    /**
     * 获取top10
     * @param beginTime
     * @param endTime
     * @return
     */
    List<GoodsSalesDTO> getTop10(LocalDateTime beginTime, LocalDateTime endTime);
    <select id="getTop10" resultType="com.sky.dto.GoodsSalesDTO">
        select od.name,sum(od.number) number from orders o
            inner join order_detail od on o.id = od.order_id
                <where>
                    <if test="beginTime != null">
                        and order_time &gt;= #{beginTime}
                    </if>
                    <if test="endTime != null">
                        and order_time &lt;= #{endTime}
                    </if>
                </where>
                group by od.name order by number desc limit 10
    </select>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1720107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++系列-STL简介

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 什么是STL STL是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 STL的版本 原始版本 Alexander Stepa…

浅谈安科瑞ASJ10-LD1A智能漏电继电器的设计与应用-安科瑞 蒋静

一 产品简介 功能 ASJ10-LD1A安科瑞智能电力继电器 剩余电流保护可与低压断路器或低压接触器等组成组合式的剩余电流动作保护器&#xff0c;主要适用于交流50Hz&#xff0c;额定电压为400V及以下的TT或TN系统配电线路&#xff0c;防止接地故障电流引起的设备和电气火灾事故&a…

香橙派OriengePi AiPro 华为昇腾芯片开发板开箱测评

香橙派OriengePi AiPro 华为昇腾芯片开发板开箱测评 文章目录 前言OrangePi AIpro硬件相关及配置外观接口配置虚拟桌面网络配置拓展swap内存 软件相关及配置docker基础镜像搭建pytorch安装及匹配 软件测试使用yolo v8测试使用模型转换 总结 前言 博主有幸受邀CSDN测评香橙派与…

智能小家电风潮渗透美国市场,哪些产品适合入驻沃尔玛?

智能小家电风潮在美国市场持续渗透&#xff0c;这为众多品牌提供了良好的商机。沃尔玛作为全球零售巨头&#xff0c;自然成为许多品牌进驻美国市场的首选平台。 针对智能小家电产品&#xff0c;以下是一些适合入驻沃尔玛的产品类型&#xff1a; 一、智能厨房电器 美国市场接受…

如何基于知行之桥V2024快速搭建一个EDI工作流?

本文将基于知行之桥EDI系统V2024版本展开介绍&#xff0c;与之前的版本相比&#xff0c;UI界面的变化较为明显。 创建工作区 首先登录知行之桥EDI系统&#xff0c;输入用户名密码后将会看到 概览 页面。 点击 概览 右侧的 工作流&#xff0c;即可进入到 工作流 页面&#xff…

K8S 证书过期不能使用kubectl之后,kubeadm 重新生成证书

查询证书过期时间 kubeadm certs check-expiration重新生成证书 # 重新生成所有证书 kubeadm certs renew all # 重新生成某个组件的证书 kubeadm certs renew 组件名称 如&#xff1a;apiserver生成新的配置 # 重新生成kubeconfig配置 kubeadm init phase kubeconfig # 重…

12 FreeRTOS 调试与优化

1、调试 1.1 打印 在FreeRTOS工程中使用了microlib&#xff0c;里面实现了printf函数。 只需要实现一下以下函数即可使用printf。 int fputc(int ch; FILE *f); 假如要从串口实现打印函数&#xff1a; int fputc( int ch, FILE *f ) {//指定串口USART_TypeDef* USARTx USAR…

语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(二)音频数据预处理及去噪算法+Python源码应用

前言 深度学习技术在当今技术市场上面尚有余力和开发空间的&#xff0c;主流落地领域主要有&#xff1a;视觉&#xff0c;听觉&#xff0c;AIGC这三大板块。 目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相…

【火炬打宝策略】

打宝策略刷遗物&#xff1a; 时可4 只刷奇诊加稀有度&#xff0c;没有奇诊可以直接不打。

当新媒体运营开始说真话,这些道理你真的懂么?沈阳新媒体运营培训

运营新人&#xff0c;尤其是刚毕业、啥都不会的大学生&#xff0c;一定要认清的现实就是&#xff1a;虽然新媒体运营这个岗位门槛比较低&#xff0c;薪资也比较香&#xff0c;但绝不是养老型的工作。 平时大家还是很忙的&#xff0c;所以一定要摒弃学生思维&#xff0c;千万别…

vivo鄢楠:基于OceanBase 的降本增效实践

在3 月 20 日的2024 OceanBase 数据库城市行中&#xff0c;vivo的 体系与流程 IT 部 DBA 组总监鄢楠就“vivo 基于 OceanBase 的降本增效实践”进行了主题演讲。本文为该演讲的精彩回顾。 vivo 在1995年于中国东莞成立&#xff0c;作为一家全球领先的移动互联网智能终端公司&am…

【HarmonyOS - ArkTS - 状态管理】

概述 本文主要是从页面和应用级两个方面介绍了ArkTS中的状态管理的一些概念以及如何使用。可能本文比较粗略&#xff0c;细节化请前往官网(【状态管理】)学习&#xff0c;若有理解错误的地方&#xff0c;欢迎评论指正。 装饰器总览 由于下面会频繁提及到装饰器&#xff0c;所…

将三个字符串通过strcat连接起来并打印输出

将三个字符串通过strcat连接起来并打印输出 #include <stdio.h> #include <string.h> int main () { char a[10]"I", b[10]" am",c[10]" happy"; strcat(a,b); strcat(a,c); printf("%s",a); printf("\n"); re…

win10键盘按乱了,如何恢复?

今天键盘被宝宝给按乱了&#xff0c;好不容易给重新调整回来&#xff0c;记录备忘&#xff1a; 1、win10的asdf和方向键互换了&#xff1a; 使用Fnw键来回切换&#xff0c;OK&#xff01; 2、键盘的win键失效&#xff0c;例如&#xff1a;按winD无法显示桌面。此时&#xf…

Django企业招聘后台管理系统开发实战四

前言 首先我们看一下产品的需求背景&#xff0c;这个产品为了解决招聘面试的过程中&#xff0c;线下面试管理效率低&#xff0c;面试过程和结果不方便跟踪的痛点 招聘管理的系统几乎是每一家中小公司都需要的产品 我们以校园招聘的面试为例子来做 MVP 产品迭代 首先我们来看一下…

【计算机毕设】基于Spring Boot的课程作业管理系统 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 课程作业管理系统旨在为教师和学生提供一个便捷的平台&#xff0c;用于发布、提交和评定课程作业。本系统旨在提高作业管理的效率&#xff0c;促进教…

【免费Web系列】JavaWeb实战项目案例四

这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r 多表操作&员工列表查询 1. 多表关系 关于单表的操作(单表的设计、单表的增删改查)我们就已经学习完了。接下来我们就要来学习多表的操作&#xff0c;首先来学习多表的设计。 项目开发中&#xff0…

如何使用 Connector API 将数据提取到 Elasticsearch Serverless 中

作者&#xff1a;来自 Elastic Jedr Blaszyk Elasticsearch 支持一系列摄取方法。 其中之一是 Elastic Connectors&#xff0c;它将 SQL 数据库或 SharePoint Online 等外部数据源与 Elasticsearch 索引同步。 连接器对于在现有数据之上构建强大的搜索体验特别有用。 例如&…

618 购物指南:简单点 618 捡便宜,用这个利器就行

直接干货&#xff0c;看效果&#xff0c;安装脚本直接显示商家额外优惠券&#xff1a; 1、安装好脚本后&#xff0c;打开京东、淘宝(天猫) 商品详情页面&#xff0c;脚本会自动获取优惠券进行展示。 2、如果当前商品 处于 30 天最低价&#xff0c;脚本将自动进行标记 提醒&…

基于Python的校园预约打印网站的实现

基于Python的校园预约打印网站的实现 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 注册 新用户首先要进行注册信息填写&#xff0c;填写完成以后进行登录即可使用此网站 打印社 分别有…