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

文章目录

  • Spring Task
    • 介绍
    • cron表达式
    • 入门案例
  • 订单状态定时处理
    • 需求分析
    • 代码开发
    • 扩展
  • WebSocket
    • 介绍
    • 入门案例
    • 特点
  • 来单提醒
    • 需求分析和设计
    • 代码实现
  • 客户催单
    • 需求分析和设计
    • 代码实现

Spring Task

介绍

Spring Task 是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。
定位:定时任务框架
作用:定时自动执行某段Java代码
应用场景

  • 信用卡每月还款提醒
  • 银行贷款每月还款提醒
  • 火车票售票系统处理未支付订单
  • 入职纪念日为用户发送通知

只要是需要定时处理的场景都可以使用Spring Task

cron表达式

cron表达式其实就是一个字符串,通过cron表达式可以定义任务触发的时间
构造规则:分为6或7个域,由空格分隔开,每个域代表一个含义
每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)
image.png
说明:一般的值不同时设置,其中一个设置,另一个用?表示。
cron表达式在线生成器:https://cron.qqe2.com/
image.png

入门案例

Spring Task使用步骤:

  1. 导入maven坐标 spring-context
  2. 启动类添加注解**@EnableScheduling **开启任务调度
  3. 自定义定时任务类
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());}
}

订单状态定时处理

需求分析

用户下单后可能存在的情况:

  • 下单后未支付,订单一直处于**“待支付”**状态
  • 用户收货后管理端未点击完成按钮,订单一直处于**“派送中”**状态

问题
支付超市的订单如何处理?
派送中的订单一直不点击完成如何处理?
解决措施
对于上面两种情况需要通过定时任务来修改订单,具体逻辑为:

  • 通过定时任务每分钟检查一次是否存在支付超时订单(下单后超过15分钟仍未支付则判定为支付超市订单),如果存在则修改订单状态为”已取消“
  • 通过定时任务每天凌晨1点检查一次是否存在”派送中“的订单,如果存在则修改订单状态为”已完成“。

代码开发

  //目标:每分钟检查待付款状态订单数据,如果存在将其状态修改为已取消@Scheduled(cron = "0 0/1 * * * ?")public void processTimeoutOrder(){//1.计算当前时间-15分钟LocalDateTime checkTime = LocalDateTime.now().minusMinutes(15);//2.查询指定时间内待付款的订单状态列表List<Orders> ordersList = orderMapper.getByStatusAndOrderTime(Orders.PENDING_PAYMENT,checkTime);//3.判断列表数据是否为空if (ordersList != null && ordersList.size() > 0){//3.1 不为空,更新每个订单状态为已取消List<Long> ids = ordersList.stream().map(Orders::getId).collect(Collectors.toList());orderMapper.updateStatusBatch(ids,Orders.CANCELLED);log.info("成功处理了{}笔超时未支付订单数据!",ids.size());}else {//3.2 为空,说明不存在超时未支付订单,打印说明log.info("不存在超市未支付订单数据!");}}
  List<Orders> getByStatusAndOrderTime(@Param("status") Integer status, @Param("orderTime") LocalDateTime orderTime);void updateStatusBatch(@Param("ids") List<Long> ids, @Param("cancelled") Integer cancelled);
 <update id="updateStatusBatch">update orders<set><if test="status != null">status = #{status}</if></set>where id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach></update><select id="getByStatusAndOrderTime" resultType="com.sky.entity.Orders">select * from orders<where><if test="orderTime != null">order_time &lt;= ${orderTime}</if><if test="status != null">status = #{status}</if></where></select>

扩展

问题:定时任务框架是如何执行java代码的?
底层原理:jdk提供的定时任务工具类Timer和TimeTask,利用线程池使用线程来运行每个任务。
注意:不要乱用定时任务,否则会导致线程池资源耗尽,性能会慢

WebSocket

介绍

WebSocket 是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成二次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。
image.png
应用场景

  • 视频弹幕
  • 网页聊天
  • 体育实况更新
  • 股票基金报价实时更新

image.png
image.png

入门案例

实现步骤
①直接使用websocket.html页面作为WebSocket客户端
②导入WebSocket的maven坐标
③导入WebSocket服务端组件WebSocketServer,用于和客户端通信
④导入配置类WebSocketConfiguration,注册WebSocket的服务端组件
⑤导入定时任务类WebSocketTask,定时向客户端推送数据
代码开发
定义websocket.html页面

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><title>WebSocket Demo</title>
</head>
<body><input id="text" type="text" /><button onclick="send()">发送消息</button><button onclick="closeWebSocket()">关闭连接</button><div id="message"></div>
</body>
<script type="text/javascript">var 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>

导入maven坐标

<dependency>    <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

定义WebSocket服务端组件

package com.sky.websocket;import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;/*** WebSocket服务*/
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {//存放会话对象private static Map<String, 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) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}}

定义配置类,注册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();}}

定义定时任务类,定时向客户端推送数据

package com.sky.task;import com.sky.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
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()));}
}

特点

WebSocket缺点
• 服务器长期维护长连接需要一定的成本
• 各个浏览器支持程度不一
• WebSocket 是长连接,受网络限制比较大,需要处理好重连
结论:WebSocket并不能完全取代HTTP,它只适合在特定的场景下使用

来单提醒

需求分析和设计

image.png
image.png

代码实现

 /*** 来单提醒接口* @param id*/@ApiOperation("来单提醒接口")@GetMapping("/orderService")public void orderAdvice(Long id){log.info("来单提醒接口");//1.根据id查询订单数据Orders orders = orderService.findById(id);//2.封装数据返回Map<String,Object> map = new HashMap<>();map.put("type",1);map.put("orderId",id);map.put("content","订单号:" + orders.getNumber());//3.利用websocket发送数据webSocketServer.sendToAllClient(JSON.toJSONString(map));}

image.png

客户催单

需求分析和设计

image.png
image.png
image.png

代码实现

/*** 催单接口* @param id* @return*/@ApiOperation("催单接口")@GetMapping("/reminder/{id}")public Result reminder(@PathVariable Long id){log.info("催单接口:{}",id);//根据id查询订单数据Orders orders = orderService.findById(id);//操作催单,发送数据给商家端JSONObject jsonObject = new JSONObject();jsonObject.put("type",2);jsonObject.put("orderId",id);jsonObject.put("context","订单id:" + orders.getNumber());webSocketServer.sendToAllClient(jsonObject.toJSONString());//返回数据return Result.success();}

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

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

相关文章

Dify 零代码 AI 应用开发:快速入门与实战

一、Dify 介绍 Dify 是一个开源的大语言模型 (LLM) 应用开发平台。它结合了后端即服务 (Backend-as-a-Service) 和 LLMOps (LLMOps) 的概念&#xff0c;使开发人员能够快速构建生产级生成式 AI (Generative AI) 应用。即使是非技术人员也可以参与 AI 应用的定义和数据操作。 …

鸿蒙UI系统组件10——菜单(Menu)

果你也对鸿蒙开发感兴趣&#xff0c;加入“Harmony自习室”吧&#xff01;扫描下面名片&#xff0c;关注公众号。 Menu是菜单接口&#xff0c;一般用于鼠标右键弹窗、点击弹窗等。 1、创建默认样式的菜单 菜单需要调用bindMenu接口来实现。bindMenu响应绑定组件的点击事件&am…

【MATLAB APP】建立独立桌面APP

背景&#xff1a;已有MATLAB APP的.mlapp文件&#xff0c;但客户提出需要可以直接使用的exe文件。 要求&#xff1a;点开即用&#xff0c;无需下载MATLAB。使用者无法修改APP的代码。 一、环境配置 APP创建者&#xff1a;安装MATLAB R2023a&#xff0c;配置Application Compile…

【SpringBoot】5 Swagger

官网 https://swagger.io/ 介绍 Swagger 是一套基于 OpenAPI 规范构建的开源工具&#xff0c;可以帮助开发者实现设计、构建、记录、使用 Rest API。 Swagger 是一款根据 Restful 风格生成的接口开发文档&#xff0c;并且支持做测试的一款中间软件。 Swagger主要包括三部分&…

AI绘画;Stable Diffusion再升级:学会以图生图!

前言 Stability AI 很高兴地宣布推出 Stable Diffusion Reimagine&#xff01;我们邀请用户通过 Stable Diffusion 尝试图像并“重新构想”他们的设计。 Stable Diffusion Reimagine 是一种新的 Clipdrop 工具&#xff0c;它允许用户无限制地生成单个图像的多个变体。无需复杂…

科研绘图系列:R语言山脊图(Ridgeline Chart)

介绍 山脊图(Ridge Chart)是一种用于展示数据分布和比较不同类别或组之间差异的数据可视化技术。它通常用于展示多个维度或变量之间的关系,以及它们在不同组中的分布情况。山脊图的特点: 多变量展示:山脊图可以同时展示多个变量的分布情况,允许用户比较不同变量之间的关…

【Java基础语法】字符修改,以及equals的用法

前言&#xff1a; 小编这里将上一期String类型进行了补充&#xff0c;添加了字符串的修改&#xff0c;以及equals的用法内容&#xff0c;和hashcode的使用&#xff1b;上一期&#xff1a;http://t.csdnimg.cn/ijiM6 1.字符串的修改 在上一期中我们说到字符串是不能被修改的&am…

计算机视觉项目-2024年第3号超强台风“格美”登陆福建带来大暴雨造成城市积水,通过模型识别路段积水避开积水道路

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉项目-2024年第3号超强台风“格美”登陆福建带来大暴雨造成城市积水&#xff0c;通过模型识别路段积水避开积水道路。今年第3号台风“格美”(强台风级)的中心今天(24日)早晨5点钟位于我国台湾省宜兰县东南…

多表查询的内连接与外连接

目录 1. 内连接 1.1 概述 1.2 等值连接 1.3 非等值连接 1.4 自连接 2. 外连接 2.1 概述 2.2 左/右连接 2.3 全连接 3. 多张表连接 1. 内连接 1.1 概述 查询满足条件的两张表数据&#xff0c;也就是两张表的交集&#xff1b; 内连接使用过程中&#xff0c;尽量对表重…

linux系统安装pytorch_中文地址命名实体识别案例

命名实体有关文章参考这篇文章 中文地址命名实体识别训练和预测 win10系统安装cuda环境参考这篇文章 搭建Pytorch的GPU环境超详细 1、下载python https://www.python.org/downloads/release/python-368/ 2、下载python包 https://pypi.org/search/?q=transformers 1、搜…

董宇辉离职,我一点都不意外!只不过感觉来的太快

下面这张图&#xff0c;是我在半年多前写的一段随笔&#xff0c;没想到来的这么快&#xff01; 碰巧的是今天中午&#xff0c;在开发者群里有两位老铁自曝&#xff0c;本以为能公司干到老&#xff0c;但公司却不给机会&#xff0c;已经不在是公司员工了。 最近&#xff0c;晓衡…

C++——QT:保姆级教程,从下载到安装到用QT写出第一个程序

登录官网&#xff0c;在官网选择合适的qt版本进行下载 这里选择5.12.9版本 点击exe文件下载&#xff0c;因为服务器在国外&#xff0c;国内不支持&#xff0c;所以可以从我的网盘下载 链接: https://pan.baidu.com/s/1XMILFS1uHTenH3mH_VlPLw 提取码: 1567 --来自百度网盘超级…

我澄清下,大数据界面虽然有点花,但对趋势的判断还是很准的!

我澄清下&#xff0c;大数据界面虽然有点花&#xff0c;但对趋势的判断还是很准的&#xff01; 艾斯视觉的观点认为&#xff1a;在这个充满不确定性的世界里&#xff0c;大数据就像一位智者&#xff0c;透过那些令人眼花缭乱的界面&#xff0c;总能以它独到的洞察力&#xff0…

matlab笔记 - 最小二乘法拟合直线的原理与实现

最小二乘法拟合直线原理与实现 一、引言二、原理概述1. 建模思路2.误差函数3.求解最优参数 三、matlab实现最小二乘法拟合直线1.直接代码实现2.MATLAB内置函数实现 四、扩展统计学与回归分析经济学工程学图像处理机器学习 一、引言 最小二乘法&#xff08;Least Squares Metho…

遇到Websocket就不会测了?别慌,学会这个Jmeter插件轻松解决....

websocket 是一种双向通信协议&#xff0c;在建立连接后&#xff0c;websocket服务端和客户端都能主动向对方发送或者接收数据&#xff0c;而在http协议中&#xff0c;一个request只能有一个response&#xff0c;而且这个response也是被动的&#xff0c;不能主动发起。 websoc…

常见的jmeter面试题及答案

1、解释什么是JMeter? JMeter是一款Java开源工具&#xff0c; 用于性能负载测试。它旨在分析和衡量Web应用程序和各种服务的性能和负载功能行为。 2、说明JMeter的工作原理? JMeter就像一群将请求发送到目标服务器的用户-样。它收集来自目标服务器的响应以及其他统计数据&…

WARNING: Ignoring invalid distribution -ip警告信息如何去掉?

查看已安装依赖列表的时候&#xff0c;出现了很多警告信息&#xff0c;如何去掉呢&#xff1f; 解决办法 打开这个路径&#xff1a;d:\software\python\python39\lib\site-packages 这种波浪线开头的&#xff0c;我们将它删除掉,就可以了。

结构体,联合体,指针和浮点代码笔记

系列文章 : 深入理解计算机系统笔记 文章目录 系列文章3.9 异质的数据结构3.9.1 结构3.9.2 联合3.9.3 数据对齐 3.10 在机器级程序中将控制和数据结合起来3.10.1 理解指针3.10.2 应用&#xff1a;使用GDB调试器3.10.3 内存越界引用和缓冲区溢出3.10.4 对抗缓冲区溢出攻击3.10…

2.1、matlab绘图汇总(图例、标题、坐标轴、线条格式、颜色和散点格式设置)

1、前言 在 MATLAB 中进行绘图是一种非常常见且实用的操作&#xff0c;可以用来可视化数据、结果展示、分析趋势等。通过 MATLAB 的绘图功能&#xff0c;用户可以创建各种类型的图形&#xff0c;包括线图、散点图、柱状图、曲线图等&#xff0c;以及三维图形、动画等复杂的可视…

京东云ifrit-agent占用80端口问题

即使停止服务后还是会自动重启&#xff0c;网上查找无果后询问京东云客服&#xff0c;人家服务蛮好&#xff0c;回复很快 解决办法 centos7&#xff1a; 停止服务 systemctl stop ifritd 卸载 rm -rf /usr/local/share/jcloud/ifrit centos 6: 停止服务 cd /usr/local…