苍穹外卖数据可视化

文章目录

        • 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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

谷歌上架,可以用云手机来完成开发者个人号“20+14”封测?

根据谷歌的政策要求&#xff0c;自2023年11月13日之后创建的个人开发者账号&#xff0c;其应用必须满足20人连续14天封闭测试的要求&#xff0c;才能在Google Play 中上架正式版应用。 20人连续测试14天&#xff0c;这对大多数开发者&#xff0c;尤其是那些采用矩阵方式上架的开…

变现实谈,我要的不是灵光一现,而是真实的实现!——感悟篇

变现要的是行动不是想法 正文时代奇点奇迹 点题以己及人 正文 每当我看到了一个有趣的事情 我会在脑中构思一些想法 会贴合我当下的想要做的事情 比如 在我写下这篇文章之前 我看到了 二战期间的诞生的一个奇迹 可口可乐 我就思考 咦 原来可口可乐居然是在这么个时间点成长…

Vue.js2+Cesium1.103.0 十六、多模型轨迹运动

Vue.js2Cesium1.103.0 十六、多模型轨迹运动 Demo <template><div id"cesium-container" style"width: 100%; height: 100%;"><ul class"ul"><li v-for"(item, index) of deviceInfo" :key"index" cl…

SqlServer还原系统库步骤及问题解决

还原master 需要切换到binn目录 Cd C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Binn 关闭服务 用单用户模式启动 SQL Server 默认实例 sqlservr.exe -m 直接单用户登录 恢复master备份文件 RESTORE DATABASE master FROM DISK E:\dbbak\txic_ke…

低代码与人工智能的深度融合:行业应用的广泛前景

引言 在当今快速变化的数字化时代&#xff0c;企业面临着越来越多的挑战和机遇。低代码平台和人工智能技术的兴起&#xff0c;为企业提供了新的解决方案&#xff0c;加速了应用开发和智能化转型的步伐。 低代码平台的基本概念及发展背景 低代码平台是一种软件开发方法&#x…

Golang | Leetcode Golang题解之第119题杨辉三角II

题目&#xff1a; 题解&#xff1a; func getRow(rowIndex int) []int {row : make([]int, rowIndex1)row[0] 1for i : 1; i < rowIndex; i {row[i] row[i-1] * (rowIndex - i 1) / i}return row }

python基础-数据结构-int类型——你知道python的最大整数是什么吗?无限大?还是sys.maxsize?

文章目录 int底层源码最大整数推断 int底层源码 python 的int类型貌似并没有一个位数上线&#xff0c;然而我们知道其他语言的整数都是有位数&#xff0c;一般为32位或者64位等&#xff0c;那么python是怎么实现int类型没有位数限制的呢&#xff0c;下面这段代码是cpython仓库…

ams仿真将一组输出波形转化为所对应的十进制code

virtuoso ADE XL ams仿真将一组输出波形转化为所对应的十进制code 选中一组波形 输入波形翻转电压&#xff0c;起个名字

复习leetcode第二题:两数相加

本文会给出笔者自己的解答&#xff08;代码较为冗余&#xff0c;其实就是屎山代码&#xff09;以及优秀代码的解析 下图是题目 解法1&#xff08;笔者所使用的办法&#xff09;&#xff1a; 解题思路&#xff1a; 以下思路是基于示例1&#xff08;上图&#xff09;思考的 步骤…

【JS红宝书学习笔记】第6章 集合引用类型

第6章 集合引用类型 对象 数组与定型数组 Map、WeakMap、Set 以及 WeakSet 类型 1. object 很适合存储和在应用程序间交换数据。 显式创建object的两种方式&#xff1a; &#xff08;1&#xff09;new操作符 let person new Object(); person.name "Nicholas";…

nginx的安装001

Nginx是一款高性能的HTTP和反向代理服务器&#xff0c;以及邮件代理服务器&#xff0c;由 Igor Sysoev 开发并公开发布于2004年。Nginx以其高并发处理能力、低内存消耗和稳定性著称&#xff0c;特别适合部署在高流量的网站上。 操作系统&#xff1a; CentOS Stream 9 安装步骤…

CentOS7配置国内清华源并安装docker-ce以及配置docker加速

说明 由于国内访问国外的网站包括docker网站&#xff0c;由于种种的原因经常打不开&#xff0c;或无法访问&#xff0c;所以替换成国内的软件源和国内镜像就是非常必要的了&#xff0c;这里整理了我安装配置的基本的步骤。 国内的软件源有很多&#xff0c;这里选择清华源作为…

官方小游戏项目

一 项目原理&#xff1a;看广告&#xff0c;操作简单&#xff0c;时间自由&#xff0c;适合利用业余时间来做&#xff0c;一个广告大概在15s-30s之间。 二 介绍&#xff1a;给你开代理权限&#xff0c;你就有独立后台管理系统&#xff0c;监测每台手机每条广告的情况&#xff0…

案例研究|MeterSphere助力万物云构建高效自动化测试平台

万物云空间科技服务股份有限公司&#xff08;以下简称为“万物云”&#xff09;&#xff0c;前身为万科物业发展股份有限公司&#xff0c;是国内领先的物管龙头上市公司。作为一家科技引领的全域空间服务商&#xff0c;万物云致力于打造产业级共享服务平台&#xff0c;基于空间…

【qt】自定义对话框

自定义对话框 一.自定义对话框的使用1.应用场景2.项目效果3.界面拖放4.模型和视图的设置5.action功能实现 二.自定义对话框的创建1.设置对话框界面2.创建对话框 三.对话框的功能与样式实现1.对话框数据的交换2.对话框的显示3.设置对话框的特性4.完成按钮的功能 四.编辑表头的对…

根据PDF模版填充数据并生成新的PDF

准备模版 使用 福昕高级PDF编辑器 &#xff08;本人用的这个&#xff0c;其他的也行&#xff0c;能作模版就行&#xff09;打开PDF文件点击 表单 选项&#xff0c;点击 文本域在需要填充数据的位置设计文本域设置 名称、提示名称相当于 属性名&#xff0c;提示就是提示&#x…

Docker的数据管理(数据卷+数据卷容器)

文章目录 一、Docker的数据管理1、概述2、主要的技术&#xff08;三种数据挂载方式&#xff09;2.1、数据卷&#xff08;Volumes&#xff09;2.2、绑定挂载&#xff08;Bind mounts&#xff09;2.3、tmpfs挂载&#xff08;Tmpfs mounts&#xff09;2.4、之间的关系&#xff08;…

移动端性能测试(android/ios)

solox官网 https://github.com/smart-test-ti/SoloX solox简介 实时收集android/ios性能的工具&#xff0c;Android设备无需Root&#xff0c;iOS设备无需越狱。有效解决Android和iOS性能的测试和分析挑战。 solox安装 环境准备 python安装3.10以上的 python官网下载地址…

CasaOS:开源家庭云系统安装

CasaOS是一个基于Docker生态系统的开源家庭云系统&#xff0c;专为家庭场景而设计。致力于打造全球最简单、最易用、最优雅的家居云系统。安装CasaOS可以给鲁班猫带来更好的局域网文件传输体验。 安装脚本 wget -qO- https://get.casaos.io | sudo bash软件截图

【论文复现|智能算法改进】基于自适应蜣螂算法的无人机三维路径规划方法

目录 1.UAV路径规划数学模型2.改进点3.结果展示4.参考文献5.代码获取 1.UAV路径规划数学模型 【智能算法应用】蜣螂优化算法DBO求解UAV路径规划 2.改进点 混沌序列初始化 在处理复杂的优化问题时&#xff0c;原始蜣螂算法采用随机生成种群的方法进行种群初始化&#xff0c;…