• Java项目-苍穹外卖-Day10-SpirngTask及WebSocket


    前言

    本章实现的业务功能

    超时未支付订单自动取消,配送中订单商家忘点完成自动再固定时间检查且修改成完成状态
    在这里插入图片描述
    来单提醒功能
    在这里插入图片描述
    催单提醒功能
    在这里插入图片描述

    SpringTask

    介绍

    在这里插入图片描述
    在这里插入图片描述

    SpringTask_corn表达式

    一般的话周几和第几日是不能同时出现的
    因为比如 4月15日 周四 可能4月15日不是周四 可能冲突的 所以周和日一般只能有一个
    在这里插入图片描述
    现在有这种生成表达式的网站
    在这里插入图片描述
    !其实还挺复杂的,建议看个视频稍微学一下怎么用这个网站

    Spring_Task入门案例

    使用springtask主要关注 1.cron表达式 2.内部处理逻辑
    spring_Task挺小的一个框架,是没有自己的jar包的,集成在了spring_context这个包里面
    在这里插入图片描述
    在这里插入图片描述
    自定义的定时任务类
    在这里插入图片描述

    订单状态定时处理

    需求分析

    在这里插入图片描述
    在这里插入图片描述
    合理一点,你派送中订单不能12点弄的,一般这个时候有很多是真的在派送中的

    代码开发

    com.sky.Task.OrderTask

    //自定义定时任务类,定时处理订单状态
    @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 * * ?")//每天凌晨一点触发一次
        public void processDeliveryOrder(){
            log.info("定时处理处于派送中的订单:{}",LocalDateTime.now());
    
            List<Orders> ordersList = orderMapper.
                    getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS, LocalDateTime.now().plusMinutes(-60));
            if(ordersList != null && ordersList.size() > 0){
                for (Orders orders : ordersList) {
                    orders.setStatus(Orders.COMPLETED);
                    orderMapper.update(orders);
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    ordermapper

        /**
         *根据订单状态和订单时间查询订单
         * @return
         */
        @Select("select * from orders where status=#{status} and order_time < #{orderTime} ")
        List<Orders> getByStatusAndOrderTimeLT(Integer status, LocalDateTime orderTime);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    功能测试


    这个运行然后看数据库
    弄几个status为1(待支付)的订单然后等到它自动处理看看能不能取消
    然后那个配送的可以改一下那个cron表达式不用真的等到1点

    WebScoket

    介绍

    在这里插入图片描述
    在这里插入图片描述

    入门案例

    在这里插入图片描述
    com.sky.webscoket.WebSocketServer
    前三个方法 1. 建立连接 2.进行通话 3.结束连接
    最后一个是 服务端向客户端发送信息的方法需要自己调用 所以没有注解标识

    package com.sky.webscoket;
    
    /**
     * WebSocket服务
     */
    @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();
                }
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    给这个bean注册一下
    在这里插入图片描述

    弄个Task来模拟服务端发消息
    在这里插入图片描述

    然后自己运行一下看效果
    在这里插入图片描述
    在这里插入图片描述

    来单提醒

    需求分析

    在这里插入图片描述
    在这里插入图片描述

    代码开发

    修改OrderServiceImpl的代码
    在PaySuccess下新增推送消息即可
    新增的

            //通过websocket向客户端浏览器推送消息!!!!!!!!!
            Map map = new HashMap();
            map.put("type",1);//type1表示来单提醒 2表示客户催单
            map.put("orderId",ordersDB.getId());
            map.put("content","订单号"+ outTradeNo);
            String json = JSON.toJSONString(map);
            webSocketServer.sendToAllClient(json);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    完整的

    
        /**
         * 支付成功,修改订单状态
         *
         * @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向客户端浏览器推送消息!!!!!!!!!
            Map map = new HashMap();
            map.put("type",1);//type1表示来单提醒 2表示客户催单
            map.put("orderId",ordersDB.getId());
            map.put("content","订单号"+ outTradeNo);
            String json = JSON.toJSONString(map);
            webSocketServer.sendToAllClient(json);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    功能测试

    这个略显难受
    因为我们实际上没有实现微信支付接口
    所以我们要更改一下逻辑的
    小程序前端

    if (res.code === 1) {
                wx.showModel({
                  title: '提示',
                  content: '支付成功',
                  success:function(){
                    uni.redirectTo({url: '/pages/success/index?orderId=' + _this.orderId });
                  }
                })
              //  wx.requestPayment({
              //    nonceStr: res.data.nonceStr,
              //    package: res.data.packageStr,
              //    paySign: res.data.paySign,
              //    timeStamp: res.data.timeStamp,
              //    signType: res.data.signType,
              //    success:function(res){
              //      wx.showModal({
              //        title: '提示',
              //        content: '支付成功',
              //        success:function(){
              //          uni.redirectTo({url: '/pages/success/index?orderId=' + _this.orderId });
              //        }
              //      })
              //      console.log('支付成功!')
              //    }
              //  })
    
    //  直接重新定向不用微信支付
    //这里的代码移到前面
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在这里插入图片描述
    OrderController
    在这里插入图片描述

    OrderServiceImpl
    在这里插入图片描述
    效果就会是你点击确定支付就会直接支付成功
    且不会跳出那个支付成功的页面

    客户催单

    代码开发

    controller

       /**
         * 客户催单
         * @param id
         * @return
         */
        @ApiOperation("客户催单")
        @GetMapping("/reminder/{id}")
        public Result reminder(@PathVariable Long id){
            orderService.reminder(id);
            return Result.success();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    serviceimpl

        /**
         * 用户催单
         * @param id
         */
        public void reminder(Long id) {
            // 根据id查询订单
            Orders ordersDB = orderMapper.getById(id);
    
            // 校验订单是否存在
            if (ordersDB == 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","订单号:"+ordersDB.getNumber());
            String json = JSON.toJSONString(map);
            webSocketServer.sendToAllClient(json);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    功能测试

    催单去个人中心的订单找
    然后我这个没报语音(后来我换了edge浏览器就可以了)
    在这里插入图片描述

  • 相关阅读:
    qml 两个listview共用一个listmodel,显示排斥的数据
    java计算机毕业设计高中生学业水平测试系统源码+mysql数据库+系统+lw文档+部署
    梦开始的地方 —— C语言(枚举+位段+联合体)
    13.2 GAS与输入
    Web3 时代 市场营销的变迁
    十大运动蓝牙耳机品牌排行榜,六款值得买的运动耳机推荐
    x64dbg 自动化控制插件
    node实现本地接口,地址可以访问
    交换机和路由器技术-17-生成树协议配置
    怎么配置electron-updater
  • 原文地址:https://blog.csdn.net/y_k_j_c/article/details/132752113