黑马苍穹外卖学习Day10

文章目录

  • Spring Task
    • 介绍
    • cron表达式
    • 入门案例
  • 订单状态定时处理
    • 需求分析
    • 代码开发
    • 功能测试
  • WebSocket
    • 介绍
    • 入门案例
  • 来单提醒
    • 需求分析
    • 代码开发
  • 客户催单
    • 需求分析
    • 代码开发

Spring Task

介绍

黑马苍穹外卖学习Day10_第1张图片
黑马苍穹外卖学习Day10_第2张图片

cron表达式

黑马苍穹外卖学习Day10_第3张图片

入门案例

黑马苍穹外卖学习Day10_第4张图片
黑马苍穹外卖学习Day10_第5张图片
在这里插入图片描述

订单状态定时处理

黑马苍穹外卖学习Day10_第6张图片

需求分析

黑马苍穹外卖学习Day10_第7张图片

代码开发

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

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

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

功能测试

黑马苍穹外卖学习Day10_第8张图片

WebSocket

介绍

黑马苍穹外卖学习Day10_第9张图片
黑马苍穹外卖学习Day10_第10张图片

入门案例

黑马苍穹外卖学习Day10_第11张图片
新建一个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 注解,表明它是一个 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();
            }
        }
    }

}

导入配置类

/**
 * 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 的实例。

来单提醒

需求分析

黑马苍穹外卖学习Day10_第12张图片
黑马苍穹外卖学习Day10_第13张图片

代码开发

在OrderService实现类中的函数修改

    /**
     * 支付成功,修改订单状态
     *
     * @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);
    }

客户催单

需求分析

黑马苍穹外卖学习Day10_第14张图片

代码开发

Controller层`

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

Service实现类

        /**
        * 客户催单
        * @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));
    }

你可能感兴趣的:(学习,数据库,spring,boot,mybatis,websocket)