“mitao”
2026-04-13 99b4c0f1bd527eede3753c805d6006ceb92faa4a
fix:订单改派异常修改
2个文件已修改
70 ■■■■■ 已修改文件
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -290,8 +290,16 @@
        if (mqttPublishDto.getCode() == 200) {
            if(!dto.getOrderId().contains("XU")){
                // 正常订单处理
                redisService.setCacheObject(String.valueOf(sequence), "cancelOrder_" + dto.getOrderId() + "_" + dto.getVin(), 30l, TimeUnit.MINUTES);
                Map<String, Object> cancelContext = new HashMap<>();
                cancelContext.put("orderId", dto.getOrderId());
                cancelContext.put("vin", dto.getVin());
                cancelContext.put("cancelScene", StringUtils.isNotEmpty(dto.getCancelScene())
                        ? dto.getCancelScene()
                        : CancelOrderSceneEnum.NORMAL_CANCEL.getCode());
                redisService.setCacheObject("CANCEL_ORDER_CONTEXT:" + taskId,
                        JSONObject.toJSONString(cancelContext), 30L, TimeUnit.MINUTES);
                log.info("记录取消订单上下文成功,orderId: {}, vin: {}, taskId: {}, cancelScene: {}",
                        dto.getOrderId(), dto.getVin(), taskId, cancelContext.get("cancelScene"));
            }
            return R.ok(true);
        }
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -73,6 +73,7 @@
@Service
public class KafkaConsumerService {
    private static final String REASSIGN_CANCEL_CONTEXT_PREFIX = "REASSIGN_CANCEL_CONTEXT:";
    private static final String CANCEL_ORDER_CONTEXT_PREFIX = "CANCEL_ORDER_CONTEXT:";
    @Resource
@@ -1387,6 +1388,10 @@
        }
    }
    /**
     * 兼容按订单维度缓存的改派取消上下文。
     * 该键在历史实现中使用,保留读取能力避免线上旧数据失效。
     */
    private JSONObject getReassignCancelContext(String orderId) {
        if (StringUtils.isEmpty(orderId)) {
            return null;
@@ -1398,40 +1403,59 @@
        return JSON.parseObject(cacheObject.toString());
    }
    /**
     * 当前 cancelOrder 指令是按 taskId 记录取消上下文。
     * 改派旧车取消回调优先读取该上下文,避免依赖订单当前车/状态造成竞态误判。
     */
    private JSONObject getCancelOrderContext(String taskId) {
        if (StringUtils.isEmpty(taskId)) {
            return null;
        }
        Object cacheObject = redisService.getCacheObject(CANCEL_ORDER_CONTEXT_PREFIX + taskId);
        if (cacheObject == null) {
            return null;
        }
        return JSON.parseObject(cacheObject.toString());
    }
    private JSONObject resolveReassignCancelContext(String orderId, OrderStatusInfo orderStatusInfo) {
        if (OrderStateChangeSource.ORDER_STATE_CHANGE_SOURCE_VEHICLE != orderStatusInfo.getChangeSource()) {
            return null;
        }
        JSONObject cancelContext = getReassignCancelContext(orderId);
        String taskId = orderStatusInfo.getTaskId();
        // 先按 taskId 读取当前生效的取消上下文,再兼容历史按 orderId 存储的改派上下文。
        JSONObject cancelContext = getCancelOrderContext(taskId);
        if (cancelContext == null) {
            cancelContext = getReassignCancelContext(orderId);
        }
        if (cancelContext == null) {
            log.info("改派取消回调未命中专用上下文,orderId: {}, taskId: {}, missReason: context_not_found",
                    orderId, taskId);
            return null;
        }
        if (CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE != CancelOrderSceneEnum.fromCode(
                cancelContext.getString("cancelScene"))) {
        String cancelScene = cancelContext.getString("cancelScene");
        if (CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE != CancelOrderSceneEnum.fromCode(cancelScene)) {
            log.info("改派取消回调未命中专用上下文,orderId: {}, taskId: {}, missReason: scene_not_match, cancelScene: {}, context: {}",
                    orderId, taskId, cancelScene, cancelContext);
            return null;
        }
        R<XpOrder> orderResult = xpOrderClient.queryOrderById(Long.parseLong(orderId));
        XpOrder xpOrder = orderResult == null ? null : orderResult.getData();
        if (xpOrder == null) {
            log.warn("改派取消回调识别失败,订单不存在,orderId: {}, context: {}", orderId, cancelContext);
        String contextOrderId = cancelContext.getString("orderId");
        if (StringUtils.isNotEmpty(contextOrderId) && !Objects.equals(contextOrderId, orderId)) {
            log.info("改派取消回调未命中专用上下文,orderId: {}, taskId: {}, missReason: order_not_match, contextOrderId: {}, context: {}",
                    orderId, taskId, contextOrderId, cancelContext);
            return null;
        }
        Long newVehicleId = cancelContext.getLong("newVehicleId");
        Integer currentStatus = xpOrder.getStatus();
        boolean vehicleMatched = Objects.nonNull(newVehicleId) && Objects.equals(newVehicleId, xpOrder.getVehicleId());
        boolean statusMatched = Objects.nonNull(currentStatus) && currentStatus > 0 && currentStatus < 8;
        if (vehicleMatched && statusMatched) {
            return cancelContext;
        }
        log.info("改派取消回调未命中专用上下文,orderId: {}, currentVehicleId: {}, newVehicleId: {}, currentStatus: {}",
                orderId, xpOrder.getVehicleId(), newVehicleId, currentStatus);
        return null;
        return cancelContext;
    }
    private String resolveReassignCancelResponseVin(JSONObject cancelContext) {
        if (cancelContext == null) {
            return null;
        }
        String vin = cancelContext.getString("vin");
        if (StringUtils.isNotEmpty(vin)) {
            return vin;
        }
        String oldVehicleVin = cancelContext.getString("oldVehicleVin");
        if (StringUtils.isNotEmpty(oldVehicleVin)) {
            return oldVehicleVin;