From c96fbe6b0aeb413a17c429133ee6d81d138144b9 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期二, 09 六月 2026 10:58:52 +0800
Subject: [PATCH] Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.0

---
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java | 1301 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 1,241 insertions(+), 60 deletions(-)

diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
index b192bcc..27c5b4f 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -1,7 +1,10 @@
 package com.xiaopeng.operation.utils;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
 import com.xiaopeng.api.dto.map.RouteAndFareDto;
 import com.xiaopeng.api.dto.operation.LonLatDto;
@@ -16,30 +19,36 @@
 import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
 import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
 import com.xiaopeng.api.model.operation.XpElectronicFence;
+import com.xiaopeng.api.model.operation.XpTargetedServiceVehicle;
 import com.xiaopeng.api.model.operation.XpTradingStrategy;
+import com.xiaopeng.api.model.operation.XpTradingStrategyPush;
+import com.xiaopeng.api.model.order.XpCruiseOrder;
 import com.xiaopeng.api.model.order.XpOrder;
 import com.xiaopeng.api.model.order.XpOrderReassign;
 import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
 import com.xiaopeng.api.vo.OrderType;
 import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
+import com.xiaopeng.api.vo.automaticPilot.protobuf.TaskActionType;
 import com.xiaopeng.api.vo.operation.RouteVo;
 import com.xiaopeng.api.vo.operation.VehiclePositionVo;
+import com.xiaopeng.api.vo.operation.XpTargetedServiceVehicleVo;
 import com.xiaopeng.api.vo.operation.XpTradingStrategyDetailVO;
 import com.xiaopeng.common.core.constant.CacheConstants;
 import com.xiaopeng.common.core.constant.Constants;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.enums.OrderStatusEnum;
+import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
+import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.redis.service.RedisService;
 import com.xiaopeng.operation.config.UidVinBindingConfig;
 import com.xiaopeng.operation.dto.PriorityMatchResult;
 import com.xiaopeng.operation.mapper.XpElectronicFenceMapper;
-import com.xiaopeng.operation.service.IXpElectronicFenceAreaService;
-import com.xiaopeng.operation.service.IXpTradingStrategyService;
-import com.xiaopeng.operation.service.UidVinPriorityMatcher;
-import com.xiaopeng.operation.service.XpPointService;
+import com.xiaopeng.operation.service.*;
 import com.xiaopeng.operation.utils.mango.VehiclePositionService;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.data.mongodb.core.MongoTemplate;
@@ -51,6 +60,8 @@
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -60,7 +71,11 @@
 @Slf4j
 @Component
 public class TaskOrderUtil {
+    @Resource
+    private XpTargetedServiceService xpTargetedServiceService;
 
+    @Resource
+    private XpTargetedServiceVehicleService xpTargetedServiceVehicleService;
 
     @Resource
     private RedisService redisService;
@@ -79,6 +94,9 @@
 
     @Resource
     private IXpTradingStrategyService xpTradingStrategyService;
+
+    @Resource
+    private IXpTradingStrategyPushService xpTradingStrategyPushService;
 
     @Resource
     private XpCruiseOrderClient xpCruiseOrderClient;
@@ -112,6 +130,9 @@
     @Resource
     private  XpAppUserCouponClient xpAppUserCouponClient;
 
+    @Resource
+    private OfficialPartnerUtil officialPartnerUtil;
+
 
     // 自定义线程池
     private static final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
@@ -129,6 +150,7 @@
 
     /**
      * 5秒执行一次
+     * 播单 在下单的时候会存一个 redis 队列
      */
     @Scheduled(cron = "0/5 * * * * ?")
     public void taskOrder() {
@@ -144,8 +166,54 @@
                     // 状态改为处理中
                     redisService.updateFirst(name, value);
                     threadPoolTaskExecutor.submit(() -> {
-                        orderProcess(name, firstElement.toString());
+                        log.info("订单处理:{}", firstElement);
+                        orderProcess(name, firstElement.toString(), false);
                     });
+                }else{
+                    //判断订单状态,如果不是待接单,则将数据清除
+                    String orderId = split[0];
+                    XpOrder xpOrder = xpOrderClient.queryOrderById(Long.valueOf(orderId)).getData();
+                    if(xpOrder.getStatus() != OrderStatusEnum.PENDING_ORDER.getCode()){
+                        if(StringUtils.isNotEmpty((xpOrder.getQueueName()))){
+                            redisService.removeByPattern(xpOrder.getQueueName(), xpOrder.getOrderNumber());
+                        }
+                    }
+
+                }
+            }
+        }
+    }
+
+    /**
+     * 定向订单
+     */
+    @Scheduled(cron = "0/5 * * * * ?")
+    public void taskOrder_targeted() {
+        System.out.println("5秒执行一次");
+        Set<String> quoteMatchName = redisService.getQuoteMatchName(CacheConstants.SP_QUEUE_POINT_ID);
+        for (String name : quoteMatchName) {
+            String firstElement = redisService.getFirstElement(name);
+            if (firstElement != null) {
+                String[] split = firstElement.toString().split("_");
+                // 如果未处理 创建新任务
+                if (split[2].equals("0")) {
+                    String value = split[0] + "_" + split[1] + "_1" + "_" + split[3] + "_" + split[4] + "_" + split[5] + "_" + split[6] + "_" + split[7] + "_" + split[8];
+                    // 状态改为处理中
+                    redisService.updateFirst(name, value);
+                    threadPoolTaskExecutor.submit(() -> {
+                        log.info("定向订单处理:{}", firstElement);
+                        orderProcess(name, firstElement.toString(), true);
+                    });
+                }else{
+                    //判断订单状态,如果不是待接单,则将数据清除
+                    String orderId = split[0];
+                    XpOrder xpOrder = xpOrderClient.queryOrderById(Long.valueOf(orderId)).getData();
+                    if(xpOrder.getStatus() != OrderStatusEnum.PENDING_ORDER.getCode()){
+                        if(StringUtils.isNotEmpty(xpOrder.getQueueName())){
+                            redisService.removeByPattern(xpOrder.getQueueName(), xpOrder.getOrderNumber());
+                        }
+                    }
+
                 }
             }
         }
@@ -157,7 +225,7 @@
      * @param quoteName 队列名称
      * @param firstElement 队列第一个元素
      */
-    private void orderProcess(String quoteName, String firstElement) {
+    private void orderProcess(String quoteName, String firstElement, Boolean isTargetedService) {
         XpTradingStrategy xpTradingStrategy = xpTradingStrategyService.getOne(null);
         String orderId = firstElement.split("_")[0];
         String lonLat = firstElement.split("_")[1];
@@ -173,58 +241,68 @@
         // 经纬度
         String[] split = lonLat.split(",");
 
+        //查询当前时段是不是特殊推单时段
+        List<XpTradingStrategyPush> tradingStrategyId = xpTradingStrategyPushService.list(new QueryWrapper<XpTradingStrategyPush>().eq("trading_strategy_id", xpTradingStrategy));
+        long now = Long.parseLong(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmm")));
+        XpTradingStrategyPush xpTradingStrategyPush = tradingStrategyId.stream().filter(item -> {
+            long start = Long.parseLong(item.getStartTime().replace(":", ""));
+            long end = Long.parseLong(item.getEndTime().replace(":", ""));
+            return now >= start && now < end;
+        }).findFirst().orElse(null);
+
+
         // 5轮找车辆
         //每次查找车辆推单后的等待秒数
         int sleepTime = 3;
-        Integer onePushTime = xpTradingStrategy.getOnePushTime();
-        Double onePushDistance = xpTradingStrategy.getOnePushDistance();
+        Integer onePushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getOnePushTime() : xpTradingStrategy.getOnePushTime();
+        Double onePushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getOnePushDistance() : xpTradingStrategy.getOnePushDistance();
         int count = onePushTime / sleepTime;
         // 第一轮推单
         log.info("开始第一轮推单 {}", orderNo);
-        Boolean processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, onePushDistance, distance, duration, planRule);
+        Boolean processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, onePushDistance, distance, duration, planRule, isTargetedService);
         if(processed){
             log.info("订单推送成功 {}", orderNo);
             return;
         }
         // 第二轮推单
-        Integer twoPushTime = xpTradingStrategy.getTwoPushTime();
-        Double twoPushDistance = xpTradingStrategy.getTwoPushDistance();
+        Integer twoPushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getTwoPushTime() : xpTradingStrategy.getTwoPushTime();
+        Double twoPushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getTwoPushDistance() : xpTradingStrategy.getTwoPushDistance();
         count = twoPushTime / sleepTime;
         log.info("开始第二轮推单 {}", orderNo);
-        processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, twoPushDistance, distance, duration, planRule);
+        processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, twoPushDistance, distance, duration, planRule, isTargetedService);
         if(processed){
             log.info("订单推送成功 {}", orderNo);
             return;
         }
 
         // 第三轮推单
-        Integer threePushTime = xpTradingStrategy.getThreePushTime();
-        Double threePushDistance = xpTradingStrategy.getThreePushDistance();
+        Integer threePushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getThreePushTime() : xpTradingStrategy.getThreePushTime();
+        Double threePushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getThreePushDistance() : xpTradingStrategy.getThreePushDistance();
         count = threePushTime / sleepTime;
         log.info("开始第三轮推单 {}", orderNo);
-        processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, threePushDistance, distance, duration, planRule);
+        processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, threePushDistance, distance, duration, planRule, isTargetedService);
         if(processed){
             log.info("订单推送成功 {}", orderNo);
             return;
         }
 
         // 第四轮推单
-        Integer fourPushTime = xpTradingStrategy.getFourPushTime();
-        Double fourPushDistance = xpTradingStrategy.getFourPushDistance();
+        Integer fourPushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getFourPushTime() : xpTradingStrategy.getFourPushTime();
+        Double fourPushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getFourPushDistance() : xpTradingStrategy.getFourPushDistance();
         count = fourPushTime / sleepTime;
         log.info("开始第四轮推单 {}", orderNo);
-        processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fourPushDistance, distance, duration, planRule);
+        processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fourPushDistance, distance, duration, planRule, isTargetedService);
         if(processed){
             log.info("订单推送成功 {}", orderNo);
             return;
         }
 
         // 第五轮推单
-        Integer fivePushTime = xpTradingStrategy.getFivePushTime();
-        Double fivePushDistance = xpTradingStrategy.getFivePushDistance();
+        Integer fivePushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getFivePushTime() : xpTradingStrategy.getFivePushTime();
+        Double fivePushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getFivePushDistance() : xpTradingStrategy.getFivePushDistance();
         count = fivePushTime / sleepTime;
         log.info("开始第五轮推单 {}", orderNo);
-        processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fivePushDistance, distance, duration, planRule);
+        processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fivePushDistance, distance, duration, planRule, isTargetedService);
         if(processed){
             log.info("订单推送成功 {}", orderNo);
             return;
@@ -235,8 +313,8 @@
         if (xpOrderR.getCode() == 200) {
             XpOrder xpOrder = xpOrderR.getData();
             if (xpOrder.getStatus() == 1) {
-                log.info("五轮推单结束,无车辆接单,执行取消订单 {}", orderNo);
                 xpOrderClient.cancelOrder(orderId);
+                log.info("五轮推单结束,无车辆接单,执行取消订单 {}", orderNo);
                 //推送订单状态给乘客
                 SendMessageDTO dto = new SendMessageDTO();
                 dto.setAppUserId(xpOrder.getAppUserId().toString());
@@ -260,9 +338,6 @@
                         }
                     });
                 }
-                //将订单从队列中移除
-                log.info("五轮推单结束,无车辆接单,执行队列移除订单 {}", orderNo);
-                redisService.popFirstElement(quoteName);
             }
         }
 
@@ -279,7 +354,7 @@
      * @param xpTradingStrategy  规则
      */
     @SneakyThrows
-    private Boolean processPushOrder(String quoteName, int count, int sleepTime, String uid, String[] split, String orderNo, XpTradingStrategy xpTradingStrategy, Double pushDistance, String distance, String duration, String planRule) {
+    private Boolean processPushOrder(String quoteName, int count, int sleepTime, String uid, String[] split, String orderNo, XpTradingStrategy xpTradingStrategy, Double pushDistance, String distance, String duration, String planRule, Boolean isTargetedService) {
         log.info("进入推单环节 单号 {}", orderNo);
         if (count == 0) {
             count = 1;
@@ -294,7 +369,1018 @@
         }
         XpOrder xpOrder = xpOrderR.getData();
         if (xpOrder.getStatus() == 0) {
-            redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+            log.info("订单已取消,退出退单逻辑 {}", orderNo);
+            if(StringUtils.isNotEmpty(quoteName)){
+                redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+            }
+            return true;
+        }
+
+        // 找出围栏id
+        Long xpElectronicFenceAreaId = xpOrder.getXpElectronicFenceAreaId();
+        Long electronicId = xpElectronicFenceAreaService.getById(xpElectronicFenceAreaId).getElectronicId();
+        XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(electronicId);
+
+        // ===== 新增:UID-VIN 优先匹配(仅 enabled=true 时生效)=====
+        log.info("[人车订单绑定测试] >>>>>> 进入优先匹配判断, uid={}, orderNo={}, 围栏区域ID={}", uid, orderNo, xpElectronicFenceAreaId);
+        if (uidVinBindingConfig.isEnabled()) {
+            log.info("[人车订单绑定测试] 总开关已开启, 开始执行优先匹配逻辑, uid={}, orderNo={}", uid, orderNo);
+            try {
+                PriorityMatchResult priorityResult = uidVinPriorityMatcher.tryPriorityMatch(uid, orderNo, String.valueOf(xpElectronicFenceAreaId));
+                log.info("[人车订单绑定测试] 优先匹配结果: matched={}, vin={}, failReason={}, uid={}, orderNo={}",
+                        priorityResult != null ? priorityResult.isMatched() : "null",
+                        priorityResult != null ? priorityResult.getVin() : "null",
+                        priorityResult != null ? priorityResult.getFailReason() : "null",
+                        uid, orderNo);
+                if (priorityResult != null && priorityResult.isMatched()) {
+                    String priorityVin = priorityResult.getVin();
+                    log.info("[人车订单绑定测试] 匹配成功, 准备获取分布式锁, lockKey=FIND_CAR_{}, orderNo={}", priorityVin, orderNo);
+                    RLock priorityLock = redissonClient.getLock("FIND_CAR_" + priorityVin);
+                    priorityLock.lock(10, TimeUnit.SECONDS);
+                    log.info("[人车订单绑定测试] 分布式锁获取成功, vin={}, orderNo={}", priorityVin, orderNo);
+                    try {
+                        // 二次校验车辆状态
+                        log.info("[人车订单绑定测试] 开始二次校验车辆状态, vin={}, orderNo={}", priorityVin, orderNo);
+                        R<XpVehicle> vehicleR = xpVehicleClient.findByVehicleVin(priorityVin);
+                        log.info("[人车订单绑定测试] 二次校验-车辆查询结果: code={}, hasData={}, vin={}", vehicleR.getCode(), vehicleR.getData() != null, priorityVin);
+                        if (vehicleR.getCode() == 200 && vehicleR.getData() != null) {
+                            XpVehicle vehicle = vehicleR.getData();
+                            //判断当前车辆是否在禁派单车辆内
+                            String cacheList = redisService.getCacheObject("CAN_NOT_RECEIVE_ORDER_VEHICLE:" + xpOrder.getId());
+                            List<String> strings = new ArrayList<>();
+                            if(null != cacheList){
+                                strings = JSON.parseArray(cacheList, String.class);
+                            }
+                            log.info("[人车订单绑定测试] 二次校验-车辆状态: operatingStatus={}, state={}, vehicleType={}, vin={}",
+                                    vehicle.getOperatingStatus(), vehicle.getState(), vehicle.getVehicleType(), priorityVin);
+                            if (vehicle.getOperatingStatus() == 1 && vehicle.getState() == 0 && vehicle.getVehicleType() != 1 && !strings.contains(vehicle.getVehicleVin())) {
+                                log.info("[人车订单绑定测试] 二次校验-车辆状态通过(空闲), 开始校验订单状态, orderNo={}", orderNo);
+                                // 二次校验订单状态
+                                R<XpOrder> orderCheck = xpOrderClient.queryOrderByOrderNo(orderNo);
+                                log.info("[人车订单绑定测试] 二次校验-订单查询结果: code={}, status={}, orderNo={}",
+                                        orderCheck.getCode(),
+                                        orderCheck.getData() != null ? orderCheck.getData().getStatus() : "null",
+                                        orderNo);
+                                if (orderCheck.getCode() == 200 && orderCheck.getData() != null && orderCheck.getData().getStatus() == 1) {
+                                    log.info("[人车订单绑定测试] 二次校验全部通过, 开始关闭巡游单, vin={}, orderNo={}", priorityVin, orderNo);
+                                    // 关闭巡游单
+                                    R stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(priorityVin);
+                                    log.info("[人车订单绑定测试] 关闭巡游单结果: code={}, vin={}, orderNo={}",
+                                            stringR != null ? stringR.getCode() : "null", priorityVin, orderNo);
+                                    if (stringR != null && stringR.getCode() == 200) {
+                                        log.info("[人车订单绑定测试] 关闭巡游单成功, 开始下发XPU命令, vin={}, orderNo={}", priorityVin, orderNo);
+                                        // 下发XPU命令
+                                        PushOrderDto pushOrderDto = new PushOrderDto();
+                                        pushOrderDto.setVin(priorityVin);
+                                        pushOrderDto.setOrderId(orderCheck.getData().getId().toString());
+                                        pushOrderDto.setStartTaskId(orderCheck.getData().getXpuStartTaskId());
+                                        pushOrderDto.setEndTaskId(orderCheck.getData().getXpuEndTaskId());
+                                        pushOrderDto.setStartWaypointId(orderCheck.getData().getStartPointId());
+                                        pushOrderDto.setEndWaypointId(orderCheck.getData().getEndPointId());
+                                        pushOrderDto.setStartLatitude(orderCheck.getData().getStartLat());
+                                        pushOrderDto.setStartLongitude(orderCheck.getData().getStartLon());
+                                        pushOrderDto.setEndLatitude(orderCheck.getData().getEndLat());
+                                        pushOrderDto.setEndLongitude(orderCheck.getData().getEndLon());
+                                        pushOrderDto.setEndPoiName(orderCheck.getData().getEndPointName());
+                                        pushOrderDto.setOrderType(OrderType.USER_ORDER);
+                                        pushOrderDto.setStage(1);
+                                        log.info("[人车订单绑定测试] XPU推单参数: vin={}, orderId={}, startLat={}, startLon={}, endLat={}, endLon={}, orderNo={}",
+                                                priorityVin, orderCheck.getData().getId(), orderCheck.getData().getStartLat(), orderCheck.getData().getStartLon(),
+                                                orderCheck.getData().getEndLat(), orderCheck.getData().getEndLon(), orderNo);
+                                        orderMissionClient.pushOrder(pushOrderDto);
+                                        log.info("[人车订单绑定测试] ====== 派单成功! uid={}, vin={}, orderNo={}, 从队列移除订单 ======", uid, priorityVin, orderNo);
+                                        if(StringUtils.isNotEmpty(quoteName)){
+                                            redisService.removeByPattern(quoteName, orderNo);
+                                        }
+
+                                        return true;
+                                    } else {
+                                        log.info("[人车订单绑定测试] 关闭巡游单失败, 回退常规流程, vin={}, orderNo={}", priorityVin, orderNo);
+                                    }
+                                } else {
+                                    log.info("[人车订单绑定测试] 二次校验-订单状态不满足(非待派单), 回退常规流程, orderNo={}", orderNo);
+                                }
+                            } else {
+                                if (vehicle.getState() != 0) {
+                                    log.info("[人车订单绑定测试] 二次校验-车辆已接单(state={}), 当前有未完成订单, 无法指派, vin={}, plateNumber={}, orderNo={}",
+                                            vehicle.getState(), priorityVin, vehicle.getPlateNumber(), orderNo);
+                                } else {
+                                    log.info("[人车订单绑定测试] 二次校验-车辆状态不满足, 回退常规流程, vin={}, operatingStatus={}, state={}, vehicleType={}",
+                                            priorityVin, vehicle.getOperatingStatus(), vehicle.getState(), vehicle.getVehicleType());
+                                }
+                            }
+                        } else {
+                            log.info("[人车订单绑定测试] 二次校验-车辆查询失败, 回退常规流程, vin={}, code={}", priorityVin, vehicleR.getCode());
+                        }
+                    } catch (Exception e) {
+                        log.error("[人车订单绑定测试] 锁内执行异常,回退常规流程, uid={}, vin={}, orderNo={}", uid, priorityVin, orderNo, e);
+                    } finally {
+                        priorityLock.unlock();
+                        log.info("[人车订单绑定测试] 分布式锁已释放, vin={}, orderNo={}", priorityVin, orderNo);
+                    }
+                } else {
+                    log.info("[人车订单绑定测试] 优先匹配未命中, 进入常规流程, uid={}, orderNo={}", uid, orderNo);
+                }
+            } catch (Exception e) {
+                log.error("[人车订单绑定测试] 优先匹配过程异常,回退常规流程, uid={}, orderNo={}", uid, orderNo, e);
+            }
+        } else {
+            log.info("[人车订单绑定测试] 总开关未开启(enabled=false), 跳过优先匹配, uid={}, orderNo={}", uid, orderNo);
+        }
+        // ===== 新增结束 =====
+
+        for (int i = 0; i < count; i++) {
+            //等到sleepTime秒钟
+            Thread.sleep(sleepTime * 1000);
+            // 根据距离找车
+            // 车多则根据配置找具体车数量 根据距离最近
+            // 更改 暂不限制数量
+            List<VehiclePosition> positionList = vehiclePositionService.findAvailableVehiclesNearby(Double.parseDouble(split[0]), Double.parseDouble(split[1]), pushDistance, xpTradingStrategy.getSimultaneouslyOrderCount());
+            log.info("根据距离找车 {} 距离 {}KM  经度 {} 维度 {} 查找结果 {} 单号 {}", orderNo, pushDistance, split[0], split[1], JSON.toJSONString(positionList), orderNo);
+            // 获取车辆的区域信息
+            if (positionList.isEmpty()) {
+                continue;
+            }
+            Set<String> vinList = positionList.stream().map(VehiclePosition::getVin).collect(Collectors.toSet());
+
+            //判断当前车辆是否在禁派单车辆内
+            String cacheList = redisService.getCacheObject("CAN_NOT_RECEIVE_ORDER_VEHICLE:" + xpOrder.getId());
+            if(Objects.nonNull(cacheList)){
+                List<String> strings = JSON.parseArray(cacheList, String.class);
+                Set<String> vins = new HashSet<>();
+                for (String s : vinList) {
+                    if (!strings.contains(s)) {
+                        vins.add(s);
+                    }
+                }
+                vinList = vins;
+            }
+
+            // 获取车辆的信息 筛选出可用车辆,定向服务的车辆排除
+            R<List<String>> vehiclePositionVos = xpVehicleClient.queryVehiclePositionByVin(new VehiclePositionByVinDto(xpElectronicFence.getId(), vinList, xpTradingStrategy.getSimultaneouslyOrderCount()));
+            log.info("筛选可用车辆结果 {} 单号 {}", JSON.toJSONString(vehiclePositionVos), orderNo);
+            List<String> vehicleVinByTargetedService = xpTargetedServiceVehicleService.getVehicleVinByTargetedService(xpOrderR.getData().getCityCode());
+            if(!isTargetedService){
+                vehiclePositionVos.getData().removeAll(vehicleVinByTargetedService);
+                log.info("剔除定向服务车辆后的结果 {} 单号 {}", JSON.toJSONString(vehiclePositionVos), orderNo);
+            }else{
+                vehiclePositionVos.setData(vehicleVinByTargetedService);
+                log.info("查找定向服务车辆后的结果 {} 单号 {}", JSON.toJSONString(vehiclePositionVos), orderNo);
+            }
+            if (vehiclePositionVos.getCode() != 200) {
+                continue;
+            }
+            List<VehiclePositionVo> availableVehiclesNearby = BeanUtil.copyToList(positionList, VehiclePositionVo.class);
+            List<String> data = vehiclePositionVos.getData();
+
+            // 找出符合条件的
+            availableVehiclesNearby = availableVehiclesNearby.stream().filter(e -> data.contains(e.getVin())).collect(Collectors.toList());
+
+            if (!availableVehiclesNearby.isEmpty()) {
+                if (availableVehiclesNearby.size() > 1) {
+                    log.info("附近有 {} 辆车,进入权重判断流程 单号 {}", availableVehiclesNearby.size(), orderNo);
+                    // 走权重
+
+                    // 订单价值
+                    Integer tendencyOrderValue = xpTradingStrategy.getTendencyOrderValue();
+
+                    // 距离价值
+                    Integer tendencyDistance = xpTradingStrategy.getTendencyDistance();
+
+                    // 时间价值
+                    Integer tendencyTime = xpTradingStrategy.getTendencyTime();
+
+                    try {
+
+                        // 电量价值
+                        Integer tendencyElectricity = xpTradingStrategy.getTendencyElectricity();
+                        // 找出最大的值是那个
+                        Integer max = Math.max(tendencyOrderValue, Math.max(tendencyDistance, Math.max(tendencyTime, tendencyElectricity)));
+                        if (max.equals(tendencyOrderValue)) {
+                            // 订单价值
+                            // 时间差权重
+                            Integer weightTimeDifference = xpTradingStrategy.getWeightTimeDifference();
+                            // 距离差权重
+                            Integer weightDistanceDifference = xpTradingStrategy.getWeightDistanceDifference();
+                            // 距离权重
+                            Integer weightDistance = xpTradingStrategy.getWeightDistance();
+                            // 时间权重
+                            Integer weightTime = xpTradingStrategy.getWeightTime();
+                            // 电量权重
+                            Integer weightElectricity = xpTradingStrategy.getWeightElectricity();
+
+                            // 找出最大的值是那个
+                            Integer max1 = Math.max(weightTimeDifference, Math.max(weightDistanceDifference, Math.max(weightDistance, Math.max(weightTime, weightElectricity))));
+
+                            //  时间差
+                            if (max1.equals(weightTimeDifference)) {
+                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                    RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                    LonLatDto lonLatDto = new LonLatDto();
+                                    lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                    lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                    routeAndFareDto.setOrigin(lonLatDto);
+                                    LonLatDto lonLatDto1 = new LonLatDto();
+                                    lonLatDto1.setLongitude(Double.valueOf(split[0]));
+                                    lonLatDto1.setLatitude(Double.valueOf(split[1]));
+                                    routeAndFareDto.setDestination(lonLatDto1);
+                                    if(planRule!=null&& !"null".equals(planRule)){
+                                        routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                    }
+                                    R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                    if (distanceAndDuration.getCode() == 200) {
+                                        // 送驾- 接驾
+                                        Integer durationDifference = Integer.parseInt(duration) - distanceAndDuration.getData().getDuration();
+                                        vehiclePosition.setTimeDifference(durationDifference);
+                                    }
+                                }
+                            }
+
+
+                            // 距离差
+
+                            if (max1.equals(weightDistanceDifference)) {
+                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                    RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                    LonLatDto lonLatDto = new LonLatDto();
+                                    lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                    lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                    routeAndFareDto.setOrigin(lonLatDto);
+                                    LonLatDto lonLatDto1 = new LonLatDto();
+                                    lonLatDto1.setLongitude(Double.valueOf(split[0]));
+                                    lonLatDto1.setLatitude(Double.valueOf(split[1]));
+                                    routeAndFareDto.setDestination(lonLatDto1);
+                                    if(planRule!=null&& !"null".equals(planRule)){
+                                        routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                    }
+                                    R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                    if (distanceAndDuration.getCode() == 200) {
+                                        // 送驾- 接驾
+                                        Integer distanceDifference = Integer.parseInt(distance) - distanceAndDuration.getData().getDistance();
+                                        vehiclePosition.setDistanceDifference(distanceDifference);
+                                    }
+                                }
+
+                            }
+
+                            if (max1.equals(weightDistance)) {
+                                log.info("车子距离~~");
+                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                    RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                    LonLatDto lonLatDto = new LonLatDto();
+                                    lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                    lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                    routeAndFareDto.setOrigin(lonLatDto);
+                                    LonLatDto lonLatDto1 = new LonLatDto();
+                                    lonLatDto1.setLongitude(Double.parseDouble(split[0]));
+                                    lonLatDto1.setLatitude(Double.parseDouble(split[1]));
+                                    if(planRule!=null&& !"null".equals(planRule)){
+                                        routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                    }
+                                    routeAndFareDto.setDestination(lonLatDto1);
+                                    //  调用地图 获取时间
+                                    R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                    if (r.getCode() == 200) {
+                                        log.info("车子距离~~{},{},{}",vehiclePosition.getVin(),r.getData().getDistance(),orderNo);
+                                        vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance()));
+                                    } else {
+                                        vehiclePosition.setDistance(0.0);
+                                    }
+
+                                }
+
+                                // 分数计算 把时间短的分数调高
+                                availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList());
+                                double score = 10;
+                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                    vehiclePosition.setDistance(score);
+                                    score--;
+                                }
+
+                            }
+
+                            if (max1.equals(weightTime)) {
+                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                    RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                    LonLatDto lonLatDto = new LonLatDto();
+                                    lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                    lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                    routeAndFareDto.setOrigin(lonLatDto);
+                                    LonLatDto lonLatDto1 = new LonLatDto();
+                                    lonLatDto1.setLongitude(Double.parseDouble(split[0]));
+                                    lonLatDto1.setLatitude(Double.parseDouble(split[1]));
+                                    if(planRule!=null&& !"null".equals(planRule)){
+                                        routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                    }
+                                    routeAndFareDto.setDestination(lonLatDto1);
+                                    //  调用地图 获取时间
+                                    R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                    if (r.getCode() == 200) {
+                                        vehiclePosition.setSecond(r.getData().getDuration());
+                                    } else {
+                                        vehiclePosition.setSecond(0);
+                                    }
+                                }
+                                // 分数计算 把时间短的分数调高
+                                availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getSecond)).collect(Collectors.toList());
+                                int score = 10;
+                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                    vehiclePosition.setSecond(score);
+                                    score--;
+                                }
+
+                            }
+
+                            if (max1.equals(weightElectricity)) {
+                                // 计算车的分数  分数最大是车的size
+                                availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getCurrentElectricity).reversed()).collect(Collectors.toList());
+                                int size = tendencyElectricity;
+                                // 做比对的分数
+                                int temp = availableVehiclesNearby.get(0).getCurrentElectricity();
+                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                    vehiclePosition.setCurrentElectricityScore(vehiclePosition.getCurrentElectricityScore() + size);
+                                    if (temp != vehiclePosition.getCurrentElectricity()) {
+                                        size--;
+                                    }
+                                }
+                            }
+
+
+                            // 算出总分 再来排序计算
+                            for (VehiclePositionVo vehiclePositionVo : availableVehiclesNearby) {
+                                vehiclePositionVo.setOrderValueTotal(vehiclePositionVo.getCurrentElectricityScore() + vehiclePositionVo.getDistanceScore() + vehiclePositionVo.getTimeScore() + vehiclePositionVo.getDistanceDifference() + vehiclePositionVo.getTimeDifference()+vehiclePositionVo.getSecond()+vehiclePositionVo.getDistance().intValue());
+                            }
+                            availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getOrderValueTotal).reversed()).collect(Collectors.toList());
+
+
+                            int size = tendencyOrderValue;
+                            // 做比对的分数
+                            double temp = availableVehiclesNearby.get(0).getOrderValueTotal();
+                            for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                vehiclePosition.setValueScore(vehiclePosition.getValueScore() + size);
+                                if (temp != vehiclePosition.getOrderValueTotal()) {
+                                    size--;
+                                }
+                            }
+
+
+                        }
+
+                        // 距离分数
+                        if (max.equals(tendencyDistance)) {
+                            log.info("车子距离~~");
+                            for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                LonLatDto lonLatDto = new LonLatDto();
+                                lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                routeAndFareDto.setOrigin(lonLatDto);
+                                LonLatDto lonLatDto1 = new LonLatDto();
+                                lonLatDto1.setLongitude(Double.parseDouble(split[0]));
+                                lonLatDto1.setLatitude(Double.parseDouble(split[1]));
+
+                                if(planRule!=null&& !"null".equals(planRule)){
+                                    routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                }
+                                routeAndFareDto.setDestination(lonLatDto1);
+                                //  调用地图 获取时间
+                                R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                if (r.getCode() == 200) {
+                                    log.info("车子距离~~{},{},{}",vehiclePosition.getVin(),r.getData().getDistance(),orderNo);
+                                    vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance()));
+                                } else {
+                                    vehiclePosition.setDistance(0.0);
+                                }
+                            }
+//                            availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList());
+//                            int size = tendencyDistance;
+//                            // 做比对的分数
+//                            double temp = availableVehiclesNearby.get(0).getDistance();
+//                            for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+//                                vehiclePosition.setDistanceScore(vehiclePosition.getDistanceScore() + size);
+//                                if (temp != vehiclePosition.getDistance()) {
+//                                    size--;
+//                                }
+//                            }
+
+                            // 分数计算 把时间短的分数调高
+                            availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList());
+                            int score = 10;
+                            for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                vehiclePosition.setDistanceScore(score);
+                                score--;
+                            }
+                        }
+
+
+                        // 时间分数
+                        if (max.equals(tendencyTime)) {
+                            for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                LonLatDto lonLatDto = new LonLatDto();
+                                lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                routeAndFareDto.setOrigin(lonLatDto);
+                                LonLatDto lonLatDto1 = new LonLatDto();
+                                lonLatDto1.setLongitude(Double.parseDouble(split[0]));
+                                lonLatDto1.setLatitude(Double.parseDouble(split[1]));
+
+                                if(planRule!=null&& !"null".equals(planRule)){
+                                    routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                }
+                                routeAndFareDto.setDestination(lonLatDto1);
+                                //  调用地图 获取时间
+                                R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                if (r.getCode() == 200) {
+                                    vehiclePosition.setSecond(r.getData().getDuration());
+                                } else {
+                                    vehiclePosition.setSecond(0);
+                                }
+                            }
+
+                            // 分数计算 把时间短的分数调高
+                            availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getSecond)).collect(Collectors.toList());
+                            int score = 10;
+                            for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                vehiclePosition.setTimeScore(score);
+                                score--;
+                            }
+//                            availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getSecond)).collect(Collectors.toList());
+//                            int size = tendencyTime;
+//                            // 做比对的分数
+//                            double temp = availableVehiclesNearby.get(0).getSecond();
+//                            for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+//                                vehiclePosition.setTimeScore(vehiclePosition.getTimeScore() + size);
+//                                if (temp != vehiclePosition.getSecond()) {
+//                                    size--;
+//                                }
+//                            }
+
+                        }
+
+
+                        // 电量分数
+                        if (max.equals(tendencyElectricity)) {
+                            // 计算车的分数  分数最大是车的size
+                            availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getCurrentElectricity).reversed()).collect(Collectors.toList());
+                            int size = tendencyElectricity;
+                            // 做比对的分数
+                            int temp = availableVehiclesNearby.get(0).getCurrentElectricity();
+
+                            int maxTemp = 0;
+                            for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                vehiclePosition.setCurrentElectricityScore(vehiclePosition.getCurrentElectricityScore() + size);
+                                if (temp != vehiclePosition.getCurrentElectricity()) {
+                                    size--;
+                                } else {
+                                    maxTemp++;
+                                }
+                            }
+
+                            if (maxTemp > 1) {
+                                // 证明有最高相同电量的  找下一个
+                                // 找出最第二大的值是那个
+                                // 将四个值放入列表
+                                List<Integer> values = Arrays.asList(tendencyOrderValue, tendencyDistance, tendencyTime);
+                                // 降序排序
+                                values.sort(Collections.reverseOrder());
+                                // 获取第二大值
+                                Integer secondMax = values.get(1);
+
+                                // 判断第二大的是哪个
+                                if (Objects.equals(secondMax, tendencyDistance)) {
+                                    for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                        RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                        LonLatDto lonLatDto = new LonLatDto();
+                                        lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                        lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                        routeAndFareDto.setOrigin(lonLatDto);
+                                        LonLatDto lonLatDto1 = new LonLatDto();
+                                        lonLatDto1.setLongitude(Double.parseDouble(split[0]));
+                                        lonLatDto1.setLatitude(Double.parseDouble(split[1]));
+                                        if(planRule!=null&& !"null".equals(planRule)){
+                                            routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                        }
+                                        routeAndFareDto.setDestination(lonLatDto1);
+                                        //  调用地图 获取时间
+                                        R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                        if (r.getCode() == 200) {
+                                            vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance()));
+                                        } else {
+                                            vehiclePosition.setDistance(0.0);
+                                        }
+                                    }
+                                    availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList());
+                                    int size1 = tendencyDistance;
+                                    // 做比对的分数
+                                    double temp1 = availableVehiclesNearby.get(0).getDistance();
+                                    for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                        vehiclePosition.setDistanceScore(vehiclePosition.getDistanceScore() + size1);
+                                        if (temp1 != vehiclePosition.getDistance()) {
+                                            size1--;
+                                        }
+                                    }
+                                }
+
+
+                                if (Objects.equals(secondMax, tendencyTime)) {
+                                    for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                        RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                        LonLatDto lonLatDto = new LonLatDto();
+                                        lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                        lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                        routeAndFareDto.setOrigin(lonLatDto);
+                                        LonLatDto lonLatDto1 = new LonLatDto();
+                                        lonLatDto1.setLongitude(Double.parseDouble(split[0]));
+                                        lonLatDto1.setLatitude(Double.parseDouble(split[1]));
+
+                                        if(planRule!=null&& !"null".equals(planRule)){
+                                            routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                        }
+                                        routeAndFareDto.setDestination(lonLatDto1);
+                                        //  调用地图 获取时间
+                                        R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                        if (r.getCode() == 200) {
+                                            vehiclePosition.setSecond(r.getData().getDuration());
+                                        } else {
+                                            vehiclePosition.setSecond(0);
+                                        }
+                                    }
+                                    availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getSecond)).collect(Collectors.toList());
+                                    int size1 = tendencyTime;
+                                    // 做比对的分数
+                                    double temp1 = availableVehiclesNearby.get(0).getSecond();
+                                    for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                        vehiclePosition.setTimeScore(vehiclePosition.getTimeScore() + size1);
+                                        if (temp1 != vehiclePosition.getSecond()) {
+                                            size1--;
+                                        }
+                                    }
+                                }
+
+
+                                // 订单价值
+                                if (Objects.equals(secondMax, tendencyOrderValue)) {
+                                    // 订单价值
+                                    // 时间差权重
+                                    Integer weightTimeDifference = xpTradingStrategy.getWeightTimeDifference();
+                                    // 距离差权重
+                                    Integer weightDistanceDifference = xpTradingStrategy.getWeightDistanceDifference();
+                                    // 距离权重
+                                    Integer weightDistance = xpTradingStrategy.getWeightDistance();
+                                    // 时间权重
+                                    Integer weightTime = xpTradingStrategy.getWeightTime();
+                                    // 电量权重
+                                    Integer weightElectricity = xpTradingStrategy.getWeightElectricity();
+
+                                    // 找出最大的值是那个
+                                    Integer max1 = Math.max(weightTimeDifference, Math.max(weightDistanceDifference, Math.max(weightDistance, Math.max(weightTime, weightElectricity))));
+
+                                    //  时间差
+                                    if (max1.equals(weightTimeDifference)) {
+                                        for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                            RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                            LonLatDto lonLatDto = new LonLatDto();
+                                            lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                            lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                            routeAndFareDto.setOrigin(lonLatDto);
+                                            LonLatDto lonLatDto1 = new LonLatDto();
+                                            lonLatDto1.setLongitude(Double.valueOf(split[0]));
+                                            lonLatDto1.setLatitude(Double.valueOf(split[1]));
+                                            routeAndFareDto.setDestination(lonLatDto1);
+                                            if(planRule!=null&& !"null".equals(planRule)){
+                                                routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                            }
+                                            R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                            if (distanceAndDuration.getCode() == 200) {
+                                                // 送驾- 接驾
+                                                Integer durationDifference = Integer.parseInt(duration) - distanceAndDuration.getData().getDuration();
+                                                vehiclePosition.setTimeDifference(durationDifference);
+                                            }
+                                        }
+                                    }
+
+                                    if (max1.equals(weightDistanceDifference)) {
+                                        for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                            RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                            LonLatDto lonLatDto = new LonLatDto();
+                                            lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                            lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                            routeAndFareDto.setOrigin(lonLatDto);
+                                            LonLatDto lonLatDto1 = new LonLatDto();
+                                            lonLatDto1.setLongitude(Double.valueOf(split[0]));
+                                            lonLatDto1.setLatitude(Double.valueOf(split[1]));
+                                            routeAndFareDto.setDestination(lonLatDto1);
+                                            if(planRule!=null&& !"null".equals(planRule)){
+                                                routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                            }
+                                            R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                            if (distanceAndDuration.getCode() == 200) {
+                                                // 送驾- 接驾
+                                                Integer distanceDifference = Integer.parseInt(distance) - distanceAndDuration.getData().getDistance();
+                                                vehiclePosition.setDistanceDifference(distanceDifference);
+                                            }
+                                        }
+
+                                    }
+
+                                    if (max1.equals(weightDistance)) {
+                                        for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                            RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                            LonLatDto lonLatDto = new LonLatDto();
+                                            lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                            lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                            routeAndFareDto.setOrigin(lonLatDto);
+                                            LonLatDto lonLatDto1 = new LonLatDto();
+                                            lonLatDto1.setLongitude(Double.parseDouble(split[0]));
+                                            lonLatDto1.setLatitude(Double.parseDouble(split[1]));
+                                            if(planRule!=null&& !"null".equals(planRule)){
+                                                routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                            }
+                                            routeAndFareDto.setDestination(lonLatDto1);
+                                            //  调用地图 获取时间
+                                            R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                            if (r.getCode() == 200) {
+                                                vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance()));
+                                            } else {
+                                                vehiclePosition.setDistance(0.0);
+                                            }
+                                        }
+                                    }
+
+                                    if (max1.equals(weightTime)) {
+                                        for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                            RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+                                            LonLatDto lonLatDto = new LonLatDto();
+                                            lonLatDto.setLongitude(vehiclePosition.getPoint().getX());
+                                            lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+                                            routeAndFareDto.setOrigin(lonLatDto);
+                                            LonLatDto lonLatDto1 = new LonLatDto();
+                                            lonLatDto1.setLongitude(Double.parseDouble(split[0]));
+                                            lonLatDto1.setLatitude(Double.parseDouble(split[1]));
+                                            if(planRule!=null&& !"null".equals(planRule)){
+                                                routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+                                            }
+                                            routeAndFareDto.setDestination(lonLatDto1);
+                                            //  调用地图 获取时间
+                                            R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+                                            if (r.getCode() == 200) {
+                                                vehiclePosition.setSecond(r.getData().getDuration());
+                                            } else {
+                                                vehiclePosition.setSecond(0);
+                                            }
+                                        }
+                                    }
+
+                                    if (max1.equals(weightElectricity)) {
+                                        // 计算车的分数  分数最大是车的size
+                                        availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getCurrentElectricity).reversed()).collect(Collectors.toList());
+                                        int size1 = tendencyElectricity;
+                                        // 做比对的分数
+                                        int temp1 = availableVehiclesNearby.get(0).getCurrentElectricity();
+                                        for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                            vehiclePosition.setCurrentElectricityScore(vehiclePosition.getCurrentElectricityScore() + size1);
+                                            if (temp1 != vehiclePosition.getCurrentElectricity()) {
+                                                size1--;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                // 算出总分 再来排序计算
+                                for (VehiclePositionVo vehiclePositionVo : availableVehiclesNearby) {
+                                    vehiclePositionVo.setOrderValueTotal(vehiclePositionVo.getCurrentElectricityScore() + vehiclePositionVo.getDistanceScore() + vehiclePositionVo.getTimeScore() + vehiclePositionVo.getDistanceDifference() + vehiclePositionVo.getTimeDifference()+vehiclePositionVo.getSecond()+vehiclePositionVo.getDistance().intValue());
+                                }
+                                availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getOrderValueTotal).reversed()).collect(Collectors.toList());
+
+
+                                int size2 = tendencyOrderValue;
+                                // 做比对的分数
+                                double temp2 = availableVehiclesNearby.get(0).getOrderValueTotal();
+                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+                                    vehiclePosition.setValueScore(vehiclePosition.getValueScore() + size2);
+                                    if (temp2 != vehiclePosition.getOrderValueTotal()) {
+                                        size2--;
+                                    }
+                                }
+
+                            }
+                        }
+
+
+                    } catch (Exception e) {
+                        log.error("异常", e);
+                    }
+
+                    // 判断总分来计算
+                    for (VehiclePositionVo vehiclePositionVo : availableVehiclesNearby) {
+                        vehiclePositionVo.setTotal(vehiclePositionVo.getCurrentElectricityScore() + vehiclePositionVo.getDistanceScore() + vehiclePositionVo.getTimeScore() + vehiclePositionVo.getValueScore());
+                    }
+                    VehiclePositionVo vehiclePositionVo = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getTotal).reversed()).collect(Collectors.toList()).get(0);
+
+                    RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePositionVo.getVin());
+                    lock.lock(10, TimeUnit.SECONDS);
+                    log.info("队列 {} 车辆 {} 单号 {}", quoteName, vehiclePositionVo.getVin(), orderNo);
+                    try {
+                        R<XpVehicle> vehiclePositionR = xpVehicleClient.findByVehicleVin(vehiclePositionVo.getVin());
+                        if (vehiclePositionR.getCode() == 200) {
+                            XpVehicle vehiclePosition = vehiclePositionR.getData();
+                            log.info("符合条件的车辆 {} ,直接推单XPU。单号 {}", vehiclePosition.getPlateNumber(), orderNo);
+                            log.info("当前车辆状态 {} 单号 {}", vehiclePosition.getState(), orderNo);
+
+                            String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehiclePosition.getVehicleVin());
+                            // 再次查询一下订单 看是否取消
+                            xpOrder = xpOrderClient.queryOrderByOrderNo(orderNo).getData();
+                            if (xpOrder.getStatus() == 1) {
+                                //所有条件满足,走正常派单,不满足走后面的连环派单
+                                if (vehiclePosition.getOperatingStatus() == 1 && vehiclePosition.getState() == 0 && vehiclePosition.getVehicleType() == 2) {
+                                    //非合作商的车辆需要处理巡游单
+                                    if(null == vehiclePosition.getOfficialPartnerId()){
+                                        //  关闭巡游单子
+                                        R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vin);
+                                        if (stringR != null && stringR.getCode() == 200) {
+                                            log.info("关闭巡游单成功 {} {}", vehiclePosition.getPlateNumber(), orderNo);
+                                            XpCruiseOrder cruiseOrder = stringR.getData();
+                                            // 下发命令
+                                            PushOrderDto pushOrderDto = new PushOrderDto();
+                                            pushOrderDto.setVin(vin);
+                                            pushOrderDto.setOrderId(xpOrder.getId().toString());
+                                            pushOrderDto.setStartTaskId(xpOrder.getXpuStartTaskId());
+                                            pushOrderDto.setEndTaskId(xpOrder.getXpuEndTaskId());
+                                            pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+                                            pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
+                                            pushOrderDto.setStartLatitude(xpOrder.getStartLat());
+                                            pushOrderDto.setStartLongitude(xpOrder.getStartLon());
+                                            pushOrderDto.setEndLatitude(xpOrder.getEndLat());
+                                            pushOrderDto.setEndLongitude(xpOrder.getEndLon());
+                                            pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
+                                            pushOrderDto.setOrderType(OrderType.USER_ORDER);
+                                            pushOrderDto.setStage(1);
+                                            if(null != cruiseOrder){
+                                                pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+                                                pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+                                            }
+                                            pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
+                                            // 调用推送服务  orderId + carVin
+                                            orderMissionClient.pushOrder(pushOrderDto);
+                                            log.info("开始推送 {} 订单到XPU。单号 {}", xpOrder.getOrderNumber(), orderNo);
+                                        }
+                                    }else {
+                                        //流量接入-接单推送 合作商的车辆需要调用合作商的订单通知接口
+                                        officialPartnerUtil.pushNewOrder(vehiclePosition.getOfficialPartnerId(), xpOrder);
+                                    }
+                                    if(StringUtils.isNotEmpty(quoteName)){
+                                        redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+                                    }
+
+                                    log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
+                                    return true;
+                                }
+                            }
+
+                        }
+
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    } finally {
+                        lock.unlock();
+                    }
+
+                } else {
+                    // 直接派单  定义一个锁来锁定车辆
+                    VehiclePositionVo vehiclePosition = availableVehiclesNearby.get(0);
+                    String vehicleVin = vehiclePosition.getVin();
+
+                    RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePosition.getVin());
+                    lock.lock(10, TimeUnit.SECONDS);
+                    try {
+                        // 查询车辆状态
+                        R<XpVehicle> vehicleR = xpVehicleClient.findByVehicleVin(vehicleVin);
+                        if (vehicleR.getCode() == 200) {
+                            XpVehicle vehicleId1 = vehicleR.getData();
+                            log.info("附近只有一个车辆 {} ,直接推单XPU。单号 {}", vehicleId1.getPlateNumber(), orderNo);
+                            log.info("当前车辆状态 运营状态 {} 单号 {}", vehicleId1.getState(), orderNo);
+
+                            // 再次查询一下订单 看是否取消
+                            xpOrder = xpOrderClient.queryOrderByOrderNo(orderNo).getData();
+                            if (xpOrder.getStatus() == 1) {
+                                // 所有条件满足走正常派单,不满足走循环派单
+                                if (vehicleId1.getOperatingStatus() == 1 && vehicleId1.getState() == 0 && vehicleId1.getVehicleType() == 2) {
+                                    if(null == vehicleId1.getOfficialPartnerId()){
+                                        //  关闭巡游单子
+                                        String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehicleId1.getVehicleVin());
+                                        R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vin);
+                                        if (stringR != null && stringR.getCode() == 200) {
+                                            log.info("关闭巡游单成功 {} {}", vehicleId1.getPlateNumber(), orderNo);
+                                            XpCruiseOrder cruiseOrder = stringR.getData();
+                                            PushOrderDto pushOrderDto = new PushOrderDto();
+                                            pushOrderDto.setVin(vehiclePosition.getVin());
+                                            pushOrderDto.setOrderId(xpOrder.getId().toString());
+                                            pushOrderDto.setStartTaskId(xpOrder.getXpuStartTaskId());
+                                            pushOrderDto.setEndTaskId(xpOrder.getXpuEndTaskId());
+                                            pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+                                            pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
+                                            pushOrderDto.setStartLatitude(xpOrder.getStartLat());
+                                            pushOrderDto.setStartLongitude(xpOrder.getStartLon());
+                                            pushOrderDto.setEndLatitude(xpOrder.getEndLat());
+                                            pushOrderDto.setEndLongitude(xpOrder.getEndLon());
+                                            pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
+                                            pushOrderDto.setOrderType(OrderType.USER_ORDER);
+                                            pushOrderDto.setStage(1);
+                                            if(null != cruiseOrder){
+                                                pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+                                                pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+                                            }
+                                            pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
+                                            // 调用推送服务  orderId + carVin
+                                            orderMissionClient.pushOrder(pushOrderDto);
+                                        }
+                                    }else {
+                                        //流量接入-接单推送 合作商的车辆需要调用合作商的订单通知接口
+                                        officialPartnerUtil.pushNewOrder(vehicleId1.getOfficialPartnerId(), xpOrder);
+                                    }
+                                    log.info("开始推送 {} 订单到XPU", xpOrder.getOrderNumber());
+
+                                    if(StringUtils.isNotEmpty(quoteName)){
+                                        redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+                                    }
+
+                                    log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
+                                    return true;
+                                }
+                            }
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    } finally {
+                        lock.unlock();
+                    }
+                }
+            }
+
+            log.info("没有找到空闲车辆 {},尝试连环派单给即将服务结束的车辆", orderNo);
+            // 查询状态为1的车辆vin
+            R<List<String>> servingVehicles = xpVehicleClient.queryVehiclePositionByVin(new VehiclePositionByVinDto(xpElectronicFence.getId(), vinList, xpTradingStrategy.getSimultaneouslyOrderCount(),1));
+            if (servingVehicles.getCode() != 200) {
+                continue;
+            }
+            log.info("连环派单查询车辆结果 {} {}", orderNo, JSON.toJSONString(servingVehicles.getData()));
+            if(!isTargetedService){
+                servingVehicles.getData().removeAll(vehicleVinByTargetedService);
+                log.info("连环派单剔除定向服务车辆后的结果 {} 单号 {}", JSON.toJSONString(servingVehicles), orderNo);
+            }else{
+                servingVehicles.setData(vehicleVinByTargetedService);
+                log.info("连环派单查找定向服务车辆后的结果 {} 单号 {}", JSON.toJSONString(servingVehicles), orderNo);
+            }
+
+            XpTradingStrategyDetailVO strategyDetailVO = tradingStrategyClient.queryById().getData();
+            log.info("连环排查推单逻辑 {} {}", orderNo, JSON.toJSONString(strategyDetailVO));
+            Integer distanceRegardAsEnding = strategyDetailVO.getDistanceRegardAsEnding();
+            Integer timeRegardAsEnding = strategyDetailVO.getTimeRegardAsEnding();
+
+            Integer backupPower = strategyDetailVO.getBackupPower();
+            Integer destToPassenger = strategyDetailVO.getDestToPassenger();
+            Integer endingTimeToUseTime = strategyDetailVO.getEndingTimeToUseTime();
+
+            for (String vin : servingVehicles.getData()) {
+                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class);
+                if(null == vehiclePosition){
+                    log.info("连环派单 {} 车辆查询定位数据失败 {}", vin, orderNo);
+                    continue;
+                }
+                XpOrder xpOrder1 = xpOrderClient.queryOrderById(vehiclePosition.getOrderId()).getData();
+                String json = redisService.getCacheObject(CacheConstants.nextOrder(xpOrder1.getId().toString()));
+                if (StringUtils.isNotEmpty(json)){
+                    log.info("车辆已经有连环订单 {} 单号 {}", vin, orderNo);
+                    continue;
+                }
+                Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(xpOrder1.getAppUserId().toString()));
+                RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class);
+                //距离和时间只要有一个满足条件就达到候选对象
+                if (routeRemain.getDuration() > timeRegardAsEnding * 60 && routeRemain.getDistance() > distanceRegardAsEnding * 1000) {
+                    log.info("连环派单 {} 车辆订单结束时间不满足条件 {} 秒 {} 米 {}", vin, routeRemain.getDuration(), routeRemain.getDistance(), orderNo);
+                    continue;
+                }
+
+                //剩余里程》=下一单预估里程+50
+                //预估接驾行程+送驾行程
+                RouteAndFareDto next = new RouteAndFareDto();
+                next.setOrigin(new LonLatDto(xpOrder1.getEndLon(),xpOrder1.getEndLat()));
+                next.setDestination(new LonLatDto(xpOrder.getStartLon(),xpOrder.getStartLat()));
+                RouteVo route = xpMapClient.getDistanceAndDuration(next).getData();
+                Object new_cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(xpOrder.getAppUserId().toString()));
+                RouteVo new_routeRemain = JSON.parseObject(new_cacheObject.toString(), RouteVo.class);
+                //总续航里程 米
+                long xh = new_routeRemain.getDistance() + route.getDistance() + backupPower * 1000;
+                if(vehiclePosition.getMileageRange() * 1000 < xh){
+                    log.info("连环派单 {} 车辆剩余续航不满足派车条件 {} 米 {}", vin, xh, orderNo);
+                    continue;
+                }
+
+                //下一单的起点距离本单终点小于X公里,或者下一单的用车时间与本单的预计结束时间偏差小于X分钟
+                //上一单的预估结束时间
+                LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(routeRemain.getDuration());
+                //上一单预估结束时间与本单用车时间差 秒
+                long time = localDateTime.toEpochSecond(ZoneOffset.of("+8")) - xpOrder1.getCreateTime().toEpochSecond(ZoneOffset.of("+8"));
+                if(route.getDistance() <= destToPassenger * 1000 || time <= endingTimeToUseTime * 60){
+                    log.info("连环派单 {} 找到满足条件的车辆 {} 距离 {} 时间 {}", orderNo, vin, route.getDistance(), time);
+                    log.info("上一单终点与当前订单起点距离 {} 米 {}", route.getDistance(), orderNo);
+                    log.info("当前订单用车时间与上一单预估结束时间偏差 {} 秒 {}", time, orderNo);
+                    // 设置接驾导航数据
+                    //将上一单的剩余导航添加到接驾导航中
+                    route.getPolyline().addAll(0, routeRemain.getPolyline());
+                    route.setDuration(route.getDuration() + routeRemain.getDuration());
+                    route.setDistance(route.getDistance() + routeRemain.getDistance());
+
+                    //此处找到车后先不忙给车推送接单消息,先修改订单上的车辆信息
+                    xpOrder.setVehicleId(xpOrder1.getVehicleId());
+                    xpOrder.setAcceptanceTime(LocalDateTime.now());
+                    xpOrder.setStatus(2);
+                    xpOrderClient.updateOrder(xpOrder);
+                    log.info("连环派单 {} 修改订单状态为接单成功 {}", orderNo, xpOrder.getId());
+
+                    JSONObject jsonObject = new JSONObject();
+                    jsonObject.put("orderId", xpOrder.getId());
+                    jsonObject.put("endLongitude", xpOrder.getEndLon());
+                    jsonObject.put("endLatitude", xpOrder.getEndLat());
+                    redisService.setCacheObject(CacheConstants.nextOrder(xpOrder1.getId().toString()), jsonObject.toJSONString());
+                    redisService.setCacheObject(CacheConstants.navigationStart(xpOrder.getAppUserId().toString()), JSON.toJSONString(route));
+
+                    if(StringUtils.isNotEmpty(quoteName)){
+                        redisService.removeByPattern(quoteName,xpOrder.getOrderNumber());
+                    }
+                    log.info("连环派单 {} 设置下一单接驾导航数据 {}", orderNo, JSON.toJSONString(route));
+
+                    //构建推送消息
+                    Map<String, Object> params = new HashMap<>();
+                    Map<String, Object> content = new HashMap<>();
+                    content.put("orderId", xpOrder.getId().toString());
+                    content.put("status", 2);
+                    params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
+                    params.put("content", JSONObject.toJSONString(content));
+                    params.put("timestamp", System.currentTimeMillis() + "");
+                    String message = JSONObject.toJSONString(params);
+                    SendMessageDTO dto1 = new SendMessageDTO();
+                    dto1.setAppUserId(xpOrder.getAppUserId() + "");
+                    dto1.setMessage(message);
+                    R<String> stringR = xpPushMessageClient.sendStatus(dto1);
+
+                    //推送失败,重试3次
+                    if (stringR.getCode() != Constants.SUCCESS) {
+                        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
+                        XpOrder finalXpOrder = xpOrder;
+                        executor.execute(() -> {
+                            for (int j = 0; j < 3; j++) {
+                                R<String> stringR1 = xpPushMessageClient.sendStatus(dto1);
+                                if (stringR1.getCode() == Constants.SUCCESS) {
+                                    break;
+                                }
+                                try {
+                                    Thread.sleep(1000);
+                                } catch (InterruptedException e) {
+                                    throw new RuntimeException(e);
+                                }
+                                log.info("推送订单状态消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(dto1), finalXpOrder.getOrderNumber());
+                            }
+                        });
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * 定向服务订单处理
+     * @param quoteName  队列名称
+     * @param count 轮数
+     * @param uid
+     * @param split  经纬度
+     * @param orderNo 订单号
+     * @param xpTradingStrategy  规则
+     */
+    @SneakyThrows
+    private Boolean processPushSpOrder(String quoteName, int count, int sleepTime, String uid, String[] split, String orderNo, XpTradingStrategy xpTradingStrategy, Double pushDistance, String distance, String duration, String planRule) {
+        log.info("进入推单环节 单号 {}", orderNo);
+        if (count == 0) {
+            count = 1;
+        }
+        // 订单状态
+        R<XpOrder> xpOrderR = xpOrderClient.queryOrderByOrderNo(orderNo);
+        if (xpOrderR.getCode() != 200) {
+            return false;
+        }
+        if (xpOrderR.getData().getStatus() != 1) {
+            return true;
+        }
+        XpOrder xpOrder = xpOrderR.getData();
+        if (xpOrder.getStatus() == 0) {
+            if(StringUtils.isNotEmpty(quoteName)){
+                redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+            }
+
         }
 
         // 找出围栏id
@@ -339,16 +1425,20 @@
                                 if (orderCheck.getCode() == 200 && orderCheck.getData() != null && orderCheck.getData().getStatus() == 1) {
                                     log.info("[人车订单绑定测试] 二次校验全部通过, 开始关闭巡游单, vin={}, orderNo={}", priorityVin, orderNo);
                                     // 关闭巡游单
-                                    R stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(priorityVin);
+                                    R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(priorityVin);
                                     log.info("[人车订单绑定测试] 关闭巡游单结果: code={}, vin={}, orderNo={}",
                                             stringR != null ? stringR.getCode() : "null", priorityVin, orderNo);
                                     if (stringR != null && stringR.getCode() == 200) {
                                         log.info("[人车订单绑定测试] 关闭巡游单成功, 开始下发XPU命令, vin={}, orderNo={}", priorityVin, orderNo);
+                                        XpCruiseOrder cruiseOrder = stringR.getData();
                                         // 下发XPU命令
                                         PushOrderDto pushOrderDto = new PushOrderDto();
                                         pushOrderDto.setVin(priorityVin);
-                                        pushOrderDto.setTaskId(orderCheck.getData().getXpuTaskId());
+                                        pushOrderDto.setStartTaskId(orderCheck.getData().getXpuStartTaskId());
+                                        pushOrderDto.setEndTaskId(orderCheck.getData().getXpuEndTaskId());
                                         pushOrderDto.setOrderId(orderCheck.getData().getId().toString());
+                                        pushOrderDto.setStartWaypointId(orderCheck.getData().getStartPointId());
+                                        pushOrderDto.setEndWaypointId(orderCheck.getData().getEndPointId());
                                         pushOrderDto.setStartLatitude(orderCheck.getData().getStartLat());
                                         pushOrderDto.setStartLongitude(orderCheck.getData().getStartLon());
                                         pushOrderDto.setEndLatitude(orderCheck.getData().getEndLat());
@@ -356,12 +1446,21 @@
                                         pushOrderDto.setEndPoiName(orderCheck.getData().getEndPointName());
                                         pushOrderDto.setOrderType(OrderType.USER_ORDER);
                                         pushOrderDto.setStage(1);
+                                        if(null != cruiseOrder){
+                                            pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+                                            pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+                                        }
+                                        pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
                                         log.info("[人车订单绑定测试] XPU推单参数: vin={}, orderId={}, startLat={}, startLon={}, endLat={}, endLon={}, orderNo={}",
                                                 priorityVin, orderCheck.getData().getId(), orderCheck.getData().getStartLat(), orderCheck.getData().getStartLon(),
                                                 orderCheck.getData().getEndLat(), orderCheck.getData().getEndLon(), orderNo);
                                         orderMissionClient.pushOrder(pushOrderDto);
                                         log.info("[人车订单绑定测试] ====== 派单成功! uid={}, vin={}, orderNo={}, 从队列移除订单 ======", uid, priorityVin, orderNo);
-                                        redisService.removeByPattern(quoteName, orderNo);
+
+                                        if(StringUtils.isNotEmpty(quoteName)){
+                                            redisService.removeByPattern(quoteName, orderNo);
+                                        }
+
                                         return true;
                                     } else {
                                         log.info("[人车订单绑定测试] 关闭巡游单失败, 回退常规流程, vin={}, orderNo={}", priorityVin, orderNo);
@@ -397,7 +1496,8 @@
             log.info("[人车订单绑定测试] 总开关未开启(enabled=false), 跳过优先匹配, uid={}, orderNo={}", uid, orderNo);
         }
         // ===== 新增结束 =====
-
+        //根据 用户id 和 城市编码 查询 定向服务的 车辆信息
+        List<String> targetedServiceVehicleVinList = xpTargetedServiceService.findSetVehicleVinByUserIdAndCityCode(xpOrder.getAppUserId(), xpOrder.getCityCode());
         for (int i = 0; i < count; i++) {
             //等到sleepTime秒钟
             Thread.sleep(sleepTime * 1000);
@@ -418,11 +1518,19 @@
             if (vehiclePositionVos.getCode() != 200) {
                 continue;
             }
-            List<VehiclePositionVo> availableVehiclesNearby = BeanUtil.copyToList(positionList, VehiclePositionVo.class);
-            List<String> data = vehiclePositionVos.getData();
+            List<String> data = vehiclePositionVos.getData(); //指定区域的车
+            // 计算交集:指定区域的车辆 与 定向服务车辆列表的交集
+            if (targetedServiceVehicleVinList != null && !targetedServiceVehicleVinList.isEmpty() && data != null) {
+                Collection<String> newVehicleVinList = CollUtil.intersection(data,targetedServiceVehicleVinList);
+                if(CollUtil.isNotEmpty(newVehicleVinList)){
+                    data = (List<String>) newVehicleVinList;
+                }
+            }
 
+            List<VehiclePositionVo> availableVehiclesNearby = BeanUtil.copyToList(positionList, VehiclePositionVo.class);
             // 找出符合条件的
-            availableVehiclesNearby = availableVehiclesNearby.stream().filter(e -> data.contains(e.getVin())).collect(Collectors.toList());
+            List<String> finalData = data;
+            availableVehiclesNearby = availableVehiclesNearby.stream().filter(e -> finalData.contains(e.getVin())).collect(Collectors.toList());
 //            List<VehiclePositionVo> availableVehiclesNearby =vehiclePositionVos.getData();
 
             if (!availableVehiclesNearby.isEmpty()) {
@@ -1000,19 +2108,23 @@
                             continue;
                         }
 
-
+                        String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehiclePosition.getVehicleVin());
                         //  关闭巡游单子
-                        R stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vehiclePosition.getVehicleVin());
+                        R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vin);
                         if (stringR == null || stringR.getCode() != 200) {
                             log.info("关闭巡游单子失败 车牌号 {}", vehiclePosition.getPlateNumber());
                             continue;
                         }
                         log.info("关闭巡游单成功 {} {}", vehiclePosition.getPlateNumber(), orderNo);
+                        XpCruiseOrder cruiseOrder = stringR.getData();
                         // 下发命令
                         PushOrderDto pushOrderDto = new PushOrderDto();
-                        pushOrderDto.setTaskId(xpOrder.getXpuTaskId());
-                        pushOrderDto.setVin(vehiclePosition.getVehicleVin());
+                        pushOrderDto.setStartTaskId(xpOrder.getXpuStartTaskId());
+                        pushOrderDto.setEndTaskId(xpOrder.getXpuEndTaskId());
+                        pushOrderDto.setVin(vin);
                         pushOrderDto.setOrderId(xpOrder.getId().toString());
+                        pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+                        pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
                         pushOrderDto.setStartLatitude(xpOrder.getStartLat());
                         pushOrderDto.setStartLongitude(xpOrder.getStartLon());
                         pushOrderDto.setEndLatitude(xpOrder.getEndLat());
@@ -1020,11 +2132,17 @@
                         pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
                         pushOrderDto.setOrderType(OrderType.USER_ORDER);
                         pushOrderDto.setStage(1);
+                        if(null != cruiseOrder){
+                            pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+                            pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+                        }
+                        pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
                         // 调用推送服务  orderId + carVin
                         orderMissionClient.pushOrder(pushOrderDto);
                         log.info("开始推送 {} 订单到XPU。单号 {}", xpOrder.getOrderNumber(), orderNo);
-
-                        redisService.removeByPattern(quoteName,xpOrder.getOrderNumber());
+                        if(StringUtils.isNotEmpty(quoteName)){
+                            redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+                        }
                         log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
                         return true;
                     } catch (Exception e) {
@@ -1047,6 +2165,7 @@
                             continue;
                         }
                         XpVehicle vehicleId1 = vehicleR.getData();
+                        String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehicleId1.getVehicleVin());
                         log.info("附近只有一个车辆 {} ,直接推单XPU。单号 {}", vehicleId1.getPlateNumber(), orderNo);
                         log.info("当前车辆状态 运营状态 {} 单号 {}", vehicleId1.getState(), orderNo);
                         if (vehicleId1.getOperatingStatus() != 1 || vehicleId1.getState() != 0 || vehicleId1.getVehicleType() == 1) {
@@ -1065,19 +2184,40 @@
                         }
 
                         //  关闭巡游单子
-                        R<?> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vehicleId1.getVehicleVin());
+                        R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vin);
                         if (stringR == null || stringR.getCode() != 200) {
                             log.info("关闭巡游单子失败 车牌号 {}", vehicleId1.getPlateNumber());
                             continue;
                         }
                         log.info("关闭巡游单成功 {} {}", vehicleId1.getPlateNumber(), orderNo);
-                        PushOrderDto pushOrderDto = buildPushOrderDto(xpOrder);
+                        XpCruiseOrder cruiseOrder = stringR.getData();
+                        // 下发命令
+                        PushOrderDto pushOrderDto = new PushOrderDto();
+                        pushOrderDto.setStartTaskId(xpOrder.getXpuStartTaskId());
+                        pushOrderDto.setEndTaskId(xpOrder.getXpuEndTaskId());
                         pushOrderDto.setVin(vehiclePosition.getVin());
-                        pushOrderDto.setTaskId(xpOrder.getXpuTaskId());
+                        pushOrderDto.setOrderId(xpOrder.getId().toString());
+                        pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+                        pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
+                        pushOrderDto.setStartLatitude(xpOrder.getStartLat());
+                        pushOrderDto.setStartLongitude(xpOrder.getStartLon());
+                        pushOrderDto.setEndLatitude(xpOrder.getEndLat());
+                        pushOrderDto.setEndLongitude(xpOrder.getEndLon());
+                        pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
+                        pushOrderDto.setOrderType(OrderType.USER_ORDER);
+                        pushOrderDto.setStage(1);
+                        if(null != cruiseOrder){
+                            pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+                            pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+                        }
+                        pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
                         // 调用推送服务  orderId + carVin
                         orderMissionClient.pushOrder(pushOrderDto);
                         log.info("开始推送 {} 订单到XPU", xpOrder.getOrderNumber());
-                        redisService.popFirstElement(quoteName);
+
+                        if(StringUtils.isNotEmpty(quoteName)){
+                            redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+                        }
                         log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
                         return true;
                     } catch (Exception e) {
@@ -1155,14 +2295,29 @@
                 routeToOrigin.getPolyline().addAll(0, routeRemain.getPolyline());
                 routeToOrigin.setDuration(routeToOrigin.getDuration() + routeRemain.getDuration());
                 routeToOrigin.setDistance(routeToOrigin.getDistance() + routeRemain.getDistance());
-                PushOrderDto pushOrderDto = buildPushOrderDto(xpOrder);
-                pushOrderDto.setVin(xpVehicle.getVehicleVin());
-                pushOrderDto.setTaskId(xpOrder.getXpuTaskId());
-                // 订单流转
-                orderMissionClient.pushOrder(pushOrderDto);
-                redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), xpOrder.getId());
+
+                //此处找到车后先不忙给车推送接单消息,先修改订单上的车辆信息
+                xpOrder.setVehicleId(xpVehicle.getId());
+                xpOrder.setAcceptanceTime(LocalDateTime.now());
+                xpOrder.setStatus(2);
+                xpOrderClient.updateOrder(xpOrder);
+
+//                PushOrderDto pushOrderDto = buildPushOrderDto(xpOrder);
+//                pushOrderDto.setVin(xpVehicle.getVehicleVin());
+//                pushOrderDto.setTaskId(xpOrder.getXpuTaskId());
+//                pushOrderDto.setChainSingle(true);
+//                // 订单流转
+//                orderMissionClient.pushOrder(pushOrderDto);
+                JSONObject jsonObject = new JSONObject();
+                jsonObject.put("orderId", xpOrder.getId());
+                jsonObject.put("endLongitude", xpOrder.getEndLon());
+                jsonObject.put("endLatitude", xpOrder.getEndLat());
+                redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), jsonObject.toJSONString());
                 redisService.setCacheObject(CacheConstants.navigationStart(xpOrder.getAppUserId().toString()), routeToOrigin);
-                redisService.removeByPattern(quoteName,xpOrder.getOrderNumber());
+                if(StringUtils.isNotEmpty(quoteName)){
+                    redisService.removeByPattern(quoteName,xpOrder.getOrderNumber());
+                }
+
                 log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
                 break;
             }
@@ -1170,9 +2325,13 @@
         return false;
     }
 
+
+
     private static PushOrderDto buildPushOrderDto(XpOrder xpOrder) {
         PushOrderDto pushOrderDto = new PushOrderDto();
         pushOrderDto.setOrderId(xpOrder.getId().toString());
+        pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+        pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
         pushOrderDto.setStartLatitude(xpOrder.getStartLat());
         pushOrderDto.setStartLongitude(xpOrder.getStartLon());
         pushOrderDto.setEndLatitude(xpOrder.getEndLat());
@@ -1228,6 +2387,10 @@
         XpOrderReassign entity = new XpOrderReassign(data.getId(),data.getVehicleId(),data.getFleetId(),longitude,latitude,"接驾故障");
         entity.setIsComplete(false);
         entity.setAppUserId(Long.valueOf(uid));
+
+        // 根据城市编码获取 定向服务设置的车辆
+        List<String> targetedServiceVehicleVinList = xpTargetedServiceService.findSetVehicleVinByUserIdAndCityCode(data.getAppUserId(), data.getCityCode());
+
         //循环找车
         for (int i = 0; i < count; i++) {
             log.info("进入找车环节");
@@ -1302,19 +2465,29 @@
                     routeToOrigin.getPolyline().addAll(0, routeRemain.getPolyline());
                     routeToOrigin.setDuration(routeToOrigin.getDuration() + routeRemain.getDuration());
                     routeToOrigin.setDistance(routeToOrigin.getDistance() + routeRemain.getDistance());
-                    PushOrderDto pushOrderDto = buildPushOrderDto(data);
-                    pushOrderDto.setVin(xpVehicle.getVehicleVin());
-                    // 订单流转
-                    orderMissionClient.pushOrder(pushOrderDto);
-                    redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), data.getId());
+                    JSONObject jsonObject = new JSONObject();
+                    jsonObject.put("orderId", data.getId());
+                    jsonObject.put("endLongitude", data.getEndLon());
+                    jsonObject.put("endLatitude", data.getEndLat());
+                    redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), jsonObject.toJSONString());
                     redisService.setCacheObject(CacheConstants.navigationStart(data.getAppUserId().toString()), routeToOrigin);
                     break;
                 }
             }
 
+
             // 直接派单  定义一个锁来锁定车辆
             VehiclePosition vehiclePosition = positionList.get(0);
+            if(CollUtil.isNotEmpty(targetedServiceVehicleVinList)){//定向服务获取的车
+                for (VehiclePosition position : positionList) {
+                    if(targetedServiceVehicleVinList.contains(position.getVin())){
+                        vehiclePosition = position;
+                        break;
+                    }
+                }
+            }
             String vehicleVin = vehiclePosition.getVin();
+
 
             RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePosition.getVin());
             lock.lock(10, TimeUnit.SECONDS);
@@ -1330,16 +2503,20 @@
                     continue;
                 }
                 //  关闭巡游单子
-                R<?> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vehicleId1.getVehicleVin());
+                R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vehicleId1.getVehicleVin());
                 if (stringR == null || stringR.getData() == null) {
                     log.info("关闭巡游单子失败");
                     continue;
                 }
+                XpCruiseOrder cruiseOrder = stringR.getData();
 
                 PushOrderDto pushOrderDto = new PushOrderDto();
-                pushOrderDto.setTaskId(data.getXpuTaskId());
+                pushOrderDto.setStartTaskId(data.getXpuStartTaskId());
+                pushOrderDto.setEndTaskId(data.getXpuEndTaskId());
                 pushOrderDto.setVin(vehiclePosition.getVin());
                 pushOrderDto.setOrderId(data.getId().toString());
+                pushOrderDto.setStartWaypointId(data.getStartPointId());
+                pushOrderDto.setEndWaypointId(data.getEndPointId());
                 pushOrderDto.setStartLatitude(data.getStartLat());
                 pushOrderDto.setStartLongitude(data.getStartLon());
                 pushOrderDto.setEndLatitude(data.getEndLat());
@@ -1347,15 +2524,19 @@
                 pushOrderDto.setEndPoiName(data.getEndPointName());
                 pushOrderDto.setOrderType(OrderType.USER_ORDER);
                 pushOrderDto.setStage(1);
+                if(null != cruiseOrder){
+                    pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+                    pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+                }
+                pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
                 // 调用推送服务  orderId + carVin
                 orderMissionClient.pushOrder(pushOrderDto);
-
                 entity.setNewVehicleId(vehicleId1.getId());
                 entity.setNewFleetId(vehicleId1.getFleetId());
                 entity.setIsComplete(true);
 //                //接单成功 将 修改 订单的状态=1 ( 状态 0=已取消,1=待接单,2=待出发,3=接驾中,4=待客上车,5=乘客已上车,6=服务中,7=待客下车,8=待付款,9=待评价,10=已完成)
 //                orderCarStatus = true;
-                xpOrderClient.updateOrderStatus(data.getId(), OrderStatusEnum.PENDING_ORDER.getCode(), false);
+                xpOrderClient.updateOrderStatus(data.getId(), OrderStatusEnum.PENDING_ORDER.getCode());
                 redisService.setCacheObject("ORDER_STATUS:" + data.getId(), OrderStatusEnum.PENDING_ORDER.getCode(), 24L, TimeUnit.HOURS);
 
                 break;

--
Gitblit v1.7.1