外卖小程序10

news/2024/11/24 14:37:35/

目录

  • Apache ECharts
    • 介绍
      • 入门案例
      • 实现步骤
      • 代码
    • 总结
    • 需求1
      • Service层思路
      • 代码实现
      • Controller层
        • ReportController
      • Service层
        • ReportService
        • ReportServiceImpl
      • Mapper层
        • OrderMapper
        • OrderMapper.xml
    • 需求2
      • Service层思路
      • 代码实现
      • Controller层
        • ReportController
      • Service层
        • ReportService
        • ReportServiceImpl
      • Mapper层
        • UserMapper
        • UserMapper.xml
    • 需求3
      • Service层思路
      • 代码实现
      • Controller层
        • ReportController
      • Service层
        • ReportService
        • ReportServiceImpl
        • countOrder
      • Mapper层
        • OrderMapper
        • OrderMapper.xml

Apache ECharts

介绍

基于javascript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。

官网地址:https://echarts.apache.org/zh/index.html

入门案例

Apache Echarts官方提供的快速入门:https://echarts.apache.org/handbook/zh/get-started/

实现步骤

1.引入echarts.js

2.提供一个设置了宽高的DOM

3.初始化echarts实例

4.指定图表的配置项,数据

5.指定图表引用的配置项和数据

代码

echartsDemo.html

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>ECharts</title><!-- 引入刚刚下载的 ECharts 文件 --><script src="echarts.js"></script></head><body><!-- 为 ECharts 准备一个定义了宽高的 DOM --><div id="main" style="width: 600px;height:400px;"></div><script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data: ['销量']},xAxis: {data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']},yAxis: {},series: [{name: '销量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);</script></body>
</html>

总结

使用echarts图表重点在于分析图表需要的数据,一般后端需要以前端要求的格式响应需要的数据给前端以实现图表化

需求1

营业额统计

约定:以字符串的形式返回日期和营业额,数据之间以逗号隔开

Service层思路

根据前端传递的开始日期和结束日期封装日期集合

遍历日期集合,使用map集合封装查询条件,查询每天的营业额,将值为null的营业额设置为0,并添加到集合中去

使用StringUtils的join()方法将日期集合,营业额集合转换成以逗号隔开的字符串,并封装为返回值类型返回

代码实现

Controller层

ReportController

@Api("数据统计相关接口")
@RequestMapping("/admin/report")
@Slf4j
@RestController
public class ReportController {@Autowiredprivate ReportService reportService;/*** 获取店铺营业额** @param begin* @param end* @return*/@ApiOperation("获取店铺营业额")@GetMapping("/turnoverStatistics")public Result<TurnoverReportVO> getTurnover(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {log.info("获取店铺营业额,参数为:{},{}", begin, end);return Result.success(reportService.getTurnover(begin, end));}
}

Service层

ReportService

public interface ReportService {/*** 统计店铺某时间段内营业额** @param begin* @param end* @return*/TurnoverReportVO getTurnover(LocalDate begin, LocalDate end);
}

ReportServiceImpl

@Service
public class ReportServiceImpl implements ReportService {@Autowiredprivate OrderMapper orderMapper;/*** 统计店铺某时间段内营业额** @param begin* @param end* @return*/@Overridepublic TurnoverReportVO getTurnover(LocalDate begin, LocalDate 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 localDate : dateList) {LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);Map map = new HashMap();map.put("status", Orders.COMPLETED);map.put("begin", beginTime);map.put("end", endTime);Double dayTurnover = orderMapper.sumByMap(map);dayTurnover = dayTurnover == null ? 0.0 : dayTurnover;turnoverList.add(dayTurnover);}return TurnoverReportVO.builder().dateList(StringUtils.join(dateList, ",")).turnoverList(StringUtils.join(turnoverList, ",")).build();}
}

Mapper层

OrderMapper

@Mapper
public interface OrderMapper {/*** 动态条件查询店铺营业额** @param map* @return*/Double sumByMap(Map map);}

OrderMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.OrderMapper"><select id="sumByMap" resultType="java.lang.Double">select sum(amount)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>
</mapper>

需求2

用户统计

统计用户总量和新增用户量

Service层思路

根据前端传递的开始日期和结束日期封装日期集合

遍历日期集合,使用map集合封装结束日期,查询每天的用户总量,再封装开始日期,查询每天的新增用户量,将两者封装到集合中去

使用StringUtils的join()方法将日期集合,用户总量集合,新增用户量集合转换成以逗号隔开的字符串,并封装为返回值类型返回

代码实现

Controller层

ReportController

    /*** 用户统计** @param begin* @param end* @return*/@ApiOperation("用户统计")@GetMapping("/userStatistics")public Result<UserReportVO> getUserStatistic(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {log.info("用户统计,参数为:{},{}", begin, end);return Result.success(reportService.getUserStatistic(begin, end));}

Service层

ReportService

    /*** 指定时间段内用户统计** @param begin* @param end* @return*/UserReportVO getUserStatistic(LocalDate begin, LocalDate end);

ReportServiceImpl

/*** 统计用户数量** @param begin* @param end* @return*/@Overridepublic UserReportVO getUserStatistic(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<Integer> newUserList = new ArrayList<>();//存放用户总数List<Integer> totalUserList = new ArrayList<>();for (LocalDate localDate : dateList) {LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);Map map = new HashMap();map.put("end", endTime);Integer totalUser = userMapper.countByMap(map);map.put("begin", beginTime);Integer newUser = userMapper.countByMap(map);newUserList.add(newUser);totalUserList.add(totalUser);}return UserReportVO.builder().dateList(StringUtils.join(dateList, ",")).newUserList(StringUtils.join(newUserList, ",")).totalUserList(StringUtils.join(totalUserList, ",")).build();}

Mapper层

UserMapper

    /*** 动态统计用户数** @param map* @return*/Integer countByMap(Map map);

UserMapper.xml

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

需求3

订单统计

统计指定时间区间内的订单总数,有效订单总数,订单完成率(有效订单数/订单总数),每日订单总数,每日有效订单数

Service层思路

时间区间内总订单数的计算(stream流的使用,reduce,方法引用)

根据前端传递的开始日期和结束日期封装日期集合

遍历日期集合,使用map集合封装查询条件,查询每天的订单总量和有效订单总量,将两者封装到集合中去

使用stream流的reduce()方法合并集合,并调用Integer的sum()方法求和,计算订单总量和有效订单总量,计算订单完成率

使用StringUtils的join()方法将每日订单总量集合,每日有效订单集合,日期集合转换成以逗号隔开的字符串,并封装数据返回

代码实现

Controller层

ReportController

    /*** 订单数据统计** @param begin* @param end* @return*/@ApiOperation("统计订单数据")@GetMapping("/ordersStatistics")public Result<OrderReportVO> getOrderStatistic(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {log.info("统计订单数量,参数为:{},{}", begin, end);return Result.success(reportService.getOrderStatistic(begin, end));}

Service层

ReportService

    /*** 指定时间段内订单统计** @param begin* @param end* @return*/OrderReportVO getOrderStatistic(LocalDate begin, LocalDate end);

ReportServiceImpl

/*** 订单统计** @param begin* @param end* @return*/@Overridepublic OrderReportVO getOrderStatistic(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);}//存放每日订单数// select count(id) from orders where order_time > ? and order_time < ?List<Integer> orderCountList = new ArrayList<>();//存放每日有效订单数// select count(id) from orders where order_time > ? and order_time < ? and status = ?List<Integer> validOrderCountList = new ArrayList<>();//查询每日订单数据for (LocalDate localDate : dateList) {LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);Integer validDayOrderCount = countOrder(beginTime, endTime, Orders.COMPLETED);Integer dayOrderCount = countOrder(beginTime, endTime, null);orderCountList.add(dayOrderCount);validOrderCountList.add(validDayOrderCount);}//计算指定时间区间内的订单总数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, ",")).orderCompletionRate(orderCompletionRate).totalOrderCount(totalOrderCount).validOrderCount(validOrderCount).orderCountList(StringUtils.join(orderCountList, ",")).validOrderCountList(StringUtils.join(validOrderCountList, ",")).build();}

countOrder

    /*** 根据条件统计订单数据** @param beginTime* @param endTime* @param status* @return*/private Integer countOrder(LocalDateTime beginTime, LocalDateTime endTime, Integer status) {Map map = new HashMap();map.put("begin", beginTime);map.put("end", endTime);map.put("status", status);Integer orderCount = orderMapper.countOrderByMap(map);return orderCount;}

Mapper层

OrderMapper

    /*** 动态统计订单数** @param map* @return*/Integer countOrderByMap(Map map);

OrderMapper.xml

    <select id="countOrderByMap" 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>

http://www.ppmy.cn/news/47327.html

相关文章

技术分析内核并发消杀器(KCSAN)一文解决!

一、KCSAN介绍 KCSAN(Kernel Concurrency Sanitizer)是一种动态竞态检测器&#xff0c;它依赖于编译时插装&#xff0c;并使用基于观察点的采样方法来检测竞态&#xff0c;其主要目的是检测数据竞争。 KCSAN是一种检测LKMM(Linux内核内存一致性模型)定义的数据竞争(data race…

电路原理-反激式电路

1、1反激式电路是小功率电源(150W以下)当中&#xff0c;最常用的电路&#xff0c;它的工作原理如下。 1、2如图1&#xff0c;变压器T1&#xff0c;标记红点的端&#xff0c;12、3、A为同名端&#xff0c;10、1、B为异名端。 当MOS管导通的时候&#xff0c;初级绕组N1、…

ROS学习第九节——服务通信

1.基本介绍 服务通信较之于话题通信更简单些&#xff0c;理论模型如下图所示&#xff0c;该模型中涉及到三个角色: ROS master(管理者)Server(服务端)Client(客户端) ROS Master 负责保管 Server 和 Client 注册的信息&#xff0c;并匹配话题相同的 Server 与 Client &#…

Scrum of Scrums规模化敏捷开发管理全流程

Scrum of Scrums是轻量化的规模化敏捷管理模式&#xff0c;Leangoo领歌可以完美支持Scrum of Scrums多团队敏捷管理。 Scrum of Scrums的场景 Scrum of Scrums是指多个敏捷团队共同开发一个大型产品、项目或解决方案。Leangoo提供了多团队场景下的产品路线图规划、需求管理、…

函数式编程、Stream流操作复习

Lambda表达式 使用 当一个接口中只含有一个抽象方法时&#xff0c;这个接口就叫做函数式接口 一般使用FunctionalInterface注解来标识这个接口是一个函数式接口。 但不论有没有标识这个注解&#xff0c;只要接口中只有一个抽象方法&#xff0c;那么这个接口就是函数式接口 …

(PCB系列七)PCB差分信号布线及其要点

1、差分信号的定义 差分传输是一种信号传输的技术&#xff0c;区别于传统的一根信号线一根地线的做法&#xff0c;差分传输在这两根线上都传输信号&#xff0c;这两个信号的振幅相同&#xff0c;相位相反。在这两根线上的传输的信号就是差分信号。信号接收端比较这两个电压的差…

ubuntu虚拟机下搭建zookeeper集群,安装jdk压缩包,搭建Hadoop集群与spark集群的搭建【上篇】

系列文章目录 在vmbox里面安装Ubuntu16.04并且配置jdk以及Hadoop配置的教程【附带操作步骤】 虚拟机vmware下安装Ubuntu16.04修改屏幕尺寸与更新源&#xff0c;以及对应的安装vim和vim常见的操作 Hadoop与主机连接以及20版本的Hadoop配置网络的问题_hadoop连不上网 Hadoop升…

deepstream开发学习笔记: 追踪越界

main.cpp 文件解析 1. 创建元素前的准备 GStreamer是一个开源的流媒体框架&#xff0c;用于构建音频和视频流应用程序。它提供了一组库和工具&#xff0c;可以通过它们将多个组件&#xff08;element&#xff09;组合在一起以构建流媒体应用程序。以下是对几个常见组件的简要解…