liujie
2026-06-09 c96fbe6b0aeb413a17c429133ee6d81d138144b9
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;