“mitao”
2026-02-13 52c1e023e60aa53ae76d875460d11f8e02ff2bc7
Merge remote-tracking branch 'origin/master'
8个文件已添加
21个文件已修改
612 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/MqttPublishDto.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/ElectronicFenceAddDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/ElectronicFenceUpdateDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automaticPilot/XPUClientFallbackFactory.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpElectronicClientFallbackFactory.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpSystemSettingClientFallbackFactory.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automaticPilot/XPUClient.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpElectronicClient.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpSystemSettingClient.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFenceArea.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderEvaluate.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/MqttPublishVo.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/ResponseMessage.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/StatusCode.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/dto/ServiceNameConstantsEnum.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/config/DataUpdateHandlerConfig.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpElectronicFenceController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFeedbackTypeController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/dto/XpOrderCommentDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/vo/OrderDetailVo.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/util/SnowFlake.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/MqttPublishDto.java
New file
@@ -0,0 +1,19 @@
package com.xiaopeng.api.dto.automaticPilot;
import lombok.Data;
@Data
public class MqttPublishDto {
    /**
     * 状态码
     */
    private Integer code;
    /**
     * 状态信息
     */
    private String msg;
    /**
     * 数据
     */
    private Object data;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/ElectronicFenceAddDto.java
@@ -10,6 +10,7 @@
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@@ -24,7 +25,8 @@
    private String cityCode;
    @ApiModelProperty(value = "围栏编号唯一 规则:城市首字母-类型简写-4位自增流水号(如 SZ-OP-001)")
    private String electronicNumber;
    @ApiModelProperty(value = "面积")
    private BigDecimal area;
    @ApiModelProperty(value = "围栏状态 0=草稿 1=待启用 2=启用中 3=已停用 草稿传0 发布传1")
    @NotNull(message = "围栏状态不能为空")
    private Integer status;
@@ -35,7 +37,6 @@
    private Integer effectType;
    @ApiModelProperty(value = "生效时间")
    @NotNull(message = "生效时间不能为空")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime effectTime;
@@ -44,7 +45,6 @@
    private Integer failureType;
    @ApiModelProperty(value = "失效时间")
    @NotNull(message = "失效时间不能为空")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime failureTime;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/ElectronicFenceUpdateDto.java
@@ -38,7 +38,6 @@
    private Integer effectType;
    @ApiModelProperty(value = "生效时间")
    @NotNull(message = "生效时间不能为空")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime effectTime;
@@ -47,7 +46,6 @@
    private Integer failureType;
    @ApiModelProperty(value = "失效时间")
    @NotNull(message = "失效时间不能为空")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime failureTime;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automaticPilot/XPUClientFallbackFactory.java
New file
@@ -0,0 +1,22 @@
package com.xiaopeng.api.factory.automaticPilot;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.feignClient.automaticPilot.XPUClient;
import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
@Slf4j
public class XPUClientFallbackFactory implements FallbackFactory<XPUClient> {
    @Override
    public XPUClient create(Throwable cause) {
        return new XPUClient(){
            @Override
            public MqttPublishDto publish(MqttPublishVo vo) {
                log.error("推送XPU-MQTT消息失败: {}", cause.getMessage());
                return null;
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpElectronicClientFallbackFactory.java
@@ -12,6 +12,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.Collection;
import java.util.List;
@@ -54,7 +55,7 @@
            }
            @Override
            public R copy(Integer id) {
            public R<Long> copy(@RequestBody Integer id) {
                log.error("复制电子围栏失败:{}", cause.getMessage());
                return R.fail("复制电子围栏失败");
            }
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpSystemSettingClientFallbackFactory.java
@@ -3,6 +3,7 @@
import com.xiaopeng.api.feignClient.operation.SysLogClient;
import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient;
import com.xiaopeng.api.model.operation.SysOperLog;
import com.xiaopeng.api.model.operation.XpFeedbackType;
import com.xiaopeng.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
@@ -25,6 +26,12 @@
                log.error("获取自动结束行程时间失败:{}", cause.getMessage());
                return R.fail("获取自动结束行程时间失败,"+cause.getMessage());
            }
            @Override
            public R<XpFeedbackType> getFeedbackTypeById(Long id) {
                log.error("获取反馈类型名称失败:{}", cause.getMessage());
                return R.fail(null);
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automaticPilot/XPUClient.java
New file
@@ -0,0 +1,25 @@
package com.xiaopeng.api.feignClient.automaticPilot;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.factory.automaticPilot.XPUClientFallbackFactory;
import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(contextId = "XPUClient",
        value = ServiceNameConstantsEnum.XP_MQTT_ROUTER_THIRDPARTY_BOOT,
        fallbackFactory = XPUClientFallbackFactory.class)
public interface XPUClient {
    /**
     * 推送MQTT消息
     * @param vo
     */
    @PostMapping("/logan/mqtt/publish")
    MqttPublishDto publish(@RequestBody MqttPublishVo vo);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpElectronicClient.java
@@ -12,10 +12,7 @@
import com.xiaopeng.common.core.web.page.PageInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
@@ -40,8 +37,8 @@
    /**
     * 电子围栏详情
     */
    @GetMapping("/api/v1/electronicFence/queryById")
    R<ElectronicFenceDetailVo> queryById(Long id);
    @PostMapping("/api/v1/electronicFence/queryById")
    R<ElectronicFenceDetailVo> queryById(@RequestParam("id")Long id);
    /**
     * 编辑电子围栏
     */
@@ -50,8 +47,8 @@
    /**
     * 复制电子围栏
     */
    @PutMapping("/api/v1/electronicFence/copy")
     R copy(Integer id);
    @PostMapping("/api/v1/electronicFence/copy")
    R<Long> copy(@RequestParam("id") Integer id);
    /**
     * 根据ID列表批量查询电子围栏
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpSystemSettingClient.java
@@ -1,11 +1,13 @@
package com.xiaopeng.api.feignClient.operation;
import com.xiaopeng.api.factory.operation.XpSystemSettingClientFallbackFactory;
import com.xiaopeng.api.model.operation.XpFeedbackType;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@FeignClient(contextId = "XpSystemSettingClient", value = ServiceNameConstantsEnum.XP_OPERATION_SERVICE, fallbackFactory = XpSystemSettingClientFallbackFactory.class)
@@ -22,4 +24,10 @@
    @GetMapping("/api/v1/mini-program/support/getOrderFinishTime")
    R<Integer> getOrderFinishTime();
    /**
     * 获取反馈类型
     * @return
     */
    @GetMapping("/base/v1/mini-program/getFeedbackTypeById/{id}")
    R<XpFeedbackType> getFeedbackTypeById(@PathVariable("id")Long id);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFenceArea.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.io.Serializable;
@@ -37,7 +39,8 @@
    @ApiModelProperty(value = "围栏id")
    private Long electronicId;
    @ApiModelProperty(value = "面积")
    private BigDecimal area;
    @ApiModelProperty(value = "区域名称")
    private String areaName;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderEvaluate.java
@@ -49,9 +49,9 @@
    private LocalDateTime evaluateTime;
    @ApiModelProperty(value = "问题类型id")
    private Integer feedbackTypeId;
    private Long feedbackTypeId;
    @ApiModelProperty(value = "反馈内容")
    private Integer feedbackContent;
    private String feedbackContent;
    @ApiModelProperty(value = "图片 json格式")
    private Integer feedbackPictures;
    private String feedbackPictures;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/MqttPublishVo.java
New file
@@ -0,0 +1,15 @@
package com.xiaopeng.api.vo.automaticPilot;
import lombok.Data;
@Data
public class MqttPublishVo {
    /**
     * 消息内容
     */
    private String payload;
    /**
     * Mqtt topic
     */
    private String topic;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/ResponseMessage.java
New file
@@ -0,0 +1,22 @@
package com.xiaopeng.api.vo.automaticPilot.proto.up;
import lombok.Data;
/**
 * 应答消息
 */
@Data
public class ResponseMessage {
    /**
     * 对应请求seq
     */
    private Long request_seq;
    /**
     * 响应码
     */
    private StatusCode code;
    /**
     * 时间戳(毫秒)
     */
    private Long timestamp;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/up/StatusCode.java
New file
@@ -0,0 +1,29 @@
package com.xiaopeng.api.vo.automaticPilot.proto.up;
/**
 * HTTP状态码枚举
 */
public enum StatusCode {
    HTTP_STATUS_CODE_UNSPECIFIED(0),
    OK(200),                            // 成功
    BAD_REQUEST(400),                   // 请求参数错误
    FORBIDDEN(403),
    NOT_FOUND(404),
    REQUEST_TIMEOUT(408),               // 请求超时
    INTERNAL_SERVER_ERROR(500);        // 失败
    private int value;
    StatusCode(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
}
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -21,4 +21,5 @@
com.xiaopeng.api.factory.vehicleConvoy.XpFleetOperationsClientFallbackFactory
com.xiaopeng.api.factory.pushMessage.XpPushMessageClientFallbackFactory
com.xiaopeng.api.factory.account.UserResourcesClientFallbackFactory
com.xiaopeng.api.factory.vehicleConvoy.VehicleControlClientFallbackFactory
com.xiaopeng.api.factory.vehicleConvoy.VehicleControlClientFallbackFactory
com.xiaopeng.api.factory.automaticPilot.XPUClientFallbackFactory
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -153,7 +153,15 @@
        }
        //消息应答
        if(MessageType.MESSAGE_TYPE_RESPONSE == type){
            com.xiaopeng.api.vo.automaticPilot.proto.up.ResponseMessage resposne = msgContent.getContent_detail().getObject("resposne", com.xiaopeng.api.vo.automaticPilot.proto.up.ResponseMessage.class);
            com.xiaopeng.api.vo.automaticPilot.proto.up.StatusCode code = resposne.getCode();
            Long requestSeq = resposne.getRequest_seq();
            if(code == com.xiaopeng.api.vo.automaticPilot.proto.up.StatusCode.OK){
            }
        }
    }
    /**
@@ -239,9 +247,6 @@
     * @param msgContent
     */
    public void systemStatusXpu(MsgContent msgContent) {
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence);
        //开始处理消息对应的业务逻辑
        SystemRuntimeStatus systemRuntimeStatus = msgContent.getContent_detail().getObject("systemRuntimeStatus", SystemRuntimeStatus.class);
        //获取实时位姿
@@ -254,6 +259,10 @@
        //获取车辆静态信息
        VehicleStaticInfo staticInfo = systemRuntimeStatus.getVehicle_status().getStatic_info();
        String vin = staticInfo.getVin();
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence, vin);
        //保存车辆实时位置到redis
        redisTemplate.opsForGeo().add("vehiclePosition:" + vin, new GeoJsonPoint(longitude, latitude), vin);
        //保存车辆实时信息到mongodb
@@ -306,9 +315,6 @@
     * @param msgContent
     */
    public void xpuNavigationRequest(MsgContent msgContent) {
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence);
        //开始处理消息对应的业务逻辑
        NavigationRequest naviRequest = msgContent.getContent_detail().getObject("naviRequest", NavigationRequest.class);
        String orderId = naviRequest.getOrder_id();
@@ -322,15 +328,15 @@
                break;
            case ROUTE_TO_PICKUP:
                log.info("驶往上车点的行程");
                buildNaviRequest(orderId, taskId, orderPhase);
                buildNaviRequest(orderId, taskId, orderPhase, msgContent.getHeader().getSequence());
                break;
            case ROUTE_TO_DESTINATION:
                log.info("驶往下车点的行程");
                buildNaviRequest(orderId, taskId, orderPhase);
                buildNaviRequest(orderId, taskId, orderPhase, msgContent.getHeader().getSequence());
                break;
            case ROUTE_TO_CRUISE:
                log.info("巡游阶段路线");
                buildNaviRequest(orderId, taskId, orderPhase);
                buildNaviRequest(orderId, taskId, orderPhase, msgContent.getHeader().getSequence());
                break;
        }
    }
@@ -344,7 +350,6 @@
    public void navigationDeviationEvent(MsgContent msgContent) {
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence);
        //开始处理消息对应的业务逻辑
        NavigationDeviationEvent deviationEvent = msgContent.getContent_detail().getObject("deviationEvent", NavigationDeviationEvent.class);
        //偏航事件类型 1:请求导航,2:取消导航
@@ -366,6 +371,8 @@
                origin.setLatitude(latitude);
                destination.setLongitude(116.40528);
                destination.setLatitude(39.90498);
                //响应消息
                responseMessage(sequence, "");
            } else {
                //正常单
                R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
@@ -373,6 +380,9 @@
                    throw new RuntimeException("订单不存在");
                }
                XpOrder xpOrder = xpOrderR.getData();
                XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
                //响应消息
                responseMessage(sequence, xpVehicle.getVehicleVin());
                //驶往上车点的行程
                if (Arrays.asList(3).contains(xpOrder.getStatus())) {
                    //查询司机当前位置到起点的线路
@@ -399,7 +409,7 @@
                }
                RouteVo routeVo = routeVoR.getData();
                //构建导航下发请求对象
                cloudOrderOperation(orderType, orderId, taskId, routeVo);
                cloudOrderOperation(orderType, orderId, taskId, routeVo, xpVehicle.getVehicleVin());
            }
        }
    }
@@ -412,7 +422,7 @@
     * @param taskId
     * @param orderPhase
     */
    public void buildNaviRequest(String orderId, String taskId, OrderPhase orderPhase) {
    public void buildNaviRequest(String orderId, String taskId, OrderPhase orderPhase, Long sequence) {
        //订单类型  1:乘客订单,2=巡游订单
        Integer orderType = 1;
        LonLatDto destination = new LonLatDto();
@@ -426,6 +436,9 @@
                origin.setLatitude(39.90498);
                destination.setLongitude(116.40528);
                destination.setLatitude(39.90498);
                //先响应消息
                responseMessage(sequence, "");
            }
        } else {
            //正常单
@@ -437,6 +450,9 @@
            //驶往上车点的行程
            if (orderPhase.equals(OrderPhase.ROUTE_TO_PICKUP)) {
                XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
                //先响应消息
                responseMessage(sequence, xpVehicle.getVehicleVin());
                //查询车辆位置
                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class);
                if (Objects.isNull(vehiclePosition)) {
                    throw new RuntimeException("车辆位置信息不存在");
@@ -463,9 +479,10 @@
            if (200 != routeVoR.getCode()) {
                throw new RuntimeException("获取订单线路和运费失败");
            }
            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
            RouteVo routeVo = routeVoR.getData();
            //构建导航下发请求对象
            cloudOrderOperation(orderType, orderId, taskId, routeVo);
            cloudOrderOperation(orderType, orderId, taskId, routeVo, xpVehicle.getVehicleVin());
        }
    }
@@ -475,7 +492,7 @@
     *
     * @param routeVo
     */
    public void cloudOrderOperation(Integer orderType, String orderId, String taskId, RouteVo routeVo) {
    public void cloudOrderOperation(Integer orderType, String orderId, String taskId, RouteVo routeVo, String vin) {
        //构建消息体
        OrderOperation orderOperation = new OrderOperation();
        orderOperation.setOrder_id(orderId);
@@ -511,19 +528,19 @@
        }
        orderOperation.setWaypoints(waypoints);
        //开发发送请求到XPU
        xpuUtil.cloudOrderOperation(orderOperation);
        xpuUtil.cloudOrderOperation(orderOperation, vin);
    }
    /**
     * 构建响应消息
     */
    public void responseMessage(Long request_seq) {
    public void responseMessage(Long request_seq, String vin) {
        ResponseMessage responseMessage = new ResponseMessage();
        responseMessage.setRequest_seq(request_seq);
        responseMessage.setCode(StatusCode.OK);
        responseMessage.setTimestamp(System.currentTimeMillis());
        xpuUtil.responseMessage(responseMessage);
        xpuUtil.responseMessage(responseMessage, vin);
    }
@@ -534,7 +551,6 @@
    public void orderStateUpdateEvent(MsgContent msgContent) {
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence);
        //开始处理消息对应的业务逻辑
        OrderStatusInfoEvent orderStatusInfoEvent = msgContent.getContent_detail().getObject("orderStatusInfoEvent", OrderStatusInfoEvent.class);
        //只处理请求消息
@@ -550,7 +566,7 @@
                    break;
                case ORDER_RECEIVED:
                    //收到订单
                    buildPushOrderStatus(orderId, OrderStatusEnum.READY_DEPART);
                    buildPushOrderStatus(orderId, OrderStatusEnum.READY_DEPART, sequence);
                    break;
                case ORDER_STARTED:
                    //开始执行订单
@@ -558,7 +574,7 @@
                    break;
                case ORDER_EN_ROUTE_TO_PICKUP:
                    //前往上车点
                    buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP);
                    buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP, sequence);
                    break;
                case ORDER_ARRIVED_AT_PICKUP:
                    //到达上车点
@@ -566,15 +582,15 @@
                    break;
                case ORDER_WAITING_FOR_PICKUP:
                    //等待乘客上车
                    buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP_GUESTS);
                    buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP_GUESTS, sequence);
                    break;
                case ORDER_PASSENGER_ONBOARD:
                    //乘客已上车
                    buildPushOrderStatus(orderId, OrderStatusEnum.PASSENGER_BOARDED);
                    buildPushOrderStatus(orderId, OrderStatusEnum.PASSENGER_BOARDED, sequence);
                    break;
                case ORDER_EN_ROUTE_TO_DESTINATION:
                    //前往目的地
                    buildPushOrderStatus(orderId, OrderStatusEnum.IN_SERVICE);
                    buildPushOrderStatus(orderId, OrderStatusEnum.IN_SERVICE, sequence);
                    break;
                case ORDER_ARRIVED_AT_DESTINATION:
                    //到达目的地
@@ -582,11 +598,11 @@
                    break;
                case ORDER_WAITING_FOR_DROPOFF:
                    //等待乘客下车
                    buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS);
                    buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence);
                    break;
                case ORDER_DROPOFF_COMPLETED:
                    //下车完成
                    buildPushOrderStatus(orderId, OrderStatusEnum.APPROVAL_REJECTION);
                    buildPushOrderStatus(orderId, OrderStatusEnum.APPROVAL_REJECTION, sequence);
                    break;
                case ORDER_COMPLETED:
                    //已完成
@@ -594,11 +610,11 @@
                    break;
                case ORDER_CANCELLED:
                    //已取消
                    buildPushOrderStatus(orderId, OrderStatusEnum.CANCELED);
                    buildPushOrderStatus(orderId, OrderStatusEnum.CANCELED, sequence);
                    break;
                case ORDER_ARRIVED_AT_CRUISE_DESTINATION:
                    //到达巡游终点
                    buildPushOrderStatus(orderId, null);
                    buildPushOrderStatus(orderId, null, sequence);
                    break;
                case ORDER_PAUSED:
                    //订单暂停
@@ -616,11 +632,19 @@
     * @param orderId
     * @param status
     */
    public void buildPushOrderStatus(String orderId, OrderStatusEnum status){
    public void buildPushOrderStatus(String orderId, OrderStatusEnum status, Long sequence){
        if(orderId.contains("XU")){
            //巡游单
            //响应消息
            responseMessage(sequence, "");
        }else{
            //普通单
            R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
            XpOrder xpOrder = xpOrderR.getData();
            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
            //响应消息
            responseMessage(sequence, xpVehicle.getVehicleVin());
            //构建推送消息
            Map<String, Object> params = new HashMap<>();
            Map<String, Object> content = new HashMap<>();
@@ -630,8 +654,6 @@
            params.put("content", com.alibaba.fastjson2.JSONObject.toJSONString(content));
            params.put("timestamp", System.currentTimeMillis() + "");
            String message = JSONObject.toJSONString(params);
            R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
            XpOrder xpOrder = xpOrderR.getData();
            Long appUserId = xpOrder.getAppUserId();
            SendMessageDTO dto = new SendMessageDTO();
            dto.setAppUserId(appUserId + "");
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java
@@ -7,13 +7,17 @@
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.feignClient.automaticPilot.XPUClient;
import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo;
import com.xiaopeng.api.vo.automaticPilot.proto.down.*;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperation;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.RTTask;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperation;
import com.xiaopeng.common.core.utils.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * 自动驾驶接口对接文档
@@ -22,11 +26,8 @@
@Component
public class XPUUtil {
    /**
     * 接口地址
     */
    @Value("${xpu.url}")
    private String xpuUrl;
    @Resource
    private XPUClient xpuClient;
    /**
@@ -35,7 +36,7 @@
     * @param task
     * @return
     */
    public ResponseMessage cloudCreateOrder(RTTask task) {
    public MqttPublishDto cloudCreateOrder(RTTask task, String vin) {
        MsgContent msgContent = new MsgContent();
        // 消息头
        RtMsgHeader header = new RtMsgHeader();
@@ -50,22 +51,12 @@
        jsonObject.put("task", task);
        msgContent.setContent_detail(jsonObject);
        log.info("云端-->XPU 创建订单:{}", msgContent);
        HttpRequest post = HttpUtil.createPost("");
        post.body(JSON.toJSONString(msgContent));
        HttpResponse execute = post.execute();
        int status = execute.getStatus();
        if (200 != status) {
            throw new RuntimeException("XPU 接口异常:" + execute.getStatus());
        }
        MsgContent resMsgContent = JSON.parseObject(execute.body(), MsgContent.class);
        RtMsgHeader resHeader = resMsgContent.getHeader();
        int value = resHeader.getType().getValue();
        //只处理应答消息
        if (value == MessageType.MESSAGE_TYPE_RESPONSE.getValue()) {
            JSONObject contentDetail = resMsgContent.getContent_detail();
            return contentDetail.getObject("response", ResponseMessage.class);
        }
        return null;
        //组装请求消息体
        MqttPublishVo vo = new MqttPublishVo();
        vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin);
        vo.setPayload(JSON.toJSONString(msgContent));
        return xpuClient.publish(vo);
    }
@@ -76,7 +67,7 @@
     * @param operation
     * @return
     */
    public ResponseMessage cloudOrderOperation(OrderOperation operation) {
    public MqttPublishDto cloudOrderOperation(OrderOperation operation, String vin) {
        MsgContent msgContent = new MsgContent();
        // 消息头
        RtMsgHeader header = new RtMsgHeader();
@@ -92,22 +83,11 @@
        jsonObject.put("operation", operation);
        msgContent.setContent_detail(jsonObject);
        log.info("云端-->XPU 操作订单:{}", msgContent);
        HttpRequest post = HttpUtil.createPost("");
        post.body(JSON.toJSONString(msgContent));
        HttpResponse execute = post.execute();
        int status = execute.getStatus();
        if (200 != status) {
            throw new RuntimeException("XPU 接口异常:" + execute.getStatus());
        }
        MsgContent resMsgContent = JSON.parseObject(execute.body(), MsgContent.class);
        RtMsgHeader resHeader = resMsgContent.getHeader();
        int value = resHeader.getType().getValue();
        //只处理应答消息
        if (value == MessageType.MESSAGE_TYPE_RESPONSE.getValue()) {
            JSONObject contentDetail = resMsgContent.getContent_detail();
            return contentDetail.getObject("response", ResponseMessage.class);
        }
        return null;
        //组装请求消息体
        MqttPublishVo vo = new MqttPublishVo();
        vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin);
        vo.setPayload(JSON.toJSONString(msgContent));
        return xpuClient.publish(vo);
    }
@@ -119,7 +99,7 @@
     * @param responseMessage
     * @return
     */
    public ResponseMessage responseMessage(ResponseMessage responseMessage) {
    public MqttPublishDto responseMessage(ResponseMessage responseMessage, String vin) {
        MsgContent msgContent = new MsgContent();
        // 消息头
        RtMsgHeader header = new RtMsgHeader();
@@ -135,14 +115,11 @@
        jsonObject.put("resposne", responseMessage);
        msgContent.setContent_detail(jsonObject);
        log.info("云端-->XPU 响应消息:{}", msgContent);
        HttpRequest post = HttpUtil.createPost("");
        post.body(JSON.toJSONString(msgContent));
        HttpResponse execute = post.execute();
        int status = execute.getStatus();
        if (200 != status) {
            throw new RuntimeException("XPU 接口异常:" + execute.getStatus());
        }
        return null;
        //组装请求消息体
        MqttPublishVo vo = new MqttPublishVo();
        vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin);
        vo.setPayload(JSON.toJSONString(msgContent));
        return xpuClient.publish(vo);
    }
}
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/dto/ServiceNameConstantsEnum.java
@@ -61,5 +61,9 @@
     * 小鹏用车控服务
     */
    String XP_IM_OPEN_BOOT_SERVICE = "xp-im-open-boot";
    /**
     * 小鹏用车控服务
     */
    String XP_MQTT_ROUTER_THIRDPARTY_BOOT = "xp-mqtt-router-thirdparty-boot";
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java
@@ -14,6 +14,7 @@
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.utils.bean.BeanUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -39,6 +40,8 @@
public class XpElectronicFenceManagementController {
    @Resource
    private TokenService tokenService;
    @Resource
    private XpElectronicClient xpElectronicClient;
@@ -56,6 +59,7 @@
    @ApiOperation(value = "新增电子围栏")
    @Transactional
    public R add(@Validated @RequestBody ElectronicFenceAddDto dto) {
        return xpElectronicClient.add(dto);
    }
@@ -75,10 +79,10 @@
    /**
     * 电子围栏详情
     */
    @GetMapping("/queryById")
    @PostMapping("/queryById")
    @ResponseBody
    @ApiOperation(value = "电子围栏详情")
    public R<ElectronicFenceDetailVo> queryById(Long id) {
    public R<ElectronicFenceDetailVo> queryById(@RequestParam("id")Long id) {
        return xpElectronicClient.queryById(id);
    }
@@ -96,11 +100,9 @@
    /**
     * 复制电子围栏
     */
    @GetMapping("/copy")
    @ResponseBody
    @PostMapping("/copy")
    @ApiOperation(value = "复制电子围栏")
    @Transactional
    public R copy(Integer id) {
    public R<Long> copy(@RequestParam("id") Integer id) {
        return xpElectronicClient.copy(id);
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/config/DataUpdateHandlerConfig.java
@@ -50,7 +50,6 @@
        }
        this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("createBy", userName, metaObject);
    }
    /**
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpElectronicFenceController.java
@@ -110,9 +110,9 @@
    /**
     * 电子围栏详情
     */
    @GetMapping("/queryById")
    @PostMapping("/queryById")
    @ApiOperation(value = "电子围栏详情")
    public R<ElectronicFenceDetailVo> queryById(Long id) {
    public R<ElectronicFenceDetailVo> queryById(@RequestParam("id")Long id) {
        ElectronicFenceDetailVo res = new ElectronicFenceDetailVo();
        XpElectronicFence electronicFence = xpElectronicFenceService.getById(id);
        if (electronicFence == null) {
@@ -141,10 +141,10 @@
    /**
     * 复制电子围栏
     */
    @GetMapping("/copy")
    @PostMapping("/copy")
    @ApiOperation(value = "复制电子围栏")
    @Transactional
    public R copy(Integer id) {
    public R<Long> copy(@RequestParam("id") Integer id) {
        XpElectronicFence electronicFence = xpElectronicFenceService.getById(id);
        if (electronicFence.getStatus()==2){
            throw new ServiceException(
@@ -165,7 +165,7 @@
            area.setAreaName("副本_"+area.getAreaName());
        }
        xpElectronicFenceAreaService.saveBatch(electronicFenceAreaList);
        return R.ok();
        return R.ok(electronicFence.getId());
    }
    /**
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpFeedbackTypeController.java
@@ -8,6 +8,7 @@
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
@@ -36,7 +37,14 @@
    public XpFeedbackTypeController(IXpFeedbackTypeService xpFeedbackTypeService) {
        this.xpFeedbackTypeService = xpFeedbackTypeService;
    }
    /**
     * 获取反馈类型
     * @return
     */
    @GetMapping("/getFeedbackTypeById/{id}")
    public R<XpFeedbackType> getFeedbackTypeById(@PathVariable("id")Long id){
        return R.ok(xpFeedbackTypeService.getById(id));
    }
    @GetMapping("/feedback-type/getList")
    @ApiOperation(value = "获取意见反馈类型列表",tags = {"意见反馈类型列表"},response = XpFeedbackType.class)
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java
@@ -15,6 +15,7 @@
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.utils.DateUtils;
import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.core.utils.bean.BeanUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.constant.I18nKeyConstant;
@@ -65,6 +66,9 @@
    @Override
    public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) {
        PageInfo<XpElectronicFence> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        if (StringUtils.isEmpty(query.getCreateSort())&& StringUtils.isEmpty(query.getUpdateSort())){
            query.setCreateSort("2");
        }
        List<XpElectronicFence> list = this.baseMapper.pageList(pageInfo, query);
        if (list.isEmpty()) {
            return new PageInfo<>();
@@ -78,7 +82,9 @@
            if (xpElectronicFenceAreas != null) {
                xpElectronicFence.setOperatingAreaCount(xpElectronicFenceAreas.stream().filter(xpElectronicFenceArea -> xpElectronicFenceArea.getAreaType() == 1).count());
                xpElectronicFence.setProhibitedAreaCount(xpElectronicFenceAreas.stream().filter(xpElectronicFenceArea -> xpElectronicFenceArea.getAreaType() == 2).count());
            }else{
                xpElectronicFence.setOperatingAreaCount(0L);
                xpElectronicFence.setProhibitedAreaCount(0L);
            }
        }
        pageInfo.setRecords(list);
@@ -194,6 +200,7 @@
                for (XpElectronicFenceArea area : newElectronicFenceAreas) {
                    area.setElectronicId(xpElectronicFence.getId());
                    area.setAreaStatus(1);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
@@ -333,6 +340,7 @@
            for (XpElectronicFenceArea area : updatedElectronicFenceAreas) {
                area.setElectronicId(dto.getId()); // 设置关联的电子围栏ID
                area.setCityCode(dto.getCityCode());
                area.setArea(area.getArea());
                xpElectronicFenceAreaMapper.insert(area);
            }
            if (dto.getStatus() == 2) {
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -28,6 +28,7 @@
import com.xiaopeng.order.model.vo.XpOrderHistoryVO;
import com.xiaopeng.order.model.vo.XpOrderPageVO;
import com.xiaopeng.order.service.IXpOrderService;
import com.xiaopeng.order.vo.OrderDetailVo;
import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -252,7 +253,6 @@
        return R.ok();
    }
    /**
     * 获取用户快捷胶囊 历史 时段 终点高点
     */
@@ -265,6 +265,18 @@
        return R.ok(xpOrderService.getUserQuickCapsule(uid));
    }
    /**
     * 获取订单详情
     */
    @PutMapping("/api/v1/mini-program/order/orderDetail/{orderId}")
    @ApiOperation(value = "获取订单详情", tags = {"小程序-获取订单详情"})
    @XpClientCheck(checkToken = false, checkOtpToken = true)
    public R<OrderDetailVo> orderDetail(@PathVariable("orderId") Long orderId, HttpServletRequest request) {
        // uid已通过拦截器otp校验,可以直接使用
        String uid = request.getHeader("XP-Uid");
        ;
        return R.ok(xpOrderService.orderDetail(orderId,uid));
    }
    /**
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/dto/XpOrderCommentDto.java
@@ -12,9 +12,9 @@
    @ApiModelProperty(value = "订单评分")
    private Integer orderRating;
    @ApiModelProperty(value = "问题类型id")
    private Integer feedbackTypeId;
    private Long feedbackTypeId;
    @ApiModelProperty(value = "反馈内容")
    private Integer feedbackContent;
    private String feedbackContent;
    @ApiModelProperty(value = "图片 json格式")
    private Integer feedbackPictures;
    private String feedbackPictures;
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
@@ -21,6 +21,7 @@
import com.xiaopeng.order.model.vo.XpOrderDetailVO;
import com.xiaopeng.order.model.vo.XpOrderHistoryVO;
import com.xiaopeng.order.model.vo.XpOrderPageVO;
import com.xiaopeng.order.vo.OrderDetailVo;
import java.util.List;
@@ -186,4 +187,6 @@
     * @param orderTrajectory
     */
    void saveVehicleLocation(OrderTrajectory orderTrajectory);
    OrderDetailVo orderDetail(Long orderId, String uid);
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -28,6 +28,7 @@
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpAppUser;
import com.xiaopeng.api.model.operation.XpFeedbackType;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.order.XpOrderCancel;
@@ -69,6 +70,8 @@
import com.xiaopeng.order.service.IXpOrderReassignService;
import com.xiaopeng.order.service.IXpOrderService;
import com.xiaopeng.order.utils.holiday.HolidayUtil;
import com.xiaopeng.order.vo.OrderDetailVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
@@ -913,6 +916,8 @@
            userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo);
        }
        // 计算起步价
//        // 计算实际价格
//        // 根据订单所属开通城市id 查询定价
//        R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCityId(order.getCityId());
@@ -1588,6 +1593,49 @@
        }
    }
    @Override
    public OrderDetailVo orderDetail(Long orderId, String uid) {
        OrderDetailVo orderDetailVo = new OrderDetailVo();
        XpOrder order = this.getById(orderId);
        BeanUtils.copyProperties(order, orderDetailVo);
        // 查询车辆信息
        XpVehicle vehicle = xpVehicleClient.queryById(order.getVehicleId()).getData();
        if (vehicle!=null){
            orderDetailVo.setVehicleCode(vehicle.getVehicleCode());
            orderDetailVo.setPlateNumber(vehicle.getPlateNumber());
            orderDetailVo.setVehicleColor(vehicle.getVehicleColor());
            orderDetailVo.setVehiclePictures(vehicle.getVehiclePictures());
        }
        // 查询评价信息
        XpOrderEvaluate evaluate = xpOrderEvaluateService.lambdaQuery().eq(XpOrderEvaluate::getOrderId, orderId)
                .last("limit 1").one();
        if (evaluate != null) {
            orderDetailVo.setFeedbackPictures(evaluate.getFeedbackPictures());
            orderDetailVo.setFeedbackContent(evaluate.getFeedbackContent());
            orderDetailVo.setOrderRating(evaluate.getOrderRating());
            XpFeedbackType feedbackType = xpSystemSettingClient.getFeedbackTypeById(evaluate.getFeedbackTypeId()).getData();
            orderDetailVo.setFeedbackTypeName(feedbackType.getFeedbackType());
        }
        List<OrderTrajectory> trajectories = mongoTemplate.find(
                new Query(Criteria.where("orderId").is(orderId))
                        .with(Sort.by(Sort.Direction.ASC, "locatetime")),
                OrderTrajectory.class
        );
        orderDetailVo.setTrajectories(trajectories);
        if (order.getTripBegin()!=null&&order.getTripEnd()!=null){
            // 计算两个时间相差多少分钟
            long minutesDifference = Duration.between(order.getTripBegin(), order.getTripEnd()).toMinutes();
            orderDetailVo.setOrderTime(minutesDifference);
        }else{
            orderDetailVo.setOrderTime(0l);
        }
        if (order.getStartMileage()!=null){
            orderDetailVo.setTotalMileage(order.getStartMileage()+(order.getMileageKilometers()!=null?order.getMileageKilometers():0D));
        }
        return orderDetailVo;
    }
    /**
     * 获取当前用户正在执行的订单
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/vo/OrderDetailVo.java
New file
@@ -0,0 +1,37 @@
package com.xiaopeng.order.vo;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.order.mangodb.model.OrderTrajectory;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value = "订单详情")
public class OrderDetailVo extends XpOrder {
    @ApiModelProperty(value = "车辆编码")
    private String vehicleCode;
    @ApiModelProperty(value = "车牌号")
    private String plateNumber;
    @ApiModelProperty(value = "车辆颜色")
    private String vehicleColor;
    @ApiModelProperty(value = "车辆图片")
    private String vehiclePictures;
    @ApiModelProperty(value = "反馈图片")
    private String feedbackPictures;
    @ApiModelProperty(value = "反馈内容")
    private String feedbackContent;
    @ApiModelProperty(value = "问题类型")
    private String feedbackTypeName;
    @ApiModelProperty(value = "评分")
    private Integer orderRating;
    @ApiModelProperty(value = "时长分钟")
    private Long orderTime;
    @ApiModelProperty(value = "总里程")
    private Double totalMileage;
    @ApiModelProperty(value = "轨迹")
    private List<OrderTrajectory> trajectories;
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/util/SnowFlake.java
New file
@@ -0,0 +1,111 @@
package com.xiaopeng.vehicleConvoy.util;
/**
 * see @https://raw.githubusercontent.com/beyondfengyu/SnowFlake/master/SnowFlake.java
 * Created by Lox on 2017/8/21.
 */
public class SnowFlake {
    /**
     * 起始的时间戳
     */
    private static long START_STMP = 1503305692631L;
    /**
     * 每一部分占用的位数
     */
    private final static long SEQUENCE_BIT = 12; //序列号占用的位数
    private final static long MACHINE_BIT = 5;   //机器标识占用的位数
    private final static long DATACENTER_BIT = 5;//数据中心占用的位数
    /**
     * 每一部分的最大值
     */
    public final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
    public final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
    /**
     * 每一部分向左的位移
     */
    private final static long MACHINE_LEFT = SEQUENCE_BIT;
    private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
    private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
    private long datacenterId;  //数据中心
    private long machineId;     //机器标识
    private long sequence = 0L; //序列号
    private long lastStmp = -1L;//上一次时间戳
    public SnowFlake(long datacenterId, long machineId) {
        if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
            throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
        }
        if (machineId > MAX_MACHINE_NUM || machineId < 0) {
            throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
        }
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }
    /**
     * 设置初始时间,各业务方的旧算法有可能初始时间不一致,请使用
     * @param timestamp 设定的新初始时间戳
     * @return 当前对象
     */
    public SnowFlake withStartTimestamp(long timestamp) {
        SnowFlake.START_STMP = timestamp;
        return this;
    }
    /**
     * 产生下一个ID
     *
     * @return
     */
    public synchronized long nextId() {
        long currStmp = getNewstmp();
        if (currStmp < lastStmp) {
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        }
        if (currStmp == lastStmp) {
            //相同毫秒内,序列号自增
            sequence = (sequence + 1) & MAX_SEQUENCE;
            //同一毫秒的序列数已经达到最大
            if (sequence == 0L) {
                currStmp = getNextMill();
            }
        } else {
            //不同毫秒内,序列号置为0
            sequence = 0L;
        }
        lastStmp = currStmp;
        return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
                | datacenterId << DATACENTER_LEFT       //数据中心部分
                | machineId << MACHINE_LEFT             //机器标识部分
                | sequence;                             //序列号部分
    }
    private long getNextMill() {
        long mill = getNewstmp();
        while (mill <= lastStmp) {
            mill = getNewstmp();
        }
        return mill;
    }
    private long getNewstmp() {
        return System.currentTimeMillis();
    }
//    public static void main(String[] args) {
//        SnowFlake snowFlake = new SnowFlake(0, 0);
//        snowFlake.withStartTimestamp(1420041600000L);
//
//        for (int i = 0; i < (1 << 5); i++) {
//            System.out.println(snowFlake.nextId());
//        }
//    }
}