xuhy
2026-04-23 d9e201f71882d7d6faac88f1f2f69b31f5fb29f1
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -1,12 +1,10 @@
package com.xiaopeng.automaticPilot.controller;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO;
import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
@@ -20,7 +18,6 @@
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.model.order.XpOrder;import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.SystemEventType;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.automaticPilot.protobuf.*;
@@ -35,7 +32,6 @@
import com.xiaopeng.common.redis.service.RedisService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
@@ -46,7 +42,10 @@
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.*;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -80,7 +79,7 @@
        if(dto.getOrderType().equals(com.xiaopeng.api.vo.OrderType.CRUISE_ORDER)){
            RtTask.Builder taskBuilder = RtTask.newBuilder();
            taskBuilder.setOrderId(dto.getOrderId().toString());
            taskBuilder.setTaskId(snowflake.nextId() + "");
            taskBuilder.setTaskId(StringUtils.isNotEmpty(dto.getEndTaskId()) ? dto.getEndTaskId() : snowflake.nextId() + "");
            taskBuilder.setTaskType(OrderType.ORDER_TYPE_CRUISE);
            //构建起点坐标数据
            pointBuilderStart.setWaypointId(dto.getOrderId() + "-001");
@@ -105,16 +104,24 @@
            taskBuilder.addPoints(pointBuilderEnd);
            taskBuilder.setSequence(1);
            taskBuilder.setOrderPhase(OrderPhase.ROUTE_TO_CRUISE);
            //不停车替换原有任务
            if(null != dto.getLastOrderId()){
                TaskAction.Builder taskActionBuilder = TaskAction.newBuilder();
                taskActionBuilder.setOrderId(dto.getLastOrderId());
                taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                taskActionBuilder.setActionType(dto.getTaskActionType());
                taskBuilder.setPreActions(0, taskActionBuilder);
            }
            taskListBuilder.addTasks(taskBuilder.build());
        }
        else if(dto.getOrderType().equals(com.xiaopeng.api.vo.OrderType.USER_ORDER)){
        }else if(dto.getOrderType().equals(com.xiaopeng.api.vo.OrderType.USER_ORDER)){
            //乘客单
            for (int i = 1; i < 3; i++) {
                RtTask.Builder taskBuilder = RtTask.newBuilder();
                taskBuilder.setOrderId(dto.getOrderId().toString());
                taskBuilder.setTaskId(snowflake.nextId() + "");
                taskBuilder.setTaskType(OrderType.ORDER_TYPE_ROBOTAXI);
                if(i == 1){
                    RtTask.Builder taskBuilder = RtTask.newBuilder();
                    taskBuilder.setOrderId(dto.getOrderId().toString());
                    taskBuilder.setTaskId(StringUtils.isNotEmpty(dto.getStartTaskId()) ? dto.getStartTaskId() : snowflake.nextId() + "");
                    taskBuilder.setTaskType(OrderType.ORDER_TYPE_ROBOTAXI);
                    VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(dto.getVin())), VehiclePosition.class);
                    //构建车辆当前位置数据
                    pointBuilderStart.setWaypointId(dto.getOrderId() + "-JJ-001");
@@ -139,7 +146,21 @@
                    taskBuilder.addPoints(pointBuilderEnd);
                    taskBuilder.setSequence(i);
                    taskBuilder.setOrderPhase(OrderPhase.ROUTE_TO_PICKUP);
                    //不停车替换原有任务
                    if(null != dto.getLastOrderId()){
                        TaskAction.Builder taskActionBuilder = TaskAction.newBuilder();
                        taskActionBuilder.setOrderId(dto.getLastOrderId());
                        taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                        taskActionBuilder.setActionType(dto.getTaskActionType());
                        taskBuilder.setPreActions(0, taskActionBuilder);
                    }
                    taskListBuilder.addTasks(taskBuilder.build());
                }else{
                    RtTask.Builder taskBuilder = RtTask.newBuilder();
                    taskBuilder.setOrderId(dto.getOrderId().toString());
                    taskBuilder.setTaskId(StringUtils.isNotEmpty(dto.getEndTaskId()) ? dto.getEndTaskId() : snowflake.nextId() + "");
                    taskBuilder.setTaskType(OrderType.ORDER_TYPE_ROBOTAXI);
                    //构建上车点位置信息
                    pointBuilderStart.setWaypointId(dto.getOrderId() + "-SD-001");
                    pointBuilderStart.setPointType(PointType.PICK_UP_POINT);
@@ -164,17 +185,26 @@
                    taskBuilder.addPoints(pointBuilderEnd);
                    taskBuilder.setSequence(i);
                    taskBuilder.setOrderPhase(OrderPhase.ROUTE_TO_DESTINATION);
                    //不停车替换原有任务
                    if(null != dto.getLastOrderId()){
                        TaskAction.Builder taskActionBuilder = TaskAction.newBuilder();
                        taskActionBuilder.setOrderId(dto.getLastOrderId());
                        taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                        taskActionBuilder.setActionType(dto.getTaskActionType());
                        taskBuilder.setPreActions(0, taskActionBuilder);
                    }
                    taskListBuilder.addTasks(taskBuilder.build());
                }
                taskListBuilder.addTasks(taskBuilder.build());
            }
        }else if(dto.getOrderType().equals(com.xiaopeng.api.vo.OrderType.TEST_ORDER)){
            //测试单
            for (int i = 1; i < 3; i++) {
                RtTask.Builder taskBuilder = RtTask.newBuilder();
                taskBuilder.setOrderId(dto.getOrderId().toString());
                taskBuilder.setTaskId(snowflake.nextId() + "");
                taskBuilder.setTaskType(OrderType.ORDER_TYPE_ROBOTAXI);
                if(i == 1){
                    RtTask.Builder taskBuilder = RtTask.newBuilder();
                    taskBuilder.setOrderId(dto.getOrderId().toString());
                    taskBuilder.setTaskId(StringUtils.isNotEmpty(dto.getStartTaskId()) ? dto.getStartTaskId() : snowflake.nextId() + "");
                    taskBuilder.setTaskType(OrderType.ORDER_TYPE_ROBOTAXI);
                    VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(dto.getVin())), VehiclePosition.class);
                    //构建车辆当前位置数据
                    pointBuilderStart.setWaypointId(dto.getOrderId() + "-JJ-001");
@@ -200,7 +230,21 @@
                    taskBuilder.addPoints(pointBuilderEnd);
                    taskBuilder.setSequence(i);
                    taskBuilder.setOrderPhase(OrderPhase.ROUTE_TO_PICKUP);
                    //不停车替换原有任务
                    if(null != dto.getLastOrderId()){
                        TaskAction.Builder taskActionBuilder = TaskAction.newBuilder();
                        taskActionBuilder.setOrderId(dto.getLastOrderId());
                        taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                        taskActionBuilder.setActionType(dto.getTaskActionType());
                        taskBuilder.setPreActions(0, taskActionBuilder);
                    }
                    taskListBuilder.addTasks(taskBuilder.build());
                }else{
                    RtTask.Builder taskBuilder = RtTask.newBuilder();
                    taskBuilder.setOrderId(dto.getOrderId().toString());
                    taskBuilder.setTaskId(StringUtils.isNotEmpty(dto.getEndTaskId()) ? dto.getEndTaskId() : snowflake.nextId() + "");
                    taskBuilder.setTaskType(OrderType.ORDER_TYPE_ROBOTAXI);
                    //构建上车点位置信息
                    pointBuilderStart.setWaypointId(dto.getOrderId() + "-SD-001");
                    pointBuilderStart.setPointType(PointType.PICK_UP_POINT);
@@ -224,14 +268,23 @@
                    taskBuilder.addPoints(pointBuilderEnd);
                    taskBuilder.setSequence(i);
                    taskBuilder.setOrderPhase(OrderPhase.ROUTE_TO_DESTINATION);
                    //不停车替换原有任务
                    if(null != dto.getLastOrderId()){
                        TaskAction.Builder taskActionBuilder = TaskAction.newBuilder();
                        taskActionBuilder.setOrderId(dto.getLastOrderId());
                        taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                        taskActionBuilder.setActionType(dto.getTaskActionType());
                        taskBuilder.setPreActions(0, taskActionBuilder);
                    }
                    taskListBuilder.addTasks(taskBuilder.build());
                }
                taskListBuilder.addTasks(taskBuilder.build());
            }
        }else if(dto.getOrderType().equals(com.xiaopeng.api.vo.OrderType.TEST_CRUISE_ORDER)){
            //测试单巡游单
            RtTask.Builder taskBuilder = RtTask.newBuilder();
            taskBuilder.setOrderId(dto.getOrderId().toString());
            taskBuilder.setTaskId(snowflake.nextId() + "");
            taskBuilder.setTaskId(StringUtils.isNotEmpty(dto.getEndTaskId()) ? dto.getEndTaskId() : snowflake.nextId() + "");
            taskBuilder.setTaskType(OrderType.ORDER_TYPE_CRUISE);
            //构建起点坐标数据
            pointBuilderStart.setWaypointId(dto.getOrderId() + "-001");
@@ -256,17 +309,29 @@
            taskBuilder.addPoints(pointBuilderEnd);
            taskBuilder.setSequence(1);
            taskBuilder.setOrderPhase(OrderPhase.ROUTE_TO_CRUISE);
            //不停车替换原有任务
            if(null != dto.getLastOrderId()){
                TaskAction.Builder taskActionBuilder = TaskAction.newBuilder();
                taskActionBuilder.setOrderId(dto.getLastOrderId());
                taskActionBuilder.setTaskId(dto.getLastXpuTaskId());
                taskActionBuilder.setActionType(dto.getTaskActionType());
                taskBuilder.setPreActions(0, taskActionBuilder);
            }
            taskListBuilder.addTasks(taskBuilder.build());
        }
        long sequence = snowflake.nextId();
        MqttPublishDto mqttPublishDto = xpuUtil.cloudCreateOrder(taskListBuilder.build(), dto.getVin(),sequence);
        //先将车辆修改状态,防止在异步通知之前被其他订单选中
        if(!dto.getOrderType().equals(com.xiaopeng.api.vo.OrderType.CRUISE_ORDER) &&
                !dto.getOrderType().equals(com.xiaopeng.api.vo.OrderType.TEST_CRUISE_ORDER)
                && mqttPublishDto.getCode()== 200){
            // 修改车子为接单状态
            xpVehicleClient.updateVehicleStatus(new UpdateVehicleStateDto(dto.getVin(), 1));
            // TODO[流量接入] 通过设置的URL发送订单和导航路线给运力
        }
        if(null != mqttPublishDto && mqttPublishDto.getCode() == 200){
@@ -282,9 +347,9 @@
    }
    @PostMapping("/logan/inner/cancelOrder")
    R<Boolean> cancelOrder(@RequestBody PushOrderDto dto) {
    public R<Boolean> cancelOrder(@RequestBody PushOrderDto dto) {
        log.info("取消订单,推送XPU报文:{}", JSON.toJSONString(dto));
        String taskId = StringUtils.isNotEmpty(dto.getTaskId()) ? dto.getTaskId() : snowflake.nextId() + "";
        String taskId = StringUtils.isNotEmpty(dto.getEndTaskId()) ? dto.getEndTaskId() : snowflake.nextId() + "";
        OrderOperation.Builder operationBuilder = OrderOperation.newBuilder();
        operationBuilder.setOrderId(dto.getOrderId().toString());
        operationBuilder.setTaskId(taskId);
@@ -318,6 +383,48 @@
    @PostMapping("/logan/inner/updateEndAddress")
    public R<Boolean> updateEndAddress(@RequestBody PushOrderDto dto){
        log.info("修改目的地,推送XPU报文:{}", JSON.toJSONString(dto));
        String taskId = StringUtils.isNotEmpty(dto.getEndTaskId()) ? dto.getEndTaskId() : snowflake.nextId() + "";
        OrderOperation.Builder operationBuilder = OrderOperation.newBuilder();
        operationBuilder.setOrderId(dto.getOrderId().toString());
        operationBuilder.setTaskId(taskId);
        if (dto.getOperation_type() != null) {
            operationBuilder.setOperationType(OrderOperationType.forNumber(dto.getOperation_type().getNumber()));
        }
        Waypoint.Builder waypointBuilder = Waypoint.newBuilder();
        waypointBuilder.setWaypointId(dto.getOrderId() + "-002");
        waypointBuilder.setPointType(PointType.END_POINT);
        waypointBuilder.setActionType(ActionType.DROP_OFF);
        waypointBuilder.setSequence(2);
        GeoPoint.Builder geoPointBuilder = GeoPoint.newBuilder();
        geoPointBuilder.setLatitude(dto.getEndLatitude());
        geoPointBuilder.setLongitude(dto.getEndLongitude());
        waypointBuilder.setPoint(geoPointBuilder.build());
        waypointBuilder.setPoiName(dto.getEndPoiName());
        operationBuilder.setTargetPoint(waypointBuilder);
        long sequence = snowflake.nextId();
        MqttPublishDto mqttPublishDto = xpuUtil.cloudOrderOperation(operationBuilder.build(), dto.getVin(), sequence);
        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"));
            }
            return R.ok(true);
        }
        return R.ok(false);
    }
@@ -416,7 +523,7 @@
        if (R.isError(stringR)) {
            log.error("推送消息失败:{}", stringR.getMsg());
        }
        xpOrderClient.updateOrderStatus(orderId, OrderStatusEnum.PICK_UP.getCode());
        xpOrderClient.updateOrderStatus(orderId, OrderStatusEnum.PICK_UP.getCode(), false);
//        PushOrderRouteDTO dto3 = new PushOrderRouteDTO();
//        dto3.setOrderId(orderId);
@@ -518,6 +625,7 @@
                    dto.setDuration(10.0);
                    dto.setDistance(2.0);
                    dto.setDirection(60);
                    dto.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc());
                    xpPushMessageClient.pushOrderRoute(dto);
                }
@@ -545,7 +653,7 @@
            if (R.isError(stringR)) {
                log.error("推送消息失败:{}", stringR.getMsg());
            }
            xpOrderClient.updateOrderStatus(finalOrderId, OrderStatusEnum.PICK_UP_GUESTS.getCode());
            xpOrderClient.updateOrderStatus(finalOrderId, OrderStatusEnum.PICK_UP_GUESTS.getCode(), false);
        });
    }
@@ -583,7 +691,7 @@
        if (R.isError(stringR)) {
            log.error("推送消息失败:{}", stringR.getMsg());
        }
        xpOrderClient.updateOrderStatus(orderId, status);
        xpOrderClient.updateOrderStatus(orderId, status, false);
        if(5 == status){
            //主动推一次全程轨迹
            Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_END_DATA:" + xpOrder.getAppUserId());
@@ -699,6 +807,7 @@
                    dto.setDuration(20.0);
                    dto.setDistance(10.0);
                    dto.setDirection(60);
                    dto.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc());
                    xpPushMessageClient.pushOrderRoute(dto);
                    //存储历史轨迹
@@ -736,7 +845,7 @@
            if (R.isError(stringR)) {
                log.error("推送消息失败:{}", stringR.getMsg());
            }
            xpOrderClient.updateOrderStatus(finalOrderId, OrderStatusEnum.SEE_OFF_GUESTS.getCode());
            xpOrderClient.updateOrderStatus(finalOrderId, OrderStatusEnum.SEE_OFF_GUESTS.getCode(), false);
        });
    }