首页 > 编程语言 >Java实现:如何通过调度任务搜索附近代驾司机

Java实现:如何通过调度任务搜索附近代驾司机

时间:2024-08-19 10:56:04浏览次数:12  
标签:newOrderDataVo Java 调度 司机 订单 searchNearByDriverForm 代驾 newOrderTaskVo redisTempl

文章目录


在现代的出行服务中,代驾服务越来越普及。为了确保用户能够快速找到附近的代驾司机,自动化调度系统显得尤为重要。今天,我将分享一个Java实现的调度任务,旨在根据用户的位置自动搜索附近符合条件的代驾司机,并推送订单信息。

任务需求

我们需要完成以下几个任务:

  1. 根据任务ID从数据库中查询任务的创建情况。
  2. 根据订单状态判断是否继续执行任务调度。
  3. 远程调用服务来搜索附近满足条件的司机。
  4. 为满足条件的司机创建临时队列,并将新订单信息推送给他们。

代码实现

下面是完整的代码实现,逐步解析各个步骤。

// 执行任务:搜索附近代驾司机
@Override
public void executeTask(long jobId) {
    // 1. 根据jobid查询数据库,当前任务是否已经创建
    // 如果没有创建,不往下执行了
    LambdaQueryWrapper<OrderJob> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(OrderJob::getJobId, jobId);
    OrderJob orderJob = orderJobMapper.selectOne(wrapper);
    if (orderJob == null) {
        return;
    }

    // 2. 查询订单状态,如果当前订单接单状态,继续执行。如果当前订单不是接单状态,停止任务调度
    String jsonString = orderJob.getParameter();
    NewOrderTaskVo newOrderTaskVo = JSON.parseObject(jsonString, NewOrderTaskVo.class);

    Long orderId = newOrderTaskVo.getOrderId();
    Integer status = orderInfoFeignClient.getOrderStatus(orderId).getData();
    if (status.intValue() != OrderStatus.WAITING_ACCEPT.getStatus().intValue()) {
        // 停止任务调度
        xxlJobClient.startJob(jobId);
        return;
    }

    // 3. 远程调用:搜索附近满足条件的司机
    SearchNearByDriverForm searchNearByDriverForm = new SearchNearByDriverForm();
    searchNearByDriverForm.setLongitude(newOrderTaskVo.getStartPointLongitude());
    searchNearByDriverForm.setLatitude(newOrderTaskVo.getStartPointLatitude());
    searchNearByDriverForm.setMileageDistance(newOrderTaskVo.getExpectDistance());

    List<NearByDriverVo> nearByDriverVoList = locationFeignClient.searchNearByDriver(searchNearByDriverForm)
                                                                 .getData();

    // 4. 遍历集合,得到每个司机,为每个司机创建临时队列,存储新订单信息
    nearByDriverVoList.forEach(driver -> {
        // 使用Redis的set类型,保证不重复
        String repeatKey = RedisConstant.DRIVER_ORDER_REPEAT_LIST + newOrderTaskVo.getOrderId();
        // 记录司机id,防止重复推送
        Boolean isMember = redisTemplate.opsForSet().isMember(repeatKey, driver.getDriverId());
        if (!isMember) {
            // 把订单消息推送给满足条件的多个司机
            redisTemplate.opsForSet().add(repeatKey, driver.getDriverId());
            // 过期时间:15分钟,超过15分钟没有接单自动取消
            redisTemplate.expire(repeatKey, RedisConstant.DRIVER_ORDER_REPEAT_LIST_EXPIRES_TIME, TimeUnit.MINUTES);

            NewOrderDataVo newOrderDataVo = new NewOrderDataVo();
            newOrderDataVo.setOrderId(newOrderTaskVo.getOrderId());
            newOrderDataVo.setStartLocation(newOrderTaskVo.getStartLocation());
            newOrderDataVo.setEndLocation(newOrderTaskVo.getEndLocation());
            newOrderDataVo.setExpectAmount(newOrderTaskVo.getExpectAmount());
            newOrderDataVo.setExpectDistance(newOrderTaskVo.getExpectDistance());
            newOrderDataVo.setExpectTime(newOrderTaskVo.getExpectTime());
            newOrderDataVo.setFavourFee(newOrderTaskVo.getFavourFee());
            newOrderDataVo.setDistance(driver.getDistance());
            newOrderDataVo.setCreateTime(newOrderTaskVo.getCreateTime());

            // 新订单保存司机的临时队列,Redis里面List集合
            String key = RedisConstant.DRIVER_ORDER_REPEAT_LIST + driver.getDriverId();
            redisTemplate.opsForList().leftPush(key, JSONObject.toJSONString(newOrderDataVo));
            // 过期时间:1分钟
            redisTemplate.expire(key, RedisConstant.DRIVER_ORDER_TEMP_LIST_EXPIRES_TIME, TimeUnit.MINUTES);
        }
    });
}

代码解读

1. 任务查询和校验

首先,我们根据任务ID (jobId) 查询数据库,判断该任务是否已经创建。如果没有找到相应的任务记录,直接返回,结束任务执行。

LambdaQueryWrapper<OrderJob> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OrderJob::getJobId, jobId);
OrderJob orderJob = orderJobMapper.selectOne(wrapper);
if (orderJob == null) {
    return;
}

2. 订单状态检查

接下来,通过远程调用获取订单的当前状态。只有当订单状态为“等待接单”时,任务才会继续执行。如果订单状态不符,则停止任务调度。

Long orderId = newOrderTaskVo.getOrderId();
Integer status = orderInfoFeignClient.getOrderStatus(orderId).getData();
if (status.intValue() != OrderStatus.WAITING_ACCEPT.getStatus().intValue()) {
    xxlJobClient.startJob(jobId);
    return;
}

3. 搜索附近的司机

使用locationFeignClient远程调用服务,搜索在用户附近的符合条件的司机。我们通过用户的经纬度和预期距离来筛选司机。

SearchNearByDriverForm searchNearByDriverForm = new SearchNearByDriverForm();
searchNearByDriverForm.setLongitude(newOrderTaskVo.getStartPointLongitude());
searchNearByDriverForm.setLatitude(newOrderTaskVo.getStartPointLatitude());
searchNearByDriverForm.setMileageDistance(newOrderTaskVo.getExpectDistance());

List<NearByDriverVo> nearByDriverVoList = locationFeignClient.searchNearByDriver(searchNearByDriverForm)
                                                             .getData();

4. 推送订单信息

最后,我们遍历满足条件的司机列表,为每个司机创建一个临时队列,并将订单信息推送给他们。我们使用Redis来保证推送的订单不会重复,并为每个订单设置了过期时间。

nearByDriverVoList.forEach(driver -> {
    String repeatKey = RedisConstant.DRIVER_ORDER_REPEAT_LIST + newOrderTaskVo.getOrderId();
    Boolean isMember = redisTemplate.opsForSet().isMember(repeatKey, driver.getDriverId());
    if (!isMember) {
        redisTemplate.opsForSet().add(repeatKey, driver.getDriverId());
        redisTemplate.expire(repeatKey, RedisConstant.DRIVER_ORDER_REPEAT_LIST_EXPIRES_TIME, TimeUnit.MINUTES);

        NewOrderDataVo newOrderDataVo = new NewOrderDataVo();
        newOrderDataVo.setOrderId(newOrderTaskVo.getOrderId());
        newOrderDataVo.setStartLocation(newOrderTaskVo.getStartLocation());
        newOrderDataVo.setEndLocation(newOrderTaskVo.getEndLocation());
        newOrderDataVo.setExpectAmount(newOrderTaskVo.getExpectAmount());
        newOrderDataVo.setExpectDistance(newOrderTaskVo.getExpectDistance());
        newOrderDataVo.setExpectTime(newOrderTaskVo.getExpectTime());
        newOrderDataVo.setFavourFee(newOrderTaskVo.getFavourFee());
        newOrderDataVo.setDistance(driver.getDistance());
        newOrderDataVo.setCreateTime(newOrderTaskVo.getCreateTime());

        String key = RedisConstant.DRIVER_ORDER_REPEAT_LIST + driver.getDriverId();
        redisTemplate.opsForList().leftPush(key, JSONObject.toJSONString(newOrderDataVo));
        redisTemplate.expire(key, RedisConstant.DRIVER_ORDER_TEMP_LIST_EXPIRES_TIME, TimeUnit.MINUTES);
    }
});

结论

这个调度任务的实现有效地解决了通过位置搜索司机并推送订单的问题。通过整合数据库查询、远程调用、Redis缓存等多种技术,我们实现了一个高效的代驾司机调度系统。希望这个例子能够对你的项目开发有所帮助!

标签:newOrderDataVo,Java,调度,司机,订单,searchNearByDriverForm,代驾,newOrderTaskVo,redisTempl
From: https://blog.csdn.net/Takumilove/article/details/141320045

相关文章

  • JAVA毕业设计|(免费)springboot基于spring boot的校园商铺管理系统包含文档代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot188springboot基于springboot的校园商铺管理系统开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue+html工具:IDEA/Ecilpse、Navicat、Maven1.系统展示2.万字文档展示第5章系统详细设计系统实现这个章节的......
  • JAVA毕业设计|(免费)springboot基于java的火车票订票系统的包含文档代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot294springboot基于java的火车票订票系统的开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven1.系统展示2.万字文档展示第5章系统详细设计这个环节需要使用前面的设计方案,......
  • Java中ArrayList集合—基础详解(知识点+代码示例)
    ArrayList(集合)ArrayList(集合)ArrayList(集合)10.1ArrayList成员方法10.2集合练习10.2.1添加字符串10.2.2添加数字10.2.3添加学生对象并遍历10.2.4集合概述:集合可以直接存储引用数据类型,不能直接存储基本数据类型,如果要存储基本数据类型,需要将基本数据类型变成对......
  • java队列
    1.队列定义:在Java中,队列(Queue)是一种常用的数据结构,属于java.util包。Queue接口继承自Collection接口,定义了一些基本操作,如入队、出队、查看队列头部等。Java提供了多种实现Queue接口的类,这些类可以满足不同的使用需求。2.Java队列的常见实现LinkedList:实现了Que......
  • Sonarqube 自定义规则,部署SonarSource / sonar-java源码中示例规则:docs/java-custom-r
    自定义规则,可以参考sonar-java/docs/CUSTOM_RULES_101.mdat8.0.0.36314·SonarSource/sonar-java·GitHub1、下载一份sonarqube源码,配置好本地的环境,JDK17和mavendocs/java-custom-rules-example示例项目中会有写好的规则;我们可以先尝试将这些写好的规则添加到Sonarqube......
  • (免费源码)计算机毕业设计必看必学 php 酒店预约管理系统-92767-原创定制程序 java、PHP
    摘 要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,酒店预约管理系统当然也不能排除在外。酒店预约管理系统是以实际运用为开发背景,运用软件工程开发方法,采用Thinkphp技术构建的一个管理系统。整个开发过程首......
  • 计算机毕业设计必看必学! ! 94755 spring boot高校毕业生就业信息管理系统,原创定制程
    摘 要信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对高校毕业生就业信息管理系统等问题,对高校毕业生就业信息管理系统进行研究分析,然后开发设计......
  • java计算机毕业设计疫情防控下社区互助服务系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景:在全球新冠疫情持续蔓延的背景下,社区作为疫情防控的第一线,其治理能力和服务效率直接关系到居民的健康安全与生活质量。随着疫情防控常态化,如何有效整......
  • Java入门:06.Java中的方法01
    经过了一段时间的学习,我们数组篇章终于告一段落了,我们又在Java前进之路上迈出了一大步,本期文章,我们将一起了解Java中的方法,这是十分重要的一个章节。那么要向学习方法就需要先明白,什么是方法:1什么是方法首先,如果从逻辑层面来理解:我们一般说,方法表示一个功能,一个行为,一个......
  • 基于springboot+vue+java的的智慧养老平台vue含文档lw
    前言......