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

网站icp 备案查询wordpress上显示pdf

网站icp 备案查询,wordpress上显示pdf,图片分页wordpress主题,企业网站规划书范文苍穹外卖-day10 课程内容 Spring Task订单状态定时处理WebSocket来单提醒客户催单 功能实现#xff1a;订单状态定时处理、来单提醒和客户催单 订单状态定时处理#xff1a; 来单提醒#xff1a; 客户催单#xff1a; 1. Spring Task 1.1 介绍 Spring Task 是Spring框架提供… 苍穹外卖-day10 课程内容 Spring Task订单状态定时处理WebSocket来单提醒客户催单 功能实现订单状态定时处理、来单提醒和客户催单 订单状态定时处理 来单提醒 客户催单 1. Spring Task 1.1 介绍 Spring Task 是Spring框架提供的任务调度工具可以按照约定的时间自动执行某个代码逻辑。 定位定时任务框架 作用定时自动执行某段Java代码 为什么要在Java程序中使用Spring Task 应用场景 1). 信用卡每月还款提醒 2). 银行贷款每月还款提醒 3). 火车票售票系统处理未支付订单 4). 入职纪念日为用户发送通知 强调只要是需要定时处理的场景都可以使用Spring Task 1.2 cron表达式 cron表达式其实就是一个字符串通过cron表达式可以定义任务触发的时间 构成规则分为6或7个域由空格分隔开每个域代表一个含义 每个域的含义分别为秒、分钟、小时、日、月、周、年(可选) 举例 2022年10月12日上午9点整 对应的cron表达式为0 0 9 12 10 ? 2022 说明一般日和周的值不同时设置其中一个设置另一个用表示。 比如描述2月份的最后一天最后一天具体是几号呢可能是28号也有可能是29号所以就不能写具体数字。 为了描述这些信息提供一些特殊的字符。这些具体的细节我们就不用自己去手写因为这个cron表达式它其实有在线生成器。 cron表达式在线生成器在线Cron表达式生成器 可以直接在这个网站上面只要根据自己的要求去生成corn表达式即可。所以一般就不用自己去编写这个表达式。 通配符 * 表示所有值 ? 表示未说明的值即不关心它为何值 - 表示一个指定的范围 , 表示附加一个可能值 / 符号前表示开始时间符号后表示每次递增的值 cron表达式案例 */5 * * * * ? 每隔5秒执行一次 0 */1 * * * ? 每隔1分钟执行一次 0 0 5-15 * * ? 每天5-15点整点触发 0 0/3 * * * ? 每三分钟触发一次 0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发 0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发 0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 0 0 10,14,16 * * ? 每天上午10点下午2点4点 1.3 入门案例 1.3.1 Spring Task使用步骤 1). 导入maven坐标 spring-context已存在 2). 启动类添加注解 EnableScheduling 开启任务调度 3). 自定义定时任务类 1.3.2 代码开发 编写定时任务类 进入sky-server模块中 package com.sky.task;import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;import java.util.Date;/*** 自定义定时任务类*/ Component Slf4j public class MyTask {/*** 定时任务 每隔5秒触发一次*/Scheduled(cron 0/5 * * * * ?)public void executeTask(){log.info(定时任务开始执行{},new Date());} } 开启任务调度 启动类添加注解 EnableScheduling 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);} } 1.3.3 功能测试 启动服务查看日志 每隔5秒执行一次。 2.订单状态定时处理 2.1 需求分析 用户下单后可能存在的情况 下单后未支付订单一直处于**“待支付”**状态用户收货后管理端未点击完成按钮订单一直处于**“派送中”**状态 对于上面两种情况需要通过定时任务来修改订单状态具体逻辑为 通过定时任务每分钟检查一次是否存在支付超时订单下单后超过15分钟仍未支付则判定为支付超时订单如果存在则修改订单状态为“已取消”通过定时任务每天凌晨1点检查一次是否存在“派送中”的订单如果存在则修改订单状态为“已完成” 2.2 代码开发 1). 自定义定时任务类OrderTask待完善 package com.sky.task;/*** 自定义定时任务实现订单状态定时处理*/ Component Slf4j public class OrderTask {Autowiredprivate OrderMapper orderMapper;/*** 处理支付超时订单*/Scheduled(cron 0 * * * * ?)public void processTimeoutOrder(){log.info(处理支付超时订单{}, new Date());}/*** 处理“派送中”状态的订单*/Scheduled(cron 0 0 1 * * ?)public void processDeliveryOrder(){log.info(处理派送中订单{}, new Date());}} 2). 在OrderMapper接口中扩展方法: /*** 根据状态和下单时间查询订单* param status* param orderTime*/Select(select * from orders where status #{status} and order_time #{orderTime})ListOrders getByStatusAndOrdertimeLT(Integer status, LocalDateTime orderTime); 3). 完善定时任务类的processTimeoutOrder方法 /*** 处理支付超时订单*/Scheduled(cron 0 * * * * ?)public void processTimeoutOrder(){log.info(处理支付超时订单{}, new Date());LocalDateTime time LocalDateTime.now().plusMinutes(-15);// select * from orders where status 1 and order_time 当前时间-15分钟ListOrders ordersList orderMapper.getByStatusAndOrdertimeLT(Orders.PENDING_PAYMENT, time);if(ordersList ! null ordersList.size() 0){ordersList.forEach(order - {order.setStatus(Orders.CANCELLED);order.setCancelReason(支付超时自动取消);order.setCancelTime(LocalDateTime.now());orderMapper.update(order);});}} 4). 完善定时任务类的processDeliveryOrder方法 /*** 处理“派送中”状态的订单*/Scheduled(cron 0 0 1 * * ?)public void processDeliveryOrder(){log.info(处理派送中订单{}, new Date());// select * from orders where status 4 and order_time 当前时间-1小时LocalDateTime time LocalDateTime.now().plusMinutes(-60);ListOrders ordersList orderMapper.getByStatusAndOrdertimeLT(Orders.DELIVERY_IN_PROGRESS, time);if(ordersList ! null ordersList.size() 0){ordersList.forEach(order - {order.setStatus(Orders.COMPLETED);orderMapper.update(order);});}} 2.3 功能测试 可以通过如下方式进行测试 查看控制台sql查看数据库中数据变化 支付超时的订单测试 1). 查看订单表 有一条订单状态为1。订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消 2). 开启定时任务 启动服务观察控制台日志。处理支付超时订单任务每隔1分钟执行一次。 3). 再次查看订单表 状态已更改为6已取消。 证明定时任务已生效。 处理“派送中”状态的订单任务测试自已完成测试步骤和上述一致。可适当修改cron表达式改变任务执行频率方便测试。 3. WebSocket 3.1 介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手两者之间就可以创建持久性的连接 并进行双向数据传输。 HTTP协议和WebSocket协议对比 HTTP是短连接WebSocket是长连接HTTP通信是单向的基于请求响应模式WebSocket支持双向通信HTTP和WebSocket底层都是TCP连接 思考既然WebSocket支持双向通信功能看似比HTTP强大那么我们是不是可以基于WebSocket开发所有的业务功能 WebSocket缺点 服务器长期维护长连接需要一定的成本 各个浏览器支持程度不一 WebSocket 是长连接受网络限制比较大需要处理好重连 结论WebSocket并不能完全取代HTTP它只适合在特定的场景下使用 WebSocket应用场景 1). 视频弹幕 2). 网页聊天 3). 体育实况更新 4). 股票基金报价实时更新 3.2 入门案例 3.2.1 案例分析 需求实现浏览器与服务器全双工通信。浏览器既可以向服务器发送消息服务器也可主动向浏览器推送消息。 效果展示 实现步骤 1). 直接使用websocket.html页面作为WebSocket客户端 2). 导入WebSocket的maven坐标 3). 导入WebSocket服务端组件WebSocketServer用于和客户端通信 4). 导入配置类WebSocketConfiguration注册WebSocket的服务端组件 5). 导入定时任务类WebSocketTask定时向客户端推送数据 3.2.2 代码开发 1). 定义websocket.html页面(资料中已提供) !DOCTYPE HTML html headmeta charsetUTF-8titleWebSocket Demo/title /head bodyinput idtext typetext /button onclicksend()发送消息/buttonbutton onclickcloseWebSocket()关闭连接/buttondiv idmessage/div /body script typetext/javascriptvar websocket null;var clientId Math.random().toString(36).substr(2);//判断当前浏览器是否支持WebSocketif(WebSocket in window){//连接WebSocket节点websocket new WebSocket(ws://localhost:8080/ws/clientId);}else{alert(Not support websocket)}//连接发生错误的回调方法websocket.onerror function(){setMessageInnerHTML(error);};//连接成功建立的回调方法websocket.onopen function(){setMessageInnerHTML(连接成功);}//接收到消息的回调方法websocket.onmessage function(event){setMessageInnerHTML(event.data);}//连接关闭的回调方法websocket.onclose function(){setMessageInnerHTML(close);}//监听窗口关闭事件当窗口关闭时主动去关闭websocket连接防止连接还没断开就关闭窗口server端会抛异常。window.onbeforeunload function(){websocket.close();}//将消息显示在网页上function setMessageInnerHTML(innerHTML){document.getElementById(message).innerHTML innerHTML br/;}//发送消息function send(){var message document.getElementById(text).value;websocket.send(message);}//关闭连接function closeWebSocket() {websocket.close();} /script /html 2). 导入maven坐标 在sky-server模块pom.xml中已定义 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-websocket/artifactId /dependency 3). 定义WebSocket服务端组件(资料中已提供) 直接导入到sky-server模块即可 package com.sky.websocket;import java.util.HashMap; import java.util.Map;/*** WebSocket服务*/ Component ServerEndpoint(/ws/{sid}) public class WebSocketServer {//存放会话对象private static MapString, Session sessionMap new HashMap();/*** 连接建立成功调用的方法*/OnOpenpublic void onOpen(Session session, PathParam(sid) String sid) {System.out.println(客户端 sid 建立连接);sessionMap.put(sid, session);}/*** 收到客户端消息后调用的方法** param message 客户端发送过来的消息*/OnMessagepublic void onMessage(String message, PathParam(sid) String sid) {System.out.println(收到来自客户端 sid 的信息: message);}/*** 连接关闭调用的方法** param sid*/OnClosepublic void onClose(PathParam(sid) String sid) {System.out.println(连接断开: sid);sessionMap.remove(sid);}/*** 群发** param message*/public void sendToAllClient(String message) {CollectionSession sessions sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}} } 4). 定义配置类注册WebSocket的服务端组件(从资料中直接导入即可) package com.sky.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** WebSocket配置类用于注册WebSocket的Bean*/ Configuration public class WebSocketConfiguration {Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();} } 5). 定义定时任务类定时向客户端推送数据(从资料中直接导入即可) package com.sky.task;import java.time.LocalDateTime; import java.time.format.DateTimeFormatter;Component public class WebSocketTask {Autowiredprivate WebSocketServer webSocketServer;/*** 通过WebSocket每隔5秒向客户端发送消息*/Scheduled(cron 0/5 * * * * ?)public void sendMessageToClient() {webSocketServer.sendToAllClient(这是来自服务端的消息 DateTimeFormatter.ofPattern(HH:mm:ss).format(LocalDateTime.now()));} } 3.2.3 功能测试 启动服务打开websocket.html页面 浏览器向服务器发送数据 服务器向浏览器间隔5秒推送数据 4. 来单提醒 4.1 需求分析和设计 用户下单并且支付成功后需要第一时间通知外卖商家。通知的形式有如下两种 语音播报 弹出提示框 设计思路 通过WebSocket实现管理端页面和服务端保持长连接状态当客户支付后调用WebSocket的相关API实现服务端向客户端推送消息客户端浏览器解析服务端推送的消息判断是来单提醒还是客户催单进行相应的消息提示和语音播报约定服务端发送给客户端浏览器的数据格式为JSON字段包括typeorderIdcontent type 为消息类型1为来单提醒 2为客户催单orderId 为订单idcontent 为消息内容 这里的socket链接配置了反向代理P133的视频 4.2 代码开发 在OrderServiceImpl中注入WebSocketServer对象修改paySuccess方法加入如下代码 Autowiredprivate WebSocketServer webSocketServer;/*** 支付成功修改订单状态** param outTradeNo*/public void paySuccess(String outTradeNo) {// 当前登录用户idLong userId BaseContext.getCurrentId();// 根据订单号查询当前用户的订单Orders ordersDB orderMapper.getByNumberAndUserId(outTradeNo, userId);// 根据订单id更新订单的状态、支付方式、支付状态、结账时间Orders orders Orders.builder().id(ordersDB.getId()).status(Orders.TO_BE_CONFIRMED).payStatus(Orders.PAID).checkoutTime(LocalDateTime.now()).build();orderMapper.update(orders);//Map map new HashMap();map.put(type, 1);//消息类型1表示来单提醒map.put(orderId, orders.getId());map.put(content, 订单号 outTradeNo);//通过WebSocket实现来单提醒向客户端浏览器推送消息webSocketServer.sendToAllClient(JSON.toJSONString(map));///} 4.3 功能测试 可以通过如下方式进行测试 查看浏览器调试工具数据交互过程前后端联调 1). 登录管理端后台 登录成功后浏览器与服务器建立长连接 查看控制台日志 2). 小程序端下单支付 修改回调地址利用内网穿透获取域名 下单支付 3). 查看来单提醒 支付成功后后台收到来单提醒并有语音播报 4.4 代码提交 后续步骤和其它功能代码提交一致不再赘述。 5. 客户催单 5.1 需求分析和设计 用户在小程序中点击催单按钮后需要第一时间通知外卖商家。通知的形式有如下两种 语音播报 弹出提示框 设计思路 通过WebSocket实现管理端页面和服务端保持长连接状态当用户点击催单按钮后调用WebSocket的相关API实现服务端向客户端推送消息客户端浏览器解析服务端推送的消息判断是来单提醒还是客户催单进行相应的消息提示和语音播报 约定服务端发送给客户端浏览器的数据格式为JSON字段包括typeorderIdcontent type 为消息类型1为来单提醒 2为客户催单orderId 为订单idcontent 为消息内容 当用户点击催单按钮时向服务端发送请求。 接口设计(催单) 5.2 代码开发 5.2.1 Controller层 根据用户催单的接口定义在user/OrderController中创建催单方法 /*** 用户催单** param id* return*/GetMapping(/reminder/{id})ApiOperation(用户催单)public Result reminder(PathVariable(id) Long id) {orderService.reminder(id);return Result.success();} 5.2.2 Service层接口 在OrderService接口中声明reminder方法 /*** 用户催单* param id*/void reminder(Long id); 5.2.3 Service层实现类 在OrderServiceImpl中实现reminder方法 /*** 用户催单** param id*/public void reminder(Long id) {// 查询订单是否存在Orders orders orderMapper.getById(id);if (orders null) {throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);}//基于WebSocket实现催单Map map new HashMap();map.put(type, 2);//2代表用户催单map.put(orderId, id);map.put(content, 订单号 orders.getNumber());webSocketServer.sendToAllClient(JSON.toJSONString(map));} 5.2.4 Mapper层 在OrderMapper中添加getById /*** 根据id查询订单* param id*/Select(select * from orders where id#{id})Orders getById(Long id); 5.3 功能测试 可以通过如下方式进行测试 查看浏览器调试工具数据交互过程前后端联调 1). 登录管理端后台 登录成功后浏览器与服务器建立长连接 查看控制台日志 2). 用户进行催单 用户可在订单列表或者订单详情进行催单 3). 查看催单提醒 既有催单弹窗同时语音播报 5.4 代码提交 后续步骤和其它功能代码提交一致不再赘述。 苍穹外卖-day11 课程内容 Apache ECharts营业额统计用户统计订单统计销量排名Top10 功能实现数据统计 数据统计效果图 1. Apache ECharts 1.1 介绍 Apache ECharts 是一款基于 Javascript 的数据可视化图表库提供直观生动可交互可个性化定制的数据可视化图表。 官网地址Apache ECharts 常见效果展示 1). 柱形图 2). 饼形图 3). 折线图 总结不管是哪种形式的图形最本质的东西实际上是数据它其实是对数据的一种可视化展示。 1.2 入门案例 Apache Echarts官方提供的快速入门快速上手 - Handbook - Apache ECharts 效果展示 实现步骤 1). 引入echarts.js 文件(当天资料已提供) 2). 为 ECharts 准备一个设置宽高的 DOM 3). 初始化echarts实例 4). 指定图表的配置项和数据 5). 使用指定的配置项和数据显示图表 代码开发 !DOCTYPE html htmlheadmeta charsetutf-8 /titleECharts/title!-- 引入刚刚下载的 ECharts 文件 --script srcecharts.js/script/headbody!-- 为 ECharts 准备一个定义了宽高的 DOM --div idmain stylewidth: 600px;height:400px;/divscript typetext/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重点在于研究当前图表所需的数据格式。通常是需要后端提供符合格式要求的动态数据然后响应给前端来展示图表。 2. 营业额统计 2.1 需求分析和设计 2.1.1 产品原型 营业额统计是基于折现图来展现并且按照天来展示的。实际上就是某一个时间范围之内的每一天的营业额。同时不管光标放在哪个点上那么它就会把具体的数值展示出来。并且还需要注意日期并不是固定写死的是由上边时间选择器来决定。比如选择是近7天、或者是近30日或者是本周就会把相应这个时间段之内的每一天日期通过横坐标展示。 原型图 业务规则 营业额指订单状态为已完成的订单金额合计基于可视化报表的折线图展示营业额数据X轴为日期Y轴为营业额根据时间选择区间展示每天的营业额数据 2.1.2 接口设计 通过上述原型图设计出对应的接口。 注意具体返回数据一般由前端来决定前端展示图表具体折现图对应数据是什么格式是有固定的要求的。 所以说后端需要去适应前端它需要什么格式的数据我们就给它返回什么格式的数据。 2.2 代码开发 2.2.1 VO设计 根据接口定义设计对应的VO 在sky-pojo模块TurnoverReportVO.java已定义 package com.sky.vo;import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor;import java.io.Serializable;Data Builder NoArgsConstructor AllArgsConstructor public class TurnoverReportVO implements Serializable {//日期以逗号分隔例如2022-10-01,2022-10-02,2022-10-03private String dateList;//营业额以逗号分隔例如406.0,1520.0,75.0private String turnoverList;} 2.2.2 Controller层 根据接口定义创建ReportController package com.sky.controller.admin;import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate;/*** 报表*/ RestController RequestMapping(/admin/report) Slf4j Api(tags 统计报表相关接口) public class ReportController {Autowiredprivate ReportService reportService;/*** 营业额数据统计** param begin* param end* return*/GetMapping(/turnoverStatistics)ApiOperation(营业额数据统计)public ResultTurnoverReportVO turnoverStatistics(DateTimeFormat(pattern yyyy-MM-dd)LocalDate begin,DateTimeFormat(pattern yyyy-MM-dd)LocalDate end) {return Result.success(reportService.getTurnover(begin, end));}} 2.2.3 Service层接口 创建ReportService接口声明getTurnover方法 package com.sky.service;import com.sky.vo.TurnoverReportVO; import java.time.LocalDate;public interface ReportService {/*** 根据时间区间统计营业额* param beginTime* param endTime* return*/TurnoverReportVO getTurnover(LocalDate beginTime, LocalDate endTime); } 2.2.4 Service层实现类 创建ReportServiceImpl实现类实现getTurnover方法: package com.sky.service.impl;import java.util.List; import java.util.Map;Service Slf4j public class ReportServiceImpl implements ReportService {Autowiredprivate OrderMapper orderMapper;/*** 根据时间区间统计营业额* param begin* param end* return*/public TurnoverReportVO getTurnover(LocalDate begin, LocalDate end) {ListLocalDate dateList new ArrayList();dateList.add(begin);while (!begin.equals(end)){begin begin.plusDays(1);//日期计算获得指定日期后1天的日期dateList.add(begin);}ListDouble turnoverList new ArrayList();for (LocalDate date : dateList) {LocalDateTime beginTime LocalDateTime.of(date, LocalTime.MIN);//0:0LocalDateTime endTime LocalDateTime.of(date, LocalTime.MAX);//23:59999999999Map map new HashMap();map.put(status, Orders.COMPLETED);map.put(begin,beginTime);map.put(end, endTime);Double turnover orderMapper.sumByMap(map); turnover turnover null ? 0.0 : turnover;//为空就返回0.0turnoverList.add(turnover);}//数据封装return TurnoverReportVO.builder().dateList(StringUtils.join(dateList,,)).turnoverList(StringUtils.join(turnoverList,,)).build();} } 2.2.5 Mapper层 在OrderMapper接口声明sumByMap方法 /*** 根据动态条件统计营业额* param map*/Double sumByMap(Map map); 在OrderMapper.xml文件中编写动态SQL select idsumByMap resultTypejava.lang.Doubleselect sum(amount) from orderswhereif teststatus ! nulland status #{status}/ifif testbegin ! nulland order_time #{begin}/ifif testend ! nulland order_time #{end}/if/where /select 2.3 功能测试 可以通过如下方式进行测试 接口文档测试前后端联调测试 启动服务器启动nginx直接采用前后端联调测试。 进入数据统计模块 1). 查看近7日营业额统计 进入开发者模式查看返回数据 2). 查看近30日营业额统计 进入开发者模式查看返回数据 也可通过断点方式启动查看每步执行情况。 2.4 代码提交 后续步骤和其它功能代码提交一致不再赘述。 3. 用户统计 3.1 需求分析和设计 3.1.1 产品原型 所谓用户统计实际上统计的是用户的数量。通过折线图来展示上面这根蓝色线代表的是用户总量下边这根绿色线代表的是新增用户数量是具体到每一天。所以说用户统计主要统计两个数据一个是总的用户数量另外一个是新增用户数量。 原型图 业务规则 基于可视化报表的折线图展示用户数据X轴为日期Y轴为用户数根据时间选择区间展示每天的用户总量和新增用户量数据 3.1.2 接口设计 根据上述原型图设计接口。 3.2 代码开发 3.2.1 VO设计 根据用户统计接口的返回结果设计VO 在sky-pojo模块UserReportVO.java已定义 package com.sky.vo;import lombok.NoArgsConstructor; import java.io.Serializable;Data Builder NoArgsConstructor AllArgsConstructor public class UserReportVO implements Serializable {//日期以逗号分隔例如2022-10-01,2022-10-02,2022-10-03private String dateList;//用户总量以逗号分隔例如200,210,220private String totalUserList;//新增用户以逗号分隔例如20,21,10private String newUserList;} 3.2.2 Controller层 根据接口定义在ReportController中创建userStatistics方法 /*** 用户数据统计* param begin* param end* return*/GetMapping(/userStatistics)ApiOperation(用户数据统计)public ResultUserReportVO userStatistics(DateTimeFormat(pattern yyyy-MM-dd) LocalDate begin,DateTimeFormat(pattern yyyy-MM-dd) LocalDate end){return Result.success(reportService.getUserStatistics(begin,end)); } 3.2.3 Service层接口 在ReportService接口中声明getUserStatistics方法 /*** 根据时间区间统计用户数量* param begin* param end* return*/UserReportVO getUserStatistics(LocalDate begin, LocalDate end); 3.2.4 Service层实现类 在ReportServiceImpl实现类中实现getUserStatistics方法 Overridepublic UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {ListLocalDate dateList new ArrayList();dateList.add(begin);while (!begin.equals(end)){begin begin.plusDays(1);dateList.add(begin);}ListInteger newUserList new ArrayList(); //新增用户数ListInteger totalUserList new ArrayList(); //总用户数for (LocalDate date : dateList) {LocalDateTime beginTime LocalDateTime.of(date, LocalTime.MIN);LocalDateTime endTime LocalDateTime.of(date, LocalTime.MAX);//新增用户数量 select count(id) from user where create_time ? and create_time ?Integer newUser getUserCount(beginTime, endTime);//总用户数量 select count(id) from user where create_time ?Integer totalUser getUserCount(null, endTime);newUserList.add(newUser);totalUserList.add(totalUser);}return UserReportVO.builder().dateList(StringUtils.join(dateList,,)).newUserList(StringUtils.join(newUserList,,)).totalUserList(StringUtils.join(totalUserList,,)).build();} 在ReportServiceImpl实现类中创建私有方法getUserCount /*** 根据时间区间统计用户数量* param beginTime* param endTime* return*/private Integer getUserCount(LocalDateTime beginTime, LocalDateTime endTime) {Map map new HashMap();map.put(begin,beginTime);map.put(end, endTime);return userMapper.countByMap(map);} 3.2.5 Mapper层 在UserMapper接口中声明countByMap方法 /*** 根据动态条件统计用户数量* param map* return*/Integer countByMap(Map map); 在UserMapper.xml文件中编写动态SQL select idcountByMap resultTypejava.lang.Integerselect count(id) from userwhereif testbegin ! nulland create_time #{begin}/ifif testend ! nulland create_time #{end}/if/where /select 3.3 功能测试 可以通过如下方式进行测试 接口文档测试前后端联调测试 进入数据统计模块 1). 查看近7日用户统计 进入开发者模式查看返回数据 2). 查看近30日用户统计 进入开发者模式查看返回数据 也可通过断点方式启动查看每步执行情况。 3.4 代码提交 后续步骤和其它功能代码提交一致不再赘述。 4. 订单统计 4.1 需求分析和设计 4.1.1 产品原型 订单统计通过一个折现图来展现折线图上有两根线这根蓝色的线代表的是订单总数而下边这根绿色的线代表的是有效订单数指的就是状态是已完成的订单就属于有效订单分别反映的是每一天的数据。上面还有3个数字分别是订单总数、有效订单、订单完成率它指的是整个时间区间之内总的数据。 原型图 业务规则 有效订单指状态为 “已完成” 的订单基于可视化报表的折线图展示订单数据X轴为日期Y轴为订单数量根据时间选择区间展示每天的订单总数和有效订单数展示所选时间区间内的有效订单数、总订单数、订单完成率订单完成率 有效订单数 / 总订单数 * 100% 4.1.2 接口设计 根据上述原型图设计接口。 4.2 代码开发 4.2.1 VO设计 根据订单统计接口的返回结果设计VO 在sky-pojo模块OrderReportVO.java已定义 package com.sky.vo;import lombok.NoArgsConstructor; import java.io.Serializable;Data Builder NoArgsConstructor AllArgsConstructor public class OrderReportVO implements Serializable {//日期以逗号分隔例如2022-10-01,2022-10-02,2022-10-03private String dateList;//每日订单数以逗号分隔例如260,210,215private String orderCountList;//每日有效订单数以逗号分隔例如20,21,10private String validOrderCountList;//订单总数private Integer totalOrderCount;//有效订单数private Integer validOrderCount;//订单完成率private Double orderCompletionRate; } 4.2.2 Controller层 在ReportController中根据订单统计接口创建orderStatistics方法 /*** 订单数据统计* param begin* param end* return*/GetMapping(/ordersStatistics)ApiOperation(用户数据统计)public ResultOrderReportVO orderStatistics(DateTimeFormat(pattern yyyy-MM-dd)LocalDate begin,DateTimeFormat(pattern yyyy-MM-dd)LocalDate end){return Result.success(reportService.getOrderStatistics(begin,end));} 4.2.3 Service层接口 在ReportService接口中声明getOrderStatistics方法 /** * 根据时间区间统计订单数量 * param begin * param end * return */ OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end); 4.2.4 Service层实现类 在ReportServiceImpl实现类中实现getOrderStatistics方法 /** * 根据时间区间统计订单数量 * param begin * param end * return */ public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end){ListLocalDate dateList new ArrayList();dateList.add(begin);while (!begin.equals(end)){begin begin.plusDays(1);dateList.add(begin);}//每天订单总数集合ListInteger orderCountList new ArrayList();//每天有效订单数集合ListInteger validOrderCountList new ArrayList();for (LocalDate date : dateList) {LocalDateTime beginTime LocalDateTime.of(date, LocalTime.MIN);LocalDateTime endTime LocalDateTime.of(date, LocalTime.MAX);//查询每天的总订单数 select count(id) from orders where order_time ? and order_time ?Integer orderCount getOrderCount(beginTime, endTime, null);//查询每天的有效订单数 select count(id) from orders where order_time ? and order_time ? and status ?Integer 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();} 在ReportServiceImpl实现类中提供私有方法getOrderCount /** * 根据时间区间统计指定状态的订单数量 * param beginTime * param endTime * param status * return */ private Integer getOrderCount(LocalDateTime beginTime, LocalDateTime endTime, Integer status) {Map map new HashMap();map.put(status, status);map.put(begin,beginTime);map.put(end, endTime);return orderMapper.countByMap(map); } 4.2.5 Mapper层 在OrderMapper接口中声明countByMap方法 /** *根据动态条件统计订单数量 * param map */ Integer countByMap(Map map); 在OrderMapper.xml文件中编写动态SQL select idcountByMap resultTypejava.lang.Integerselect count(id) from orderswhereif teststatus ! nulland status #{status}/ifif testbegin ! nulland order_time #{begin}/ifif testend ! nulland order_time #{end}/if/where /select 4.3 功能测试 可以通过如下方式进行测试 接口文档测试前后端联调 重启服务直接采用前后端联调测试。 进入数据统计模块 1). 查看近7日订单统计 进入开发者模式查看返回数据 2). 查看近30日订单统计 进入开发者模式查看返回数据 也可通过断点方式启动查看每步执行情况。 4.4 代码提交 后续步骤和其它功能代码提交一致不再赘述。 5. 销量排名Top10 5.1 需求分析和设计 5.1.1 产品原型 所谓销量排名销量指的是商品销售的数量。项目当中的商品主要包含两类一个是套餐一个是菜品所以销量排名其实指的就是菜品和套餐销售的数量排名。通过柱形图来展示销量排名这些销量是按照降序来排列并且只需要统计销量排名前十的商品。 原型图 业务规则 根据时间选择区间展示销量前10的商品包括菜品和套餐基于可视化报表的柱状图降序展示商品销量此处的销量为商品销售的份数 5.1.2 接口设计 根据上述原型图设计接口。 5.2 代码开发 5.2.1 VO设计 根据销量排名接口的返回结果设计VO 在sky-pojo模块SalesTop10ReportVO.java已定义 package com.sky.vo;import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable;Data Builder NoArgsConstructor AllArgsConstructor public class SalesTop10ReportVO implements Serializable {//商品名称列表以逗号分隔例如鱼香肉丝,宫保鸡丁,水煮鱼private String nameList;//销量列表以逗号分隔例如260,215,200private String numberList; } 5.2.2 Controller层 在ReportController中根据销量排名接口创建top10方法 /** * 销量排名统计 * param begin * param end * return */ GetMapping(/top10) ApiOperation(销量排名统计) public ResultSalesTop10ReportVO top10(DateTimeFormat(pattern yyyy-MM-dd) LocalDate begin,DateTimeFormat(pattern yyyy-MM-dd) LocalDate end){return Result.success(reportService.getSalesTop10(begin,end)); } 5.2.3 Service层接口 在ReportService接口中声明getSalesTop10方法 /** * 查询指定时间区间内的销量排名top10 * param begin * param end * return */ SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end); 5.2.4 Service层实现类 在ReportServiceImpl实现类中实现getSalesTop10方法 /*** 查询指定时间区间内的销量排名top10* 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);ListGoodsSalesDTO goodsSalesDTOList orderMapper.getSalesTop10(beginTime, endTime);String nameList StringUtils.join(goodsSalesDTOList.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList()),,);String numberList StringUtils.join(goodsSalesDTOList.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList()),,);return SalesTop10ReportVO.builder().nameList(nameList).numberList(numberList).build();} 5.2.5 Mapper层 在OrderMapper接口中声明getSalesTop10方法 /** * 查询商品销量排名 * param begin * param end */ ListGoodsSalesDTO getSalesTop10(LocalDateTime begin, LocalDateTime end); 在OrderMapper.xml文件中编写动态SQL select idgetSalesTop10 resultTypecom.sky.dto.GoodsSalesDTOselect od.name name,sum(od.number) number from order_detail od ,orders owhere od.order_id o.idand o.status 5if testbegin ! nulland order_time #{begin}/ifif testend ! nulland order_time #{end}/ifgroup by nameorder by number desclimit 0, 10 /select 5.3 功能测试 可以通过如下方式进行测试 接口文档测试前后端联调 重启服务直接采用前后端联调测试。 查看近30日销量排名Top10统计 若查询的某一段时间没有销量数据则显示不出效果。 进入开发者模式查看返回数据 也可通过断点方式启动查看每步执行情况。 5.4 代码提交 后续步骤和其它功能代码提交一致不再赘述。
http://wiki.neutronadmin.com/news/3344/

相关文章:

  • 响应式网站建设外文文献哪些网站是做设计的
  • 招聘网站建设方案模板下载河北建设工程交易信息网
  • 素材网站php程序源码做网站接广告赚钱吗
  • 网站改版建设原则京津冀协同发展规划纲要全文
  • 沙田网站仿做改图宝在线制作印章
  • 成都 网站建设 app 开发建设对公银行网站打不开
  • 网站建设报价表区块链开发平台
  • 潍坊网站建设工作国家信用信息公示系统湖北
  • 网站 网页数量怎么下载app到手机上
  • 城市介绍网站模板无代码开发原理
  • 用户后台网站微信小程序传奇怎么制作
  • 广州网站定制开发公司哪家好上海自贸区注册公司优惠政策
  • 一 网站建设管理基本情况seo数据监控平台
  • 17做网站广州建立的英文found
  • 百度搜索不到我的网站网站 体系
  • 网站开发遵循电商网站开发公司哪家好
  • 外贸自建站费用网站优化需要那些工具
  • 网站访客qq系统租网站服务器价格
  • 打码网站怎么做电商网站商品排序分类怎么做
  • wordpress建站中英文seo排名外包
  • 界面设计最好的网站目前中国建筑行业现状
  • 怎么查看网站有没有备案怎样在领英上做公司网站
  • 济南 网站推广中国最大的库存尾货清货平台
  • 整站优化加盟外墙设计装修效果图软件
  • 网站都有哪些类型长沙景点视频
  • 直播课网站怎样做的wordpress标签排序
  • 株洲网站推广优化深圳网站建设哪里
  • 广东网站建设科技怎么删除wordpress插件
  • 苍南做网站哪里找医院网站建设原理
  • 化妆品产品的自建网站哟哪些wordpress滑动图片