目录

一、Spring Task

1、简介

2、cron表达式

3、入门案例

二、订单状态定时处理模块

1、需求分析

2、代码开发

(1)OrderTask

(2)OrderMapper

三、WebSocket

1、简介

(1)HTTP协议和WebSocket协议对比

(2)应用场景

2、入门案例

四、来单提醒模块

1、需求分析

2、代码开发

3、功能测试

五、用户催单模块

1、需求分析

2、代码开发

3、功能测试

六、思考:用户催单和来单提示是怎么实现的?

1、来单提示流程

2、用户催单流程


一、Spring Task

1、简介

Spring Task 是 Spring 框架提供的一个定时任务调度器

它允许开发者以注解或配置的方式,在指定的时间或周期性地执行某个方法。

2、cron表达式

  • cron表达式其实就是一个字符串,通过cron表达式可以定义任务触发的时间
  • 构成规则:分为6或7个域,由空格分隔开,每个域代表一个含义
  • 每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)

2022年10月12日上午9点的corn表达式为

其中【日】和【周】一般不能同时规定,因为10.12不一定是周几,同理,周五不一定是固定的某日

因此若规定日,则【周】为【?】;若规定周,则【日】为【?】

我们想要生成更为复杂的corn时间表达式,可以问AI

3、入门案例

(1)导入maven(已存在)

(2)启动类添加注解 @EnableScheduling开启任务调度

(3)自定义定时任务类

二、订单状态定时处理模块

1、需求分析

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

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

对于上面两种情况需要通过定时任务来修改订单状态,具体逻辑为:

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

2、代码开发

(1)OrderTask

/**
 * 自定义定时任务类
 */
@Component
@Slf4j
public class OrderTask {

    @Autowired
    private OrderMapper orderMapper;

    /**
     * 处理超时订单
     */
    @Scheduled(cron = "0 * * * * ?") //每分钟处理一次
    public void processTimeoutOrder(){
        log.info("定时处理超时订单:{}", LocalDateTime.now());

        //1.找出当前订单超时且状态为【待支付】的订单列表
        LocalDateTime time = LocalDateTime.now().plusMinutes(-15);//当前时间-15min

        List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, time);

        //2.将状态更改为【已取消】,并更新取消原因和取消时间
        if(!CollectionUtils.isEmpty(ordersList)){
            for (Orders od : ordersList) {
                od.setStatus(Orders.CANCELLED);
                od.setCancelReason("订单超时,自动取消");
                od.setCancelTime(LocalDateTime.now());

                orderMapper.update(od);
            }
        }
    }

    /**
     * 处理一直派送中的订单
     */
    @Scheduled(cron = "0 0 1 * * ?")//每天凌晨一点
    public void processDeliverOrder(){
        log.info("定时处理一直派送中订单:{}", LocalDateTime.now());

        //1.找出前一天且状态为【派送中】的订单列表
        LocalDateTime time = LocalDateTime.now().plusMinutes(-60);//当前时间-60min

        List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS, time);

        //2.将状态更改为【已完成】
        if(!CollectionUtils.isEmpty(ordersList)){
            for (Orders od : ordersList) {
                od.setStatus(Orders.COMPLETED);

                orderMapper.update(od);
            }
        }
    }

}

(2)OrderMapper

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

三、WebSocket

1、简介

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

一次连接,实时更新,用于一些需要即时更新的场景

(1)HTTP协议和WebSocket协议对比

  • HTTP是短连接
  • WebSocket长连接
  • HTTP通信是单向的,基于请求响应模式
  • WebSocket支持双向通信
  • HTTP和WebSocket底层都是TCP连接

(2)应用场景

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

2、入门案例

(1)导入maven

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>compile</scope>
        </dependency>

(2)导入配置类

(3)导入代码

将day10中的代码导入

(4)测试

重新启动项目,在项目登录页面点击登录,若在ide控制台可以看到下面的提示,则表明连接成功

四、来单提醒模块

1、需求分析

  • 通过 WebSocket 实现【后端】和【管理系统】保持长连接状态
  • 客户支付后,调用 WebSocket 的相关API实现后端(服务端)向管理系统(客户端)推送消息
  • 管理系统浏览器解析后端推送的消息,判断是【来单提醒】还是【客户催单】,进行相应的【消息提示】和【语音播报】
  • 约定后端发送给管理系统浏览器的数据格式为JSON,字段包括:type,orderld,content
    • type 为消息类型,1为来单提醒 2为客户催单
    • orderld 为订单id
    • content 为消息内容

2、代码开发

因为我们在day8的支付模块是跳过微信支付的,因此来单提醒模块也同样需要更改

OrderServiceImpl 中的 payment 方法下增加以下代码

        //通过WebSocket向客户端浏览器推送消息 type orderId content
        Map map = new HashMap<>();
        map.put("type",1); //1表示来单提醒,2表示客户催单
        map.put("orderId",this.orders.getId());
        map.put("content","订单号:"+this.orders.getNumber());

        String json = JSON.toJSONString(map);
        //向所有连接的 WebSocket 客户端广播发送 JSON 数据
        webSocketServer.sendToAllClient(json);

3、功能测试

启动项目,然后返回登录界面点击【登录】,就能在ide控制台中看到成功连接提示

接着启动小程序,选择若干商品并点击支付,支付成功后,后台管理网页会在右上角弹出窗口,并进行语音播报,若成功显示即为测试成功

五、用户催单模块

1、需求分析

  • 通过 WebSocket 实现【后端】页面和【小程序】保持长连接状态
  • 用户催单后,调用 WebSocket 的相关API实现后端(服务端)向小程序(客户端)推送消息
  • 小程序解析后端推送的消息,判断是【来单提醒】还是【客户催单】,进行相应的【消息提示】和【语音播报】
  • 约定后端发送给小程序的数据格式为JSON,字段包括:type,orderld,content
    • type 为消息类型,1为来单提醒 2为客户催单
    • orderld 为订单id
    • content 为消息内容

2、代码开发

【1】controller层

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

【2】service层

    /**
     * 用户催单
     * @param id
     */
    public void reminder(Long id) {
        //根据id查询订单是否存在
        Orders orderDB = orderMapper.getById(id);

        if(orderDB == null){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //通过WebSocket向客户端浏览器推送消息 type orderId content
        Map map = new HashMap<>();
        map.put("type",2); //1表示来单提醒,2表示客户催单
        map.put("orderId",orderDB.getId());
        map.put("content","订单号:"+orderDB.getNumber());

        String json = JSON.toJSONString(map);
        //向所有连接的 WebSocket 客户端广播发送 JSON 数据
        webSocketServer.sendToAllClient(json);
    }

3、功能测试

重新启动项目,在小程序用户订单中点击【催单】,即可在管理系统页面看到催单提示

六、思考:用户催单和来单提示是怎么实现的?

1、来单提示流程

2、用户催单流程

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐