黑马苍穹外卖学习Day10

文章目录

Spring Task

介绍


cron表达式

入门案例



订单状态定时处理

需求分析

代码开发

新建一个task包里面编写代码。

java 复制代码
package com.sky.task;


/**
 *定时任务类
 */
@Component
@Slf4j
public class OrderTask {
    @Autowired
    private OrderMapper orderMapper;
    /**
     * 处理超时订单的方法
     */
    @Scheduled(cron = "0 * * * * ? ")//每分钟触发一次
    public void processTimeOutOrder(){
        log.info("定时处理超时订单:{}", LocalDateTime.now());
        //select * from orders where status = ? and order_time < (当前时间-15分钟)
        List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, LocalDateTime.now().plusMinutes(-15));
        if (ordersList != null && ordersList.size() > 0){
            for (Orders orders : ordersList){
                orders.setStatus(Orders.CANCELLED);
                orders.setCancelReason("订单超时自动取消");
                orders.setCancelTime(LocalDateTime.now());
                orderMapper.update(orders);
            }
        }
    }

    /**
     * 处理一直派送中的订单
     */
    @Scheduled(cron = "0 0 1 * * ?")//每天凌晨1点触发1次
    public void processDeliveryOrder(){
        log.info("定时处理处于派送中的订单:{}",LocalDateTime.now());
        List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS, LocalDateTime.now().plusHours(-1));
        if (ordersList != null && ordersList.size() > 0){
            for (Orders orders : ordersList){
                orders.setStatus(Orders.COMPLETED);
                orderMapper.update(orders);
            }
        }
    }
}

Mapper接口

java 复制代码
    /**
     * 查询处理超时订单
     * @return
     */
    @Select("select * from orders where status = #{status} and order_time < #{orderTime}")
    List<Orders> getByStatusAndOrderTimeLT(Integer status, LocalDateTime orderTime);

功能测试

WebSocket

介绍


入门案例

新建一个websocket包导入代码

java 复制代码
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 注解,表明它是一个 Spring 管理的组件。
 * @ServerEndpoint("/ws/{sid}") 注解表示这是一个 WebSocket 端点,路径为 /ws/{sid},其中 {sid} 是一个占位符。
 * 在 onOpen 方法中,当有新的 WebSocket 连接建立时,将该连接的 Session 存储在 sessionMap 中。
 * 在 onMessage 方法中,当收到客户端消息时,进行处理。
 * 在 onClose 方法中,当连接关闭时,从 sessionMap 中移除相应的 Session。
 * 提供了 sendToAllClient 方法,用于向所有连接的客户端广播消息。
 */
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {

    //存放会话对象
    private static Map<String, Session> sessionMap = new HashMap();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        System.out.println("客户端:" + sid + "建立连接");
        sessionMap.put(sid, session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        System.out.println("收到来自客户端:" + sid + "的信息:" + message);
    }

    /**
     * 连接关闭调用的方法
     *
     * @param sid
     */
    @OnClose
    public 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();
            }
        }
    }

}

导入配置类

java 复制代码
/**
 * WebSocket配置类,用于注册WebSocket的Bean
 */
@Configuration
public class WebSocketConfiguration {
    /**
     * WebSocket 配置类(WebSocketConfiguration):
     * 这个配置类使用了 @Configuration 注解,表明它是一个配置类,Spring 会在启动时加载并处理它。
     * 通过 @Bean 注解,它创建了一个 ServerEndpointExporter Bean,该 Bean 是 Spring WebSocket 标准的端点导出器。
     * ServerEndpointExporter 的作用是将使用 @ServerEndpoint 注解声明的 WebSocket 端点注册到 Spring 容器中。
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

关系分析:

WebSocketConfiguration 中的 ServerEndpointExporter Bean 的存在,使得 Spring 能够自动检测并注册 WebSocketServer 中使用 @ServerEndpoint 注解声明的 WebSocket 端点。

WebSocketServer 类中通过 @ServerEndpoint 注解声明了一个 WebSocket 端点,并提供了处理连接建立、消息接收、连接关闭等逻辑。

当有新的 WebSocket 连接建立时,WebSocketServer 中的 onOpen 方法会被调用,将该连接的 Session 存储在 sessionMap 中。

当需要向所有客户端广播消息时,WebSocketServer 中的 sendToAllClient 方法会遍历 sessionMap,向每个客户端发送消息。

因此,通过 WebSocketConfiguration 的配置,WebSocketServer 中的 WebSocket 端点得以自动注册,而且可以在整个应用程序中共享 WebSocketServer 的实例。

来单提醒

需求分析


代码开发

在OrderService实现类中的函数修改

java 复制代码
    /**
     * 支付成功,修改订单状态
     *
     * @param outTradeNo
     */
    public void paySuccess(String outTradeNo) {

        // 根据订单号查询订单
        Orders ordersDB = orderMapper.getByNumber(outTradeNo);

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();

        orderMapper.update(orders);

        //通过websocket向客户端浏览器推送消息 type orderId Content
        Map map = new HashMap();
        map.put("type",1);//1表示来单提醒 2表示客户催单
        map.put("orderId", ordersDB.getId());
        map.put("content", "订单号:"+outTradeNo);
        //转成json字符串
        String jsonString = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(jsonString);
    }

客户催单

需求分析

代码开发

Controller层`

java 复制代码
    /**
     *客户催单
     */
    @GetMapping("/reminder/{id}")
    @ApiOperation("客户催单")
    public Result reminder(@PathVariable Long id){
        orderService.reminder(id);
        return Result.success();
    }

Service实现类

java 复制代码
        /**
        * 客户催单
        * @param id
        */
        @Override
        public void reminder(Long id) {
        //根据id查询订单
        Orders orders = orderMapper.getByOrderId(id);
        //校验订单是否存在
        if (orders == null){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        Map map = new HashMap();
        map.put("type", 2); //1表示来电提醒 2表示客户催单
        map.put("orderId", id);
        map.put("content", "订单号:" + orders.getNumber());
        //通过websocket向客户端浏览器推送消息
        webSocketServer.sendToAllClient(JSONObject.toJSONString(map));
    }
相关推荐
MonkeyKing_sunyuhua几秒前
ubuntu22.04 docker-compose安装postgresql数据库
数据库·docker·postgresql
天郁青几秒前
数据库交互的本地项目:后台管理系统
数据库·交互
马剑威(威哥爱编程)6 分钟前
MongoDB面试专题33道解析
数据库·mongodb·面试
hong16168816 分钟前
跨模态对齐与跨领域学习
学习
程序媛小果27 分钟前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
小光学长31 分钟前
基于vue框架的的流浪宠物救助系统25128(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
数据库·vue.js·宠物
阿伟来咯~1 小时前
记录学习react的一些内容
javascript·学习·react.js
Suckerbin1 小时前
Hms?: 1渗透测试
学习·安全·网络安全
零炻大礼包1 小时前
【SQL server】数据库远程连接配置
数据库
水豚AI课代表1 小时前
分析报告、调研报告、工作方案等的提示词
大数据·人工智能·学习·chatgpt·aigc