From eecc2a5240a4b9389d8396d36624055da808ad9b Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期六, 28 二月 2026 11:40:01 +0800
Subject: [PATCH] feat(management):订单改派逻辑完善、收车定时任务逻辑完善

---
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java |  175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 170 insertions(+), 5 deletions(-)

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 6c98b1e..850e44b 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
@@ -511,7 +511,20 @@
         orderCancel.setCancelReason("运营人员取消订单");
         orderCancel.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
         xpOrderCancelService.save(orderCancel);
-
+        //查询车辆信息
+        R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(order.getId());
+        if (xpVehicleR.getCode() == HttpStatus.SUCCESS && Objects.nonNull(xpVehicleR.getData())) {
+            // 下发命令
+            if (order.getStatus() > 1) {
+                PushOrderDto pushOrderDto = new PushOrderDto();
+                pushOrderDto.setOrderId(order.getId().toString());
+                pushOrderDto.setVin(xpVehicleR.getData().getVehicleVin());
+                pushOrderDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
+                orderMissionClient.cancelOrder(pushOrderDto);
+            }
+        } else {
+            log.info("查询车辆信息失败,订单ID: {}, 下发取消订单命令失败", order.getId());
+        }
         log.info("订单取消成功,订单ID: {}, 操作人: {}", order.getId(), SecurityUtils.getUsername());
     }
 
@@ -538,10 +551,10 @@
             throw new ServiceException("订单不存在");
         }
 
-        // 2. 校验订单状态(只有待接单、待出发、接驾中状态可以改派)
+        // 2. 校验订单状态(只有待出发、接驾中、待乘客上车状态可以改派)
         Integer currentStatus = order.getStatus();
-        if (currentStatus != 1 && currentStatus != 2 && currentStatus != 3) {
-            throw new ServiceException("当前订单状态不允许改派,只有待接单、待出发、接驾中状态的订单可以改派", I18nKeyConstant.ORDER_REASSIGN_FAILED);
+        if (currentStatus != 2 && currentStatus != 3 && currentStatus != 4) {
+            throw new ServiceException("当前订单状态不允许改派,只有待出发、接驾中、待乘客上车状态的订单可以改派", I18nKeyConstant.ORDER_REASSIGN_FAILED);
         }
 
         // 3. 校验新旧车辆是否相同
@@ -580,6 +593,47 @@
         // 6. 保存原车辆和车队信息
         Long oldVehicleId = order.getVehicleId();
         Long oldFleetId = order.getFleetId();
+
+        // 6.1 处理原车辆:取消订单指令、解绑乘客、更新状态、创建返程巡游订单
+        if (Objects.nonNull(oldVehicleId)) {
+            try {
+                R<XpVehicle> oldVehicleResult = xpVehicleClient.queryById(oldVehicleId);
+                if (oldVehicleResult != null && oldVehicleResult.getCode() == HttpStatus.SUCCESS && oldVehicleResult.getData() != null) {
+                    XpVehicle oldVehicle = oldVehicleResult.getData();
+
+                    // 6.1.1 取消原订单指令
+                    PushOrderDto cancelDto = new PushOrderDto();
+                    cancelDto.setOrderId(order.getId().toString());
+                    cancelDto.setVin(oldVehicle.getVehicleVin());
+                    cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
+                    orderMissionClient.cancelOrder(cancelDto);
+                    log.info("已取消原车辆订单指令,订单ID: {}, VIN: {}", orderId, oldVehicle.getVehicleVin());
+
+                    // 6.1.2 解绑乘客与原车辆关系
+                    if (Objects.nonNull(order.getAppUserId())) {
+                        CancelTaxiPassengerVo cancelVo = new CancelTaxiPassengerVo();
+                        cancelVo.setVin(oldVehicle.getVehicleVin());
+                        cancelVo.setUid(order.getAppUserId().toString());
+                        cancelVo.setOrderNo(order.getOrderNumber());
+                        cancelVo.setAppId("");
+                        userVehicleClient.cancelTaxiPassenger(cancelVo);
+                        log.info("已解绑乘客与原车辆关系,用户ID: {}, VIN: {}", order.getAppUserId(), oldVehicle.getVehicleVin());
+                    }
+
+                    // 6.1.3 修改原车辆状态为空闲
+                    oldVehicle.setState(0);
+                    xpVehicleClient.updateVehicleById(oldVehicle);
+                    log.info("已将原车辆状态设为空闲,车辆ID: {}", oldVehicleId);
+
+                    // 6.1.4 为原车辆创建返程巡游订单
+                    createReturnCruiseOrder(oldVehicle, order);
+                } else {
+                    log.warn("查询原车辆信息失败,车辆ID: {}", oldVehicleId);
+                }
+            } catch (Exception e) {
+                log.error("处理原车辆失败,车辆ID: {},错误: {}", oldVehicleId, e.getMessage());
+            }
+        }
 
         // 7. 查询新车辆关联的车队ID
         Long newFleetId = null;
@@ -634,7 +688,118 @@
 
         log.info("订单改派成功,订单ID: {}, 原车辆ID: {}, 新车辆ID: {}, 原车队ID: {}, 新车队ID: {}, 操作人: {}",
                 orderId, oldVehicleId, newVehicleId, oldFleetId, newFleetId, SecurityUtils.getUsername());
-        //推送消息
+
+        // 11. 处理新车辆:绑定乘客、下发订单、更新状态
+        try {
+            // 11.1 绑定乘客与新车辆关系
+            if (Objects.nonNull(order.getAppUserId())) {
+                AddTaxiPassengerVo addVo = new AddTaxiPassengerVo();
+                addVo.setVin(newVehicle.getVehicleVin());
+                addVo.setUid(order.getAppUserId().toString());
+                addVo.setOrderNo(order.getOrderNumber());
+                addVo.setAppId(""); // TODO 获取appId
+                userVehicleClient.addTaxiPassenger(addVo);
+                log.info("已绑定乘客与新车辆关系,用户ID: {}, VIN: {}", order.getAppUserId(), newVehicle.getVehicleVin());
+            }
+
+            // 11.2 下发订单到新车辆
+            PushOrderDto pushDto = new PushOrderDto();
+            pushDto.setOrderId(order.getId().toString());
+            pushDto.setVin(newVehicle.getVehicleVin());
+            orderMissionClient.pushOrder(pushDto);
+            log.info("已下发订单到新车辆,订单ID: {}, VIN: {}", orderId, newVehicle.getVehicleVin());
+
+            // 11.3 更新新车辆状态为已接单
+            newVehicle.setState(1);
+            xpVehicleClient.updateVehicleById(newVehicle);
+            log.info("已将新车辆状态设为已接单,车辆ID: {}", newVehicleId);
+
+        } catch (Exception e) {
+            log.error("处理新车辆失败,车辆ID: {},错误: {}", newVehicleId, e.getMessage());
+        }
+
+    }
+
+    /**
+     * 为原车辆创建返程巡游订单
+     * <p>
+     * 改派时,原车辆需要返回巡游路线:
+     * - 若最新巡游订单状态为已终止(status=2),返回原出发点
+     * - 若最新巡游订单状态为已完成(status=3),返回原终点
+     * - 其他状态,默认返回原出发点
+     * </p>
+     *
+     * @param oldVehicle 原车辆信息
+     * @param order      当前订单信息
+     */
+    private void createReturnCruiseOrder(XpVehicle oldVehicle, XpOrder order) {
+        try {
+            // 查询该车辆最新的一条巡游订单
+            XpCruiseOrder lastCruise = xpCruiseOrderMapper.selectOne(
+                    new LambdaQueryWrapper<XpCruiseOrder>()
+                            .eq(XpCruiseOrder::getVehicleId, oldVehicle.getId())
+                            .orderByDesc(BaseModel::getCreateTime)
+                            .last("limit 1")
+            );
+
+            if (lastCruise == null) {
+                log.warn("原车辆没有巡游订单记录,跳过创建返程订单,车辆ID: {}", oldVehicle.getId());
+                return;
+            }
+
+            XpCruiseOrder returnOrder = new XpCruiseOrder();
+            returnOrder.setId("XU" + IdUtil.fastUUID());
+            returnOrder.setVehicleId(oldVehicle.getId());
+            returnOrder.setVehicleVin(oldVehicle.getVehicleVin());
+            returnOrder.setFleetId(oldVehicle.getFleetId());
+            returnOrder.setOrderType(2); // 返程单
+            returnOrder.setStatus(1);    // 进行中
+            returnOrder.setLastOrderId(lastCruise.getId());
+            returnOrder.setCreateTime(LocalDateTime.now());
+
+            // 返程起点 = 当前订单的终点(车辆当前位置附近)
+            returnOrder.setStartPointId(order.getEndPointId());
+            returnOrder.setStartPointName(order.getEndPointName());
+            returnOrder.setStartLon(order.getEndLon());
+            returnOrder.setStartLat(order.getEndLat());
+
+            // 根据最新巡游订单状态决定返程终点
+            if (lastCruise.getStatus() != null && lastCruise.getStatus() == 2) {
+                // 已终止(status=2) -> 返回原出发点
+                returnOrder.setEndPointId(lastCruise.getStartPointId());
+                returnOrder.setEndPointName(lastCruise.getStartPointName());
+                returnOrder.setEndLon(lastCruise.getStartLon());
+                returnOrder.setEndLat(lastCruise.getStartLat());
+                log.info("巡游订单状态为已终止,返回原出发点");
+            } else if (lastCruise.getStatus() != null && lastCruise.getStatus() == 3) {
+                // 已完成(status=3) -> 返回原终点
+                returnOrder.setEndPointId(lastCruise.getEndPointId());
+                returnOrder.setEndPointName(lastCruise.getEndPointName());
+                returnOrder.setEndLon(lastCruise.getEndLon());
+                returnOrder.setEndLat(lastCruise.getEndLat());
+                log.info("巡游订单状态为已完成,返回原终点");
+            } else {
+                // 其他状态(进行中等),默认返回原出发点
+                returnOrder.setEndPointId(lastCruise.getStartPointId());
+                returnOrder.setEndPointName(lastCruise.getStartPointName());
+                returnOrder.setEndLon(lastCruise.getStartLon());
+                returnOrder.setEndLat(lastCruise.getStartLat());
+                log.info("巡游订单状态为{},默认返回原出发点", lastCruise.getStatus());
+            }
+
+            xpCruiseOrderMapper.insert(returnOrder);
+
+            // 下发巡游订单到原车辆
+            PushOrderDto pushDto = new PushOrderDto();
+            pushDto.setVin(oldVehicle.getVehicleVin());
+            pushDto.setOrderId(returnOrder.getId());
+            orderMissionClient.pushOrder(pushDto);
+
+            log.info("为原车辆创建返程巡游订单成功,订单ID: {}, 车辆ID: {}", returnOrder.getId(), oldVehicle.getId());
+
+        } catch (Exception e) {
+            log.error("创建返程巡游订单失败,车辆ID: {},错误: {}", oldVehicle.getId(), e.getMessage());
+        }
     }
 
     @Override

--
Gitblit v1.7.1