puzhibing
2026-04-10 ed838e62602c0a63a64ff4bd144a0d16cc9a7cf8
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -7,13 +7,11 @@
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.operation.VehiclePositionByVinDto;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto;
import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.model.operation.XpTradingStrategy;
@@ -23,7 +21,6 @@
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.api.vo.operation.VehiclePositionVo;
import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.constant.Constants;
import com.xiaopeng.common.core.domain.R;
@@ -32,12 +29,14 @@
import com.xiaopeng.operation.service.IXpElectronicFenceAreaService;
import com.xiaopeng.operation.service.IXpTradingStrategyService;
import com.xiaopeng.operation.service.XpPointService;
import com.xiaopeng.operation.config.UidVinBindingConfig;
import com.xiaopeng.operation.dto.PriorityMatchResult;
import com.xiaopeng.operation.service.UidVinPriorityMatcher;
import com.xiaopeng.operation.utils.mango.VehiclePositionService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
@@ -92,6 +91,12 @@
    @Resource
    private XpElectronicFenceMapper xpElectronicFenceMapper;
    @Resource
    private UidVinBindingConfig uidVinBindingConfig;
    @Resource
    private UidVinPriorityMatcher uidVinPriorityMatcher;
    // 自定义线程池
@@ -214,7 +219,7 @@
        if (xpOrderR.getCode() == 200) {
            XpOrder xpOrder = xpOrderR.getData();
            if (xpOrder.getStatus() == 1) {
                log.error("五轮推单结束,无车辆接单,执行取消订单 {}", orderNo);
                log.info("五轮推单结束,无车辆接单,执行取消订单 {}", orderNo);
                xpOrderClient.cancelOrder(orderId);
                //推送订单状态给乘客
                SendMessageDTO dto = new SendMessageDTO();
@@ -280,6 +285,101 @@
        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();
                            log.info("[人车订单绑定测试] 二次校验-车辆状态: operatingStatus={}, state={}, vehicleType={}, vin={}",
                                    vehicle.getOperatingStatus(), vehicle.getState(), vehicle.getVehicleType(), priorityVin);
                            if (vehicle.getOperatingStatus() == 1 && vehicle.getState() == 0 && vehicle.getVehicleType() != 1) {
                                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.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);
                                        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秒钟
@@ -396,7 +496,7 @@
                            }
                            if (max1.equals(weightDistance)) {
                                log.info("车子距离~~");
                                for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
                                    RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
                                    LonLatDto lonLatDto = new LonLatDto();
@@ -413,6 +513,7 @@
                                    //  调用地图 获取时间
                                    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);
@@ -898,6 +999,7 @@
                        pushOrderDto.setStartLongitude(xpOrder.getStartLon());
                        pushOrderDto.setEndLatitude(xpOrder.getEndLat());
                        pushOrderDto.setEndLongitude(xpOrder.getEndLon());
                        pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
                        pushOrderDto.setOrderType(OrderType.USER_ORDER);
                        pushOrderDto.setStage(1);
                        // 调用推送服务  orderId + carVin
@@ -928,7 +1030,7 @@
                        }
                        XpVehicle vehicleId1 = vehicleR.getData();
                        log.info("附近只有一个车辆 {} ,直接推单XPU。单号 {}", vehicleId1.getPlateNumber(), orderNo);
                        log.info("当前车辆状态 {} 运营状态 {} 单号 {}", vehicleId1.getOperatingStatus(), vehicleId1.getState(), orderNo);
                        log.info("当前车辆状态 运营状态 {} 单号 {}", vehicleId1.getState(), orderNo);
                        if (vehicleId1.getOperatingStatus() != 1 || vehicleId1.getState() != 0 || vehicleId1.getVehicleType() == 1) {
                            continue;
                        }
@@ -958,6 +1060,7 @@
                        pushOrderDto.setStartLongitude(xpOrder.getStartLon());
                        pushOrderDto.setEndLatitude(xpOrder.getEndLat());
                        pushOrderDto.setEndLongitude(xpOrder.getEndLon());
                        pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
                        pushOrderDto.setOrderType(OrderType.USER_ORDER);
                        pushOrderDto.setStage(1);
                        // 调用推送服务  orderId + carVin
@@ -1042,6 +1145,7 @@
                pushOrderDto.setStartLongitude(data.getStartLon());
                pushOrderDto.setEndLatitude(data.getEndLat());
                pushOrderDto.setEndLongitude(data.getEndLon());
                pushOrderDto.setEndPoiName(data.getEndPointName());
                pushOrderDto.setOrderType(OrderType.USER_ORDER);
                pushOrderDto.setStage(1);
                // 调用推送服务  orderId + carVin