苍穹外卖项目(黑马)学习笔记DAY10

        

目录

Spring Task

cron表达式

使用步骤

订单状态定时处理

WebSocket       

 来单提醒

客户催单


Spring Task

        Spring Task是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。

  • cron表达式

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

苍穹外卖项目(黑马)学习笔记DAY10_第1张图片

  • 使用步骤

        1.导入maven坐标spring-context

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

        3.自定义定时任务类(需要交给容器管理,在方法上使用@Scheduled注解)

订单状态定时处理

        由于可能存在用户下单后付款超时和订单一直处于派送的情况,需要使用定时处理这两种情况。

    @Scheduled(cron = "0 * * * * ?")
    public void processTimeoutOrder(){
        LocalDateTime time = LocalDateTime.now().plusMinutes(-15);
        List ordersList = orderMapper.getByStatusAndTimeLT(Orders.PENDING_PAYMENT, time);
        for (Orders order : ordersList) {
            order.setStatus(Orders.CANCELLED);
            order.setCancelReason("订单超时,自动取消");
            order.setCancelTime(LocalDateTime.now());
            orderMapper.update(order);
        }
    }




/mapper
    @Select("select * from sky_take_out.orders where status=#{status} and order_time < #{time}")
    List getByStatusAndTimeLT(Integer status, LocalDateTime time);

        对于支付超时的订单,一分钟查询一次,如果发现则将其订单状态修改为“已取消”。对于派送中的订单,每天的凌晨1点检查一次,如果发现则将其订单修改为“已完成”

    @Scheduled(cron = "0 0 1 * * ?")
    public void processDeliveryOrder(){
        LocalDateTime localDateTime = LocalDateTime.now().plusMinutes(-60);
        List byStatusAndTimeLT = orderMapper.getByStatusAndTimeLT(Orders.DELIVERY_IN_PROGRESS, localDateTime);
        for (Orders order : byStatusAndTimeLT) {
            order.setStatus(Orders.COMPLETED);

            orderMapper.update(order);
        }
    }

WebSocket       

        WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。应用场景:视频弹幕、网页聊天、体育实况更新、股票基金报价实时更新

  •  来单提醒

@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {

    //存放会话对象
    private static Map 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 sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

//OrderServiceImpl.paysuccess

        orderMapper.update(orders);
        Map map=new HashMap<>();
        map.put("type",1);
        map.put("orderId",ordersDB.getId());
        map.put("content","订单号:"+outTradeNo);
        String json= JSON.toJSONString(map);
        websocketserve.sendToAllClient(json);

        一开始自己做的时候发现,前端没有反应。我们要确保将订单状态变成已支付后调用websocket就可以了。但是,我们支付的回调是不行的。因此这里的解决方案是在用户提交订单的时候,将订单状态修改成已支付带派送,并在之后调用websocket。完整的用户提交订单代码如下:

    @Transactional
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
        //异常情况的处理(收货地址为空、购物车为空)
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        Long userId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);

        //查询当前用户的购物车数据
        List shoppingCartList = shoppingCartMapper.list(shoppingCart);
        if (shoppingCartList == null || shoppingCartList.size() == 0) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        //构造订单数据
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO,order);
        order.setPhone(addressBook.getPhone());
        order.setAddress(addressBook.getDetail());
        order.setConsignee(addressBook.getConsignee());
        order.setNumber(String.valueOf(System.currentTimeMillis()));
        order.setUserId(userId);
        //order.setStatus(Orders.PENDING_PAYMENT);
        order.setStatus(Orders.TO_BE_CONFIRMED);
        //order.setPayStatus(Orders.UN_PAID);
        order.setPayStatus(Orders.PAID);
        order.setOrderTime(LocalDateTime.now());

        //向订单表插入1条数据
        orderMapper.insert(order);

        //订单明细数据
        List orderDetailList = new ArrayList<>();
        for (ShoppingCart cart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail);
            orderDetail.setOrderId(order.getId());
            orderDetailList.add(orderDetail);
        }

        //向明细表插入n条数据
        orderDetailMapper.insertBatch(orderDetailList);

        //清理购物车中的数据
        shoppingCartMapper.deleteByUseId(userId);

        Map map=new HashMap<>();
        map.put("type",1);
        map.put("orderId",order.getId());
        map.put("content","订单号:"+order.getNumber());
        String json= JSON.toJSONString(map);
        websocketserve.sendToAllClient(json);

        //封装返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(order.getId())
                .orderNumber(order.getNumber())
                .orderAmount(order.getAmount())
                .orderTime(order.getOrderTime())
                .build();

        return orderSubmitVO;
    }

客户催单

    @Override
    public void reminder(Long id) {
        Orders order = orderMapper.getById(id);
        if(order == null){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        Map map=new HashMap();
        map.put("type",2);
        map.put("orderId",id);
        map.put("content","订单号: "+order.getNumber());
        websocketserve.sendToAllClient(JSON.toJSONString(map));
    }

你可能感兴趣的:(苍穹外卖学习笔记,学习,笔记,spring,maven,spring,boot)