From b6f3de8451867d85242b2bd706fcfa4a65df4ff7 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期六, 11 四月 2026 02:46:30 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi

---
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderPageVO.java                               |    7 +
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/exportExcel/XpOrderExportExcel.java                 |    4 
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java         |   30 ++++++
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/ElectronicEffectJob.java                             |   10 -
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java                         |   11 +-
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java                      |   23 ++++
 xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java                      |    3 
 xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java      |   85 ++++++++++++-----
 xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java |   12 --
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/schedule/ElectronicFenceFailureCompensationTask.java          |   81 ++++++++++++++++
 10 files changed, 214 insertions(+), 52 deletions(-)

diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
index c8612f4..7806135 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -290,16 +290,8 @@
 
         if (mqttPublishDto.getCode() == 200) {
             if(!dto.getOrderId().contains("XU")){
-                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"));
+                // 正常订单处理
+                redisService.setCacheObject(String.valueOf(sequence), "cancelOrder_" + dto.getOrderId() + "_" + dto.getVin(), 30l, TimeUnit.MINUTES);
             }
             return R.ok(true);
         }
diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
index b79d9e2..468af59 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -72,7 +72,7 @@
 @Slf4j
 @Service
 public class KafkaConsumerService {
-    private static final String CANCEL_ORDER_CONTEXT_PREFIX = "CANCEL_ORDER_CONTEXT:";
+    private static final String REASSIGN_CANCEL_CONTEXT_PREFIX = "REASSIGN_CANCEL_CONTEXT:";
 
 
     @Resource
@@ -1166,12 +1166,18 @@
                     //已取消
                     if(!orderId.contains("XU")){
                         String taskId = orderStatusInfo.getTaskId();
-                        JSONObject cancelContext = getCancelOrderContext(taskId);
-                        if (shouldSkipCancelForReassign(cancelContext)) {
+                        JSONObject reassignCancelContext = resolveReassignCancelContext(orderId, orderStatusInfo);
+                        if (Objects.nonNull(reassignCancelContext)) {
                             log.info("改派旧车取消回调,跳过订单取消处理,orderId: {}, taskId: {}, cancelScene: {}, context: {}",
-                                    orderId, taskId, cancelContext.getString("cancelScene"), cancelContext);
+                                    orderId, taskId, reassignCancelContext.getString("cancelScene"), reassignCancelContext);
                             //响应消息
-                            responseMessage(sequence, cancelContext.getString("vin"));
+                            String responseVin = resolveReassignCancelResponseVin(reassignCancelContext);
+                            if (StringUtils.isNotEmpty(responseVin)) {
+                                responseMessage(sequence, responseVin);
+                            } else {
+                                log.warn("改派旧车取消回调未找到响应VIN,orderId: {}, taskId: {}, context: {}",
+                                        orderId, taskId, reassignCancelContext);
+                            }
                             return;
                         }
                         if(orderId.contains("TEST")){
@@ -1212,11 +1218,11 @@
                                 //行程中取消订单,按照行程结束处理
                                 buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence);
                                 xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode());
-                                redisService.setCacheObject("ORDER_STATUS:" + orderId.substring(4), OrderStatusEnum.SEE_OFF_GUESTS.getCode(), 24L, TimeUnit.HOURS);
+                                redisService.setCacheObject("ORDER_STATUS:" + orderId, OrderStatusEnum.SEE_OFF_GUESTS.getCode(), 24L, TimeUnit.HOURS);
                             }else{
                                 buildPushOrderStatus(orderId, OrderStatusEnum.CANCELED, sequence);
                                 xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.CANCELED.getCode());
-                                redisService.setCacheObject("ORDER_STATUS:" + orderId.substring(4), OrderStatusEnum.CANCELED.getCode(), 24L, TimeUnit.HOURS);
+                                redisService.setCacheObject("ORDER_STATUS:" + orderId, OrderStatusEnum.CANCELED.getCode(), 24L, TimeUnit.HOURS);
                             }
                         }
                     }
@@ -1381,33 +1387,62 @@
         }
     }
 
-    /**
-     * 根据taskId获取订单取消的上下文信息
-     * @param taskId
-     * @return
-     */
-    private JSONObject getCancelOrderContext(String taskId) {
-        if (StringUtils.isEmpty(taskId)) {
+    private JSONObject getReassignCancelContext(String orderId) {
+        if (StringUtils.isEmpty(orderId)) {
             return null;
         }
-        Object cacheObject = redisService.getCacheObject(CANCEL_ORDER_CONTEXT_PREFIX + taskId);
+        Object cacheObject = redisService.getCacheObject(REASSIGN_CANCEL_CONTEXT_PREFIX + orderId);
         if (cacheObject == null) {
             return null;
         }
         return JSON.parseObject(cacheObject.toString());
     }
 
-    /**
-     * 判断是否是改派旧车取消回调,是则跳过订单取消处理
-     * @param cancelContext
-     * @return
-     */
-    private boolean shouldSkipCancelForReassign(JSONObject cancelContext) {
-        if (cancelContext == null) {
-            return false;
+    private JSONObject resolveReassignCancelContext(String orderId, OrderStatusInfo orderStatusInfo) {
+        if (OrderStateChangeSource.ORDER_STATE_CHANGE_SOURCE_VEHICLE != orderStatusInfo.getChangeSource()) {
+            return null;
         }
-        return CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE == CancelOrderSceneEnum.fromCode(
-                cancelContext.getString("cancelScene"));
+        JSONObject cancelContext = getReassignCancelContext(orderId);
+        if (cancelContext == null) {
+            return null;
+        }
+        if (CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE != CancelOrderSceneEnum.fromCode(
+                cancelContext.getString("cancelScene"))) {
+            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);
+            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;
+    }
+
+    private String resolveReassignCancelResponseVin(JSONObject cancelContext) {
+        if (cancelContext == null) {
+            return null;
+        }
+        String oldVehicleVin = cancelContext.getString("oldVehicleVin");
+        if (StringUtils.isNotEmpty(oldVehicleVin)) {
+            return oldVehicleVin;
+        }
+        Long oldVehicleId = cancelContext.getLong("oldVehicleId");
+        if (Objects.isNull(oldVehicleId)) {
+            return null;
+        }
+        R<XpVehicle> vehicleResult = xpVehicleClient.queryById(oldVehicleId);
+        XpVehicle xpVehicle = vehicleResult == null ? null : vehicleResult.getData();
+        return xpVehicle == null ? null : xpVehicle.getVehicleVin();
     }
 
     /**
diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java
index 2fdfcc3..b53bc0a 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java
@@ -8,6 +8,7 @@
 import com.xiaopeng.api.feignClient.automaticPilot.XPUClient;
 import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo;
 import com.xiaopeng.api.vo.automaticPilot.protobuf.*;
+import com.xiaopeng.common.core.exception.ServiceException;
 import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.core.utils.uuid.UUID;
 import lombok.extern.slf4j.Slf4j;
@@ -210,7 +211,7 @@
         log.info("getMqttPublishTopic vin,{},xpuIdMapping,{}", vin,  JSON.toJSONString(xpuIdMapping));
         if (xpuIdMapping == null || StringUtils.isEmpty(xpuIdMapping.get(XPU_ID_TYPE)) ) {
             log.error("根据vin查询车辆xpuid信息为空,vin={}", vin);
-            throw new RuntimeException("根据vin查询车辆xpuid信息为空");
+            throw new ServiceException("根据vin查询车辆xpuid信息为空");
         }
         return xpuIdMapping.get(XPU_ID_TYPE);
     }
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/ElectronicEffectJob.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/ElectronicEffectJob.java
index 6b02e45..58ce357 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/ElectronicEffectJob.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/job/jobs/ElectronicEffectJob.java
@@ -41,15 +41,7 @@
 				xpElectronicFenceAreaService.updateBatchById(electronicFenceAreaList);
 			}else{
 				// 电子围栏失效
-				XpElectronicFence electronicFence = xpElectronicFenceService.getById(electronicId);
-				electronicFence.setStatus(3);
-				xpElectronicFenceService.updateById(electronicFence);
-				List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery().eq(XpElectronicFenceArea::getElectronicId, electronicId).list();
-				// 设置为禁用
-				for(XpElectronicFenceArea electronicFenceArea : electronicFenceAreaList){
-					electronicFenceArea.setAreaStatus(2);
-				}
-				xpElectronicFenceAreaService.updateBatchById(electronicFenceAreaList);
+				xpElectronicFenceService.expireFence(electronicId);
 			}
 
 		}catch(Exception e){
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/schedule/ElectronicFenceFailureCompensationTask.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/schedule/ElectronicFenceFailureCompensationTask.java
new file mode 100644
index 0000000..c05b9a1
--- /dev/null
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/schedule/ElectronicFenceFailureCompensationTask.java
@@ -0,0 +1,81 @@
+package com.xiaopeng.map.schedule;
+
+import com.xiaopeng.api.model.operation.XpElectronicFence;
+import com.xiaopeng.map.service.XpElectronicFenceService;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * 电子围栏失效补偿定时任务
+ */
+@Slf4j
+@Component
+public class ElectronicFenceFailureCompensationTask {
+
+    private static final String LOCK_KEY = "MAP:ELECTRONIC_FENCE:FAILURE_COMPENSATE";
+    private static final int LOCK_WAIT_SECONDS = 0;
+    private static final int LOCK_LEASE_SECONDS = 15;
+
+    @Resource
+    private XpElectronicFenceService xpElectronicFenceService;
+
+    @Resource
+    private RedissonClient redissonClient;
+
+    @Scheduled(fixedDelay = 10 * 1000L)
+    public void compensateExpiredFence() {
+        RLock lock = redissonClient.getLock(LOCK_KEY);
+        boolean locked = false;
+        try {
+            locked = lock.tryLock(LOCK_WAIT_SECONDS, LOCK_LEASE_SECONDS, TimeUnit.SECONDS);
+            if (!locked) {
+                return;
+            }
+
+            LocalDateTime now = LocalDateTime.now();
+            List<XpElectronicFence> expiredFenceList = xpElectronicFenceService.lambdaQuery()
+                    .eq(XpElectronicFence::getFailureType, 2)
+                    .le(XpElectronicFence::getFailureTime, now)
+                    .in(XpElectronicFence::getStatus, 1, 2)
+                    .list();
+            if (expiredFenceList == null || expiredFenceList.isEmpty()) {
+                return;
+            }
+
+            List<Long> electronicIds = expiredFenceList.stream()
+                    .map(XpElectronicFence::getId)
+                    .collect(Collectors.toList());
+            log.info("电子围栏失效补偿开始, count={}, ids={}", electronicIds.size(), electronicIds);
+            for (Long electronicId : electronicIds) {
+                try {
+                    xpElectronicFenceService.expireFence(electronicId);
+                } catch (Exception e) {
+                    log.error("电子围栏失效补偿单条处理异常, electronicId={}", electronicId, e);
+                }
+            }
+            log.info("电子围栏失效补偿完成, count={}, ids={}", electronicIds.size(), electronicIds);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            log.warn("电子围栏失效补偿任务获取锁被中断", e);
+        } catch (Exception e) {
+            log.error("电子围栏失效补偿任务执行异常", e);
+        } finally {
+            try {
+                if (locked && lock.isHeldByCurrentThread()) {
+                    lock.unlock();
+                }
+            } catch (Exception e) {
+                log.warn("释放电子围栏失效补偿锁失败 lockKey={}", LOCK_KEY, e);
+            }
+        }
+    }
+}
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java
index 2efed47..b58fc71 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java
@@ -37,9 +37,10 @@
      * @return
      */
     List<XpElectronicFence> getList();
+
+    /**
+     * 将围栏置为已停用,并同步禁用围栏区域
+     * @param electronicId 围栏ID
+     */
+    void expireFence(Long electronicId);
 }
-
-
-
-
-
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
index 142918b..a54e6b9 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -958,6 +958,36 @@
         return list();
     }
 
+    @Override
+    @Transactional
+    @ShardingSphereTransactionType(TransactionType.BASE)
+    public void expireFence(Long electronicId) {
+        if (electronicId == null) {
+            return;
+        }
+        XpElectronicFence electronicFence = this.getById(electronicId);
+        if (electronicFence == null || electronicFence.getStatus() == null) {
+            return;
+        }
+        Integer status = electronicFence.getStatus();
+        if (status != 1 && status != 2) {
+            return;
+        }
+        electronicFence.setStatus(3);
+        this.updateById(electronicFence);
+
+        List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery()
+                .eq(XpElectronicFenceArea::getElectronicId, electronicId)
+                .list();
+        if (CollUtil.isEmpty(electronicFenceAreaList)) {
+            return;
+        }
+        for (XpElectronicFenceArea electronicFenceArea : electronicFenceAreaList) {
+            electronicFenceArea.setAreaStatus(2);
+        }
+        xpElectronicFenceAreaService.updateBatchById(electronicFenceAreaList);
+    }
+
 
     /**
      * 计算围栏中心点
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/exportExcel/XpOrderExportExcel.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/exportExcel/XpOrderExportExcel.java
index 8656765..8e0cf84 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/exportExcel/XpOrderExportExcel.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/exportExcel/XpOrderExportExcel.java
@@ -43,11 +43,11 @@
 
     @ApiModelProperty(value = "起点")
     @Excel(name = "起点", width = 30)
-    private String startAddress;
+    private String startPointName;
 
     @ApiModelProperty(value = "终点")
     @Excel(name = "终点", width = 30)
-    private String endAddress;
+    private String endPointName;
 
     @ApiModelProperty(value = "选择车型")
     @Excel(name = "选择车型", width = 15)
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderPageVO.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderPageVO.java
index 80aa692..a035113 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderPageVO.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderPageVO.java
@@ -1,5 +1,6 @@
 package com.xiaopeng.order.model.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -59,4 +60,10 @@
     private BigDecimal orderMoney;
     @ApiModelProperty(value = "状态 0=已取消,1=待接单,2=待出发,3=接驾中,4=待客上车,5=乘客已上车,6=服务中,7=待客下车,8=待付款,9=待评价,10=已完成")
     private Integer status;
+
+    @ApiModelProperty(value = "下单站点名称")
+    private String startPointName;
+
+    @ApiModelProperty(value = "下单终点站点名称")
+    private String endPointName;
 }
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
index d2d3593..5b555cc 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -137,6 +137,9 @@
 @RequiredArgsConstructor(onConstructor_ = @Lazy)
 public class XpOrderServiceImpl extends ServiceImpl<XpOrderMapper, XpOrder> implements IXpOrderService {
 
+    private static final String REASSIGN_CANCEL_CONTEXT_PREFIX = "REASSIGN_CANCEL_CONTEXT:";
+    private static final long REASSIGN_CANCEL_CONTEXT_TTL_MINUTES = 5L;
+
     private final UserResourcesClient userResourcesClient;
     private final XpPointClient xpPointClient;
     private final XpVehicleClient xpVehicleClient;
@@ -591,6 +594,8 @@
         vo.setEndAddress(order.getEndAddress());
         vo.setOrderMoney(order.getOrderMoney());
         vo.setStatus(order.getStatus());
+        vo.setStartPointName(order.getStartPointName());
+        vo.setEndPointName(order.getEndPointName());
 
         // 用户信息
         if (Objects.nonNull(order.getAppUserId()) && userInfoMap != null && userInfoMap.containsKey(order.getAppUserId().toString())) {
@@ -969,6 +974,8 @@
                     cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
                     cancelDto.setCancelScene(CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE.getCode());
                     orderMissionClient.cancelOrder(cancelDto);
+                    cacheReassignCancelContext(orderId, oldVehicleId, newVehicleId,
+                            oldVehicle.getVehicleVin(), currentStatus);
                     log.info("已取消原车辆订单指令,订单ID: {}, VIN: {}, taskId: {}, cancelScene: {}",
                             orderId, oldVehicle.getVehicleVin(), cancelDto.getTaskId(), cancelDto.getCancelScene());
 
@@ -1113,6 +1120,22 @@
 
     }
 
+    private void cacheReassignCancelContext(Long orderId, Long oldVehicleId, Long newVehicleId,
+                                            String oldVehicleVin, Integer preReassignStatus) {
+        JSONObject context = new JSONObject();
+        context.put("orderId", orderId);
+        context.put("oldVehicleId", oldVehicleId);
+        context.put("newVehicleId", newVehicleId);
+        context.put("oldVehicleVin", oldVehicleVin);
+        context.put("cancelScene", CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE.getCode());
+        context.put("operationTime", System.currentTimeMillis());
+        context.put("preReassignStatus", preReassignStatus);
+        redisService.setCacheObject(REASSIGN_CANCEL_CONTEXT_PREFIX + orderId, context.toJSONString(),
+                REASSIGN_CANCEL_CONTEXT_TTL_MINUTES, TimeUnit.MINUTES);
+        log.info("记录改派取消上下文成功,orderId: {}, oldVehicleId: {}, newVehicleId: {}, preReassignStatus: {}",
+                orderId, oldVehicleId, newVehicleId, preReassignStatus);
+    }
+
     /**
      * 为原车辆创建返程巡游订单
      * <p>

--
Gitblit v1.7.1