当前位置: 首页 > news >正文

#苍穹外卖# day 10-11

目录

day10订单状态定时处理、来电提醒和客户催单

1 SpringTask

2 订单状态自动处理

3 WebSocket

4 外卖来单提醒

day11 图形报表

1 ApacheECharts

2 营业额统计

3 用户统计

4 订单统计

5 销量排名TOP10


day10订单状态定时处理、来电提醒和客户催单

1 SpringTask

概念:是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。

作用:定时自动执行某段代码

core表达式

2 订单状态自动处理

代码实现:

package com.sky;import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j//开启日志注解
@EnableCaching//开启缓存注解
@EnableScheduling//开启定时任务
public class SkyApplication {public static void main(String[] args) {SpringApplication.run(SkyApplication.class, args);log.info("server started");}
}
package com.sky.task;import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.util.List;/*** 定时任务类,定时处理任务状态*/@Slf4j
@Component
public class OrderTask {@Autowiredprivate OrderMapper orderMapper;/*** 处理超时订单*/@Scheduled(cron = "0 * * * * ?")//每分钟执行一次public void processTimeoutOrder() {log.info("处理超时订单{}", LocalDateTime.now());LocalDateTime time = LocalDateTime.now().plusMinutes(-15);//处理超时订单List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, time.toString());if (ordersList != null && !ordersList.isEmpty()) {for (Orders orders : ordersList) {orders.setStatus(Orders.CANCELLED);//设置订单状态为已取消orders.setCancelReason("订单超时,自动取消");//设置取消原因orders.setCancelTime(LocalDateTime.now());//设置取消时间orderMapper.update(orders);//更新订单}}}@Scheduled(cron = "0 0 1 * * ?")//每天凌晨1点执行一次public void processCompletedOrder() {log.info("处理待派送订单{}", LocalDateTime.now());LocalDateTime time = LocalDateTime.now().plusMinutes(-60);List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.CONFIRMED, time.toString());if (ordersList != null && !ordersList.isEmpty()) {for (Orders orders : ordersList) {orders.setStatus(Orders.COMPLETED);//设置订单状态为已完成orderMapper.update(orders);//更新订单}}}}

Mapper接口实现

    /*** 根据状态和下单时间查询订单* @param status* @param orderTime*/@Select("select * from orders where status =#{status} and order_time <#{orderTime}")List<Orders> getByStatusAndOrderTimeLT(Integer status, String orderTime);

3 WebSocket

4 外卖来单提醒

day11 图形报表

1 ApacheECharts

快速上手 - 使用手册 - Apache ECharts

2 营业额统计

代码开发

package com.sky.controller.admin;import com.sky.result.Result;
import com.sky.vo.TurnoverReportVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sky.service.ReportService;import java.time.LocalDate;@RequestMapping("/admin/report")
@RestController
@Api(tags = "数据统计相关接口")
@Slf4j
public class ReportController {@Autowiredprivate ReportService reportService;@GetMapping("/turnoverStatistics")@ApiOperation("营业额统计")public Result<TurnoverReportVO> turnoverStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {TurnoverReportVO turnoverReportVO = reportService.getTurnoverStatistics(begin, end);return Result.success(turnoverReportVO);}
}

Service业务层

package com.sky.service;import com.sky.vo.TurnoverReportVO;import java.time.LocalDate;public interface ReportService {/*** 营业额统计** @param begin* @param end* @return*/TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end);}

接口实现类

package com.sky.service.impl;import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.service.ReportService;
import com.sky.vo.TurnoverReportVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;@Slf4j
@Service
public class ReportServiceImpl implements ReportService {@Autowiredprivate OrderMapper orderMapper;/*** 营业额统计** @param begin* @param end* @return*/@Overridepublic TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {List<LocalDate> dateList = new ArrayList<>();LocalDate currentDate = begin;while (!currentDate.isAfter(end)) {dateList.add(currentDate);currentDate = currentDate.plusDays(1);}List<Double> turnoverList = new ArrayList<>();for (LocalDate date : dateList) {LocalDateTime startOfDay = date.atStartOfDay(); // 等价于 LocalTime.MINLocalDateTime endOfDay = date.atTime(LocalTime.MAX);Map<String, Object> params = new HashMap<>();params.put("begin", startOfDay);params.put("end", endOfDay);params.put("status", Orders.COMPLETED);Double turnover = orderMapper.sumByMap(params);turnoverList.add(turnover != null ? turnover : 0.0);}// 格式化日期和营业额DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");List<String> formattedDates = dateList.stream().map(date -> date.format(formatter)).collect(Collectors.toList());String dateStr = String.join(",", formattedDates);List<String> formattedTurnovers = turnoverList.stream().map(amount -> String.format("%.2f", amount)).collect(Collectors.toList());String turnoverStr = String.join(",", formattedTurnovers);return TurnoverReportVO.builder().dateList(dateStr).turnoverList(turnoverStr).build();}
}

Order.Mapper

    /*** 根据动态条件统计数量* @param map*/Double sumByMap(Map map);

XML文件

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

3 用户统计

代码实现:

controller控制层

    /*** 用户统计** @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) {UserReportVO userReportVO = reportService.getUserStatistics(begin, end);return Result.success(userReportVO);}

Service业务层

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

接口实现类

    /*** 用户统计** @param begin* @param end* @return*/@Overridepublic UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {List<LocalDate> dateList = new ArrayList<>();// 用于存储日期的列表(存从begin 到 end)LocalDate currentDate = begin;while (!currentDate.isAfter(end)) {// 循环判断是否大于结束日期dateList.add(currentDate);currentDate = currentDate.plusDays(1);}//统计用户新增数量(select count(id) from user where create_time < ? and create_time > ? )// 统计用户总数(select count(id) from user from user where create _time < ? )List<Integer> newUserList = new ArrayList<>();List<Integer> totalUserList = new ArrayList<>();for (LocalDate date : dateList) {LocalDateTime startOfDay = date.atStartOfDay();LocalDateTime endOfDay = date.atTime(LocalTime.MAX);Map<String, Object> params = new HashMap<>();//  统计用户新增数量params.put("end", endOfDay);Integer newUser = userMapper.countByMap(params);// 统计用户总数params.put("begin", startOfDay);Integer totalUser = userMapper.countByMap(params);newUserList.add(newUser);totalUserList.add(totalUser);}// 格式化日期和用户数量(先将日期格式化为字符串,并将用户的数据新增与总的进行拼接用于展示)List<String> formattedDates = dateList.stream().map(date -> date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))).collect(Collectors.toList());String dateStr = String.join(",", formattedDates);String newUserStr = newUserList.stream().map(String::valueOf).collect(Collectors.joining(","));String totalUserStr = totalUserList.stream().map(String::valueOf).collect(Collectors.joining(","));return UserReportVO.builder().dateList(dateStr).newUserList(newUserStr).totalUserList(totalUserStr).build();}

Mapper接口

    /*** 根据动态条件统计数量** @param params*/Integer countByMap(Map<String, Object> params);

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>

展示

4 订单统计

代码实现:

    /*** 订单统计** @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) {OrderReportVO orderReportVO = reportService.getOrdersStatistics(begin, end);log.info("订单统计:{}",orderReportVO);return Result.success(orderReportVO);}

Service业务层接口

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

接口实现类

    /*** 订单统计** @param begin* @param end* @return*/@Overridepublic OrderReportVO getOrdersStatistics(LocalDate begin, LocalDate end) {// 用于存储日期的列表List<LocalDate> dateList = new ArrayList<>();LocalDate currentDate = begin;while (!currentDate.isAfter(end)) {dateList.add(currentDate);currentDate = currentDate.plusDays(1);}//查询每一天的订单数据(总的和有效的)List<Integer> ValidOrderCountList = new ArrayList<>();List<Integer> totalOrderCountList = new ArrayList<>();for (LocalDate date : dateList) {LocalDateTime startOfDay = date.atStartOfDay();LocalDateTime endOfDay = date.atTime(LocalTime.MAX);Map<String, Object> params = new HashMap<>();params.put("begin", startOfDay);params.put("end", endOfDay);// 查询每天的订单总数Integer totalOrderCount = orderMapper.countByMap(params);// 查询每天的有效订单总数params.put("status", Orders.COMPLETED);Integer validOrderCount = orderMapper.countByMap(params);ValidOrderCountList.add(validOrderCount);totalOrderCountList.add(totalOrderCount);}//计算时间区间内的订单总数与有效订单总数,直接对应的List进行求和即可Integer totalSum = totalOrderCountList.stream().reduce(Integer::sum).get();Integer validSum = ValidOrderCountList.stream().reduce(Integer::sum).get();// 计算订单完成率Double orderCompletionRate= 0.0;if(totalSum!=0){orderCompletionRate = validSum / (double) totalSum;}// 将日期列表转换为字符串List<String> formattedDates = dateList.stream().map(date -> date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))).collect(Collectors.toList());String dateStr = String.join(",", formattedDates);// 将订单数量转换为字符串String totalOrderCountStr = totalOrderCountList.stream().map(String::valueOf).collect(Collectors.joining(","));String validOrderCountStr = ValidOrderCountList.stream().map(String::valueOf).collect(Collectors.joining(","));return OrderReportVO.builder().dateList(dateStr).orderCountList(totalOrderCountStr).validOrderCountList(validOrderCountStr).totalOrderCount(totalSum).validOrderCount(validSum).orderCompletionRate(orderCompletionRate).build();}

Mapper接口

    /*** 根据动态条件统计数量** @param params*/Integer countByMap(Map<String, Object> params);

MapperXML文件

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

5 销量排名TOP10

代码实现:

Controller控制层

    /*** 销量排名** @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) {SalesTop10ReportVO salesTop10ReportVO = reportService.getSalesTop10(begin, end);log.info("销量排名:{}", salesTop10ReportVO);return Result.success(salesTop10ReportVO);}

Service业务层接口

    /*** 销量排名top10** @param begin* @param end* @return*/SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end);

接口实现类

    }/*** 销量排名top10** @param begin* @param end* @return*/@Overridepublic SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end) {LocalDateTime beginTime = begin.atStartOfDay();LocalDateTime endTime = end.atTime(LocalTime.MAX);List<GoodsSalesDTO> salesTop10 = orderMapper.getSalesTop10(beginTime, endTime);List<String> names = salesTop10.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());String nameList = String.join(",", names);List<Integer> numbers = salesTop10.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());String numberList = numbers.stream().map(String::valueOf).collect(Collectors.joining(","));return SalesTop10ReportVO.builder().nameList(nameList).numberList(numberList).build();}

Mapper持久层接口

    /*** 查询销量排名top10** @param begin* @param end* @return*/List<GoodsSalesDTO> getSalesTop10(LocalDateTime begin, LocalDateTime end);

Mapper持久层XML文件

    <select id="getSalesTop10" resultType="com.sky.dto.GoodsSalesDTO">select og.name, sum(og.number) as number from orders oleft join order_detail og on o.id = og.order_idwhere o.status = 5<if test="begin != null">and o.order_time &gt;= #{begin}</if><if test="end != null">and o.order_time &lt;= #{end}</if>group by og.nameorder by number desclimit 0,10</select>

效果展示

相关文章:

  • Move Registry 发布,实现 Sui 的超级互操作性
  • ubuntu22.04部署Snipe-IT
  • MYSQL 常用字符串函数 和 时间函数详解
  • 信息学奥赛一本通 1509:【例 1】Intervals | OpenJudge 百练 1201:Intervals
  • 云服务器centos 安装hadoop集群
  • CS001-7-hbao
  • 海之淀攻略
  • 【视频时刻检索】Text-Video Retrieval via Multi-Modal Hypergraph Networks 论文阅读
  • 驱动开发硬核特训 · Day 21(上篇) 抽象理解 Linux 子系统:内核工程师的视角
  • Spring的xxxAware接口工作原理-笔记
  • 高等数学第三章---微分中值定理与导数的应用(3.1微分中值定理3.2洛必达法则)
  • 如何设置极狐GitLab 议题截止日?
  • 050_基于springboot的音乐网站
  • 图解YOLO(You Only Look Once)目标检测(v1-v5)
  • 零基础上手Python数据分析 (23):NumPy 数值计算基础 - 数据分析的加速“引擎”
  • 深度强化学习(DRL)实战:从AlphaGo到自动驾驶
  • React 文件链条
  • [论文阅读]ReAct: Synergizing Reasoning and Acting in Language Models
  • 设备接入与APP(应用程序)接入华为云iotDA平台的详细操作步骤及获取方式
  • 【动手学大模型开发】VSCode 连接远程服务器
  • 金隅集团:今年拿地将选择核心热门地块,稳健审慎投资
  • 我国风电光伏装机历史性超过火电
  • 现场|贝聿铭上海大展:回到他建筑梦的初始之地
  • 安徽铁塔再通报“会议室不雅行为”事件:涉事员工停职检查
  • 著名茶叶专家谢丰镐逝世,享年95岁
  • 牛市早报|特朗普称或将“大幅降低”对华关税,外交部回应