puzhibing
2026-03-24 52e608d6d37bfcf541193143eefae6e3933f5cb5
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi

# Conflicts:
# xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
# xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
# xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
7个文件已添加
12个文件已修改
734 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/VehicleEventDTO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automaticPilot/VehicleBuriedPointClientFallbackFactory.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automaticPilot/VehicleBuriedPointClient.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/VehiclePosition.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/VehicleBuriedPointController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/KafkaSendUtils.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/VehicleBuriedPointProducer.java 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/resources/gio.properties 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleOperationsController.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpTaskMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/exportExcel/XpCruiseOrderExportExcel.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpPolicyApplicationServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/VehicleEventDTO.java
New file
@@ -0,0 +1,22 @@
package com.xiaopeng.api.dto.automaticPilot;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Map;
@Data
public class VehicleEventDTO {
    @ApiModelProperty(value = "车辆VIN")
    private String vin;
    @ApiModelProperty(value = "XPU ID")
    private String xpuId;
    @ApiModelProperty(value = "订单ID")
    private String orderId;
    @ApiModelProperty(value = "事件标识")
    private String eventKey;
    @ApiModelProperty(value = "事件时间")
    private Long eventTime;
    @ApiModelProperty(value = "事件属性")
    private Map<String,Object> attributes;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automaticPilot/VehicleBuriedPointClientFallbackFactory.java
New file
@@ -0,0 +1,23 @@
package com.xiaopeng.api.factory.automaticPilot;
import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO;
import com.xiaopeng.api.feignClient.automaticPilot.VehicleBuriedPointClient;
import com.xiaopeng.api.feignClient.automaticPilot.XpuVinClient;
import com.xiaopeng.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
@Slf4j
public class VehicleBuriedPointClientFallbackFactory implements FallbackFactory<VehicleBuriedPointClient> {
    @Override
    public VehicleBuriedPointClient create(Throwable cause) {
        return new VehicleBuriedPointClient() {
            @Override
            public R<String> sendVehicleEvent(VehicleEventDTO event) {
                log.error("推送埋点数据失败: {}", cause.getMessage());
                return R.fail("推送埋点数据失败");
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automaticPilot/VehicleBuriedPointClient.java
New file
@@ -0,0 +1,27 @@
package com.xiaopeng.api.feignClient.automaticPilot;
import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO;
import com.xiaopeng.api.factory.automaticPilot.VehicleBuriedPointClientFallbackFactory;
import com.xiaopeng.api.factory.automaticPilot.XpuVimClientFallbackFactory;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(contextId = "VehicleBuriedPointClient",
        value = ServiceNameConstantsEnum.XP_AUTOMATIC_PILOT_SERVICE,
        fallbackFactory = VehicleBuriedPointClientFallbackFactory.class)
public interface VehicleBuriedPointClient {
    /**
     * 推送埋点信息
     * @param event
     * @return
     */
    @PostMapping("/inner/vehicleBuriedPoint/sendVehicleEvent")
    R<String> sendVehicleEvent(@RequestBody VehicleEventDTO event);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java
@@ -1,9 +1,6 @@
package com.xiaopeng.api.model.order;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import com.xiaopeng.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -36,6 +33,7 @@
    private Long id;
    @ApiModelProperty(value = "用户id")
    @TableField(updateStrategy = FieldStrategy.NEVER)
    private Long appUserId;
    @ApiModelProperty(value = "用户id")
    private Long cityId;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/VehiclePosition.java
@@ -63,4 +63,8 @@
     * 订单id
     */
    private Long orderId;
    /**
     * 总里程
     */
    private Float totalOdometer;
}
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -32,8 +32,8 @@
com.xiaopeng.api.factory.automaticPilot.XPUClientFallbackFactory
com.xiaopeng.api.factory.automaticPilot.XpuVimClientFallbackFactory
com.xiaopeng.api.factory.automaticPilot.OrderMissionClientFallbackFactory
com.xiaopeng.api.factory.automaticPilot.VehicleBuriedPointClientFallbackFactory
com.xiaopeng.api.factory.maintenance.XpCheckLocationClientFallbackFactory
com.xiaopeng.api.factory.automaticPilot.OrderMissionClientFallbackFactory
com.xiaopeng.api.factory.maintenance.XpClockInClientFallbackFactory
com.xiaopeng.api.factory.account.SysGroupMenuClientFallbackFactory
com.xiaopeng.api.factory.order.XpCruiseOrderClientFallbackFactory
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -6,12 +6,14 @@
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;
import com.xiaopeng.api.dto.pushMessage.PushOrderRouteDTO;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto;
import com.xiaopeng.api.feignClient.automaticPilot.VehicleBuriedPointClient;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
@@ -59,6 +61,8 @@
    private RedisService redisService;
    @Resource
    private XpVehicleClient xpVehicleClient;
    @Resource
    private VehicleBuriedPointClient vehicleBuriedPointClient;
    @Resource(name = "hutoolSnowflake")
    private Snowflake snowflake;
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/VehicleBuriedPointController.java
New file
@@ -0,0 +1,31 @@
package com.xiaopeng.automaticPilot.controller;
import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO;
import com.xiaopeng.automaticPilot.util.VehicleBuriedPointProducer;
import com.xiaopeng.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@RequestMapping("")
public class VehicleBuriedPointController {
    @Autowired
    private VehicleBuriedPointProducer vehicleBuriedPointProducer;
    /**
     * 推送埋点信息
     * @param event
     * @return
     */
    @PostMapping("/inner/vehicleBuriedPoint/sendVehicleEvent")
    public R<String> sendVehicleEvent(@RequestBody VehicleEventDTO event){
        vehicleBuriedPointProducer.sendVehicleEvent(event);
        return R.ok();
    }
}
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -6,6 +6,7 @@
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO;
import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
import com.xiaopeng.api.dto.operation.CruisePointDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
@@ -15,6 +16,7 @@
import com.xiaopeng.api.dto.pushMessage.PushOrderRouteDTO;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto;
import com.xiaopeng.api.feignClient.automaticPilot.VehicleBuriedPointClient;
import com.xiaopeng.api.feignClient.maintenance.XpTaskClient;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.operation.ReassignOrderClient;
@@ -113,6 +115,8 @@
    @Resource
    private XpTaskClient xpTaskClient;
    @Resource
    private VehicleBuriedPointClient vehicleBuriedPointClient;
    @Resource
    private XpTestOrderClient testOrderClient;
@@ -353,6 +357,7 @@
                vehiclePosition.setCurrentElectricity(dynamicStatus.getBmsSocDisp());
                vehiclePosition.setMileageRange(dynamicStatus.getDstBatDisp());
                vehiclePosition.setOrderId(orderId);
                vehiclePosition.setTotalOdometer(dynamicStatus.getTotalOdometer());
                mongoTemplate.save(vehiclePosition);
            }else{
                vehiclePosition.setOrderId(orderId);
@@ -364,7 +369,8 @@
                        .set("currentElectricity", dynamicStatus.getBmsSocDisp())
                        .set("mileageRange", dynamicStatus.getDstBatDisp())
                        .set("hasOrder", hasOrder)
                        .set("orderId", orderId);
                        .set("orderId", orderId)
                        .set("totalOdometer", dynamicStatus.getTotalOdometer());
                mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class);
            }
            //调用推送服务接口
@@ -995,6 +1001,39 @@
                case ORDER_COMPLETED:
                    //已完成
                    log.info("已完成,不做任何处理:{}", orderId);
                    if(!orderId.contains("XU")){
                        XpOrder xpOrder = xpOrderClient.queryOrderById(Long.valueOf(orderId)).getData();
                        if (Objects.nonNull(xpOrder)){
                            // 查询车辆
                            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
                            if (Objects.nonNull(xpVehicle)){
                                String vin = xpVehicle.getVehicleVin();
                                // 封装埋点消息实体
                                VehicleEventDTO vehicleEventDTO = new VehicleEventDTO();
                                vehicleEventDTO.setVin(vin);
                                vehicleEventDTO.setXpuId("");
                                vehicleEventDTO.setOrderId(orderId);
                                vehicleEventDTO.setEventKey("RT_xpu_vehicle_trace_upload");
                                vehicleEventDTO.setEventTime(System.currentTimeMillis());
                                Map<String,Object> attributes = new HashMap<>();
                                attributes.put("vin",vin);
                                attributes.put("order_id",vehicleEventDTO.getOrderId());
                                attributes.put("order_type","user_order");
                                attributes.put("timestamp",vehicleEventDTO.getEventTime());
                                attributes.put("current_main_status",OrderStatus.ORDER_COMPLETED);
                                attributes.put("current_sub_status","");
                                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class);
                                if(Objects.nonNull(vehiclePosition)){
                                    attributes.put("odometer_km",vehiclePosition.getTotalOdometer());
                                }else {
                                    attributes.put("odometer_km","");
                                }
                                vehicleEventDTO.setAttributes(attributes);
                                vehicleBuriedPointClient.sendVehicleEvent(vehicleEventDTO);
                                log.info("已完成,推送埋点:{}", orderId);
                            }
                        }
                    }
                    break;
                case ORDER_CANCELLED:
                    //已取消
@@ -1029,6 +1068,38 @@
                    //到达巡游终点
                    if(orderId.contains("XU")){
                        buildPushOrderStatus(orderId, OrderStatusEnum.COMPLETED, sequence);
                        String cruiseOrderId = orderId.substring(2);
                        XpCruiseOrder xpCruiseOrder = xpCruiseOrderClient.getCruiseOrder(Long.parseLong(cruiseOrderId)).getData();
                        if (Objects.nonNull(xpCruiseOrder)){
                            // 查询车辆
                            XpVehicle xpVehicle = xpVehicleClient.queryById(xpCruiseOrder.getVehicleId()).getData();
                            if (Objects.nonNull(xpVehicle)){
                                String vin = xpVehicle.getVehicleVin();
                                // 封装埋点消息实体
                                VehicleEventDTO vehicleEventDTO = new VehicleEventDTO();
                                vehicleEventDTO.setVin(vin);
                                vehicleEventDTO.setXpuId("");
                                vehicleEventDTO.setOrderId(cruiseOrderId);
                                vehicleEventDTO.setEventKey("RT_xpu_vehicle_trace_upload");
                                vehicleEventDTO.setEventTime(System.currentTimeMillis());
                                Map<String,Object> attributes = new HashMap<>();
                                attributes.put("vin",vin);
                                attributes.put("order_id",vehicleEventDTO.getOrderId());
                                attributes.put("order_type","cruise_order");
                                attributes.put("timestamp",vehicleEventDTO.getEventTime());
                                attributes.put("current_main_status",OrderStatus.ORDER_ARRIVED_AT_CRUISE_DESTINATION);
                                attributes.put("current_sub_status","");
                                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class);
                                if(Objects.nonNull(vehiclePosition)){
                                    attributes.put("odometer_km",vehiclePosition.getTotalOdometer());
                                }else {
                                    attributes.put("odometer_km","");
                                }
                                vehicleEventDTO.setAttributes(attributes);
                                vehicleBuriedPointClient.sendVehicleEvent(vehicleEventDTO);
                                log.info("到达巡游终点,推送埋点:{}", orderId);
                            }
                        }
                    }else if(orderId.contains("TEST")){
                        //测试巡游单处理逻辑
                        testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.COMPLETED.getCode());
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/KafkaSendUtils.java
New file
@@ -0,0 +1,83 @@
package com.xiaopeng.automaticPilot.util;
//import io.growing.sdk.java.GrowingAPI;
//import io.growing.sdk.java.dto.GIOMessage;
//import io.growing.sdk.java.dto.GioCdpEventMessage;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class KafkaSendUtils {
//    private static final GrowingAPI project = new GrowingAPI.Builder().setProjectKey("89a922449121f7c2").setDataSourceId("9365c3d2f397f172").build();
    /**
     *
     * 车辆状态变更   触发时机:车辆主状态或子状态发生变化的瞬间。
     * 发送数据到GrowingIO
     *
     * @param map
     */
//    public static void sendVehicleStatusChanged(Map<String, Object> map) {
//        // Config GrowingIO
//        // 参数需要从CDP增长平台上,创建新应用,或从已创建的数据源中获取, 如不清楚请联系您的专属项目经理
//        // YourAccountId eg: 89a922449121f7c2
//        // YourDatasourceId eg: 9365c3d2f397f172
//        //事件行为消息体,anonymousId 和 loginUserId 参数,不能同时为空
//        GioCdpEventMessage eventMessage = new GioCdpEventMessage.Builder()
//                .eventTime(System.currentTimeMillis())            // 默认为系统当前时间 (选填)
//                .eventKey("RT_web_vehicle_status_changed")                             // 事件标识 (必填)
////                .domain("com.growingio.app")                      // App包名或H5域名(选填)
////                .urlScheme("growing.123c12fb12f123cc")            // 链接协议(选填)
////                .deviceBrand("google")                            // 设备品牌(选填)
////                .deviceModel("Nexus 5")                           // 设备型号(选填)
////                .deviceType("PHONE")                              // 设备类型(选填)
////                .appVersion("1.2.4")                              // App版本(选填)
////                .appName("看数助手")                               // App名称(选填)
//                .language("zh_CN")                                // 语言(选填)
//                .anonymousId("device_id")                         // 访问用户ID (选填)
////                .loginUserKey("account")  // 登录用户KEY (选填,需有规划并在平台配置后再上报)
//                .loginUserId("417abcabcabcbac")                   // 登录用户ID (选填)
////                .addEventVariable("product_name", "cdp苹果")       // 事件属性 (选填)
////                .addEventVariable("product_classify", Arrays.asList("苹果", "香蕉"))       // 事件属性 (选填)
//                .addEventVariables(map)                           // 事件属性集合 (选填)
////                .addItem("itemId", "itemKey")                     // 物品模型ID, KEY (选填)
//                .build();
//
//        //上传事件行为消息到服务器
//        project.send(eventMessage);
//    }
    /**
     *
     * 订单状态变更
     * 开始接单,上报一次
     * 订单结束,上报一次
     * 发送数据到GrowingIO
     *
     */
//    public static void sendVehicleTraceUpload(Map<String, Object> map) {
//        //事件行为消息体,anonymousId 和 loginUserId 参数,不能同时为空
//        GioCdpEventMessage eventMessage = new GioCdpEventMessage.Builder()
//                .eventTime(System.currentTimeMillis())            // 默认为系统当前时间 (选填)
//                .eventKey("RT_xpu_vehicle_trace_upload")                             // 事件标识 (必填)
//                .language("zh_CN")                                // 语言(选填)
//                .addEventVariables(map)                           // 事件属性集合 (选填)
//                .build();
//        //上传事件行为消息到服务器
//        project.send(eventMessage);
//    }
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("vin", "L1NSPGHB7SB018421");
        map.put("order_id", "");
        map.put("timestamp", System.currentTimeMillis());
        map.put("sub_status", "");
        map.put("prev_sub_status", "");
//        sendVehicleStatusChanged(map);
    }
}
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/VehicleBuriedPointProducer.java
New file
@@ -0,0 +1,161 @@
package com.xiaopeng.automaticPilot.util;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Future;
@Slf4j
@Component
public class VehicleBuriedPointProducer {
    // 预发环境 Kafka 集群
    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;
    // 目标 Topic
    private static final String TOPIC = "topic-robotaxi-vehicle-buriedPoint";
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    private Properties kafkaProperties;
    @PostConstruct
    public void init() {
        kafkaProperties = buildProperties();
    }
    /**
     * 发送埋点消息
     *
     * @param event
     * @throws Exception
     */
    public void sendVehicleEvent(VehicleEventDTO event){
        if (kafkaProperties == null) {
            kafkaProperties = buildProperties();
        }
        KafkaProducer<String, String> producer = new KafkaProducer<>(kafkaProperties);
        try {
            // 转 JSON
            String messageBody = OBJECT_MAPPER.writeValueAsString(event);
            // 建议用 vin 作为 key(保证同车有序)
            ProducerRecord<String, String> record =
                    new ProducerRecord<>(TOPIC, event.getVin(), messageBody);
            Future<RecordMetadata> future = producer.send(record);
            RecordMetadata metadata = future.get();
            log.info("发送成功:");
            log.info("Topic: " + metadata.topic());
            log.info("Partition: " + metadata.partition());
            log.info("Offset: " + metadata.offset());
        } catch (Exception e) {
            log.error("发送失败:{}", e.getMessage());
            e.printStackTrace();
        } finally {
            producer.close();
        }
    }
    /**
     * 构造埋点消息体
     *
     * @param vin
     * @param orderId
     * @param xpuId
     * @param eventKey
     * @param eventTime
     * @param extraAttributes
     * @return
     */
    public VehicleEventDTO buildVehicleEvent(String vin, String orderId, String xpuId,
                                          String eventKey, Long eventTime,
                                          Map<String, Object> extraAttributes) {
        VehicleEventDTO event = new VehicleEventDTO();
        event.setVin(vin);
        event.setXpuId(xpuId != null ? xpuId : "");
        event.setOrderId(orderId != null ? orderId : "");
        event.setEventKey(eventKey);
        event.setEventTime(eventTime != null ? eventTime : System.currentTimeMillis());
        Map<String, Object> attributes = new HashMap<>();
        attributes.put("vin", vin);
        attributes.put("order_id", orderId != null ? orderId : "");
        attributes.put("timestamp", event.getEventTime());
        if (extraAttributes != null) {
            attributes.putAll(extraAttributes);
        }
        event.setAttributes(attributes);
        return event;
    }
    private Properties buildProperties() {
        Properties props = new Properties();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        // 生产建议配置
        props.put(ProducerConfig.ACKS_CONFIG, "all");
        props.put(ProducerConfig.RETRIES_CONFIG, 3);
        props.put(ProducerConfig.LINGER_MS_CONFIG, 5);
        props.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);
        props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true);
        return props;
    }
//    public static void main(String[] args) throws Exception {
//
//        long timeMillis = System.currentTimeMillis();
//
//        // 构造埋点消息体(示例)
//        VehicleEvent event = new VehicleEvent();
//        event.setVin("L1NSPGHB7SB018421");
//        event.setXpuId("");
//        event.setOrderId("");
//        event.setEventKey("RT_web_vehicle_status_changed");
//        event.setEventTime(timeMillis);
//
//        Map<String, Object> attributes = new HashMap<>();
//        attributes.put("vin", "L1NSPGHB7SB018421");
//        attributes.put("order_id", "");
//        attributes.put("timestamp", timeMillis);
//        attributes.put("sub_status", "");
//        attributes.put("prev_sub_status", "");
//        event.setAttributes(attributes);
//
//        // 转 JSON
//        String messageBody = OBJECT_MAPPER.writeValueAsString(event);
//
//        // 建议用 vin 作为 key(保证同车有序)
//        ProducerRecord<String, String> record =
//                new ProducerRecord<>(TOPIC, event.getVin(), messageBody);
//
//        try {
//            Future<RecordMetadata> future = producer.send(record);
//            RecordMetadata metadata = future.get();
//
//            System.out.println("发送成功:");
//            System.out.println("Topic: " + metadata.topic());
//            System.out.println("Partition: " + metadata.partition());
//            System.out.println("Offset: " + metadata.offset());
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            producer.close();
//        }
//    }
}
xp-robotaxi-automatic-pilot-boot/src/main/resources/gio.properties
New file
@@ -0,0 +1,26 @@
#项目采集端地址
api.host=https://collect.test.xiaopeng.com
#消息发送间隔时间,单位ms(默认 100)
send.msg.interval=100
#消息发送线程数量 (默认 3)
send.msg.thread=3
#消息队列大小 (默认 500)
msg.store.queue.size=500
#日志级别输出 (debug | error)
logger.level=debug
#自定义日志输出实现类
logger.implementation=io.growing.sdk.java.logger.GioLoggerImpl
#运行模式,test:仅输出消息体,不发送消息,production: 发送消息
#run.mode=test
run.mode=production
# 设置代理, 如果不设置,默认为不使用代理
#proxy.host=127.0.0.1
#proxy.port=3128
# 设置代理认证用户密码, 如果不设置,默认为不使用用户验证
#proxy.user=demo
#proxy.password=demo
#http 连接超时时间
#connection.timeout=2000
#http 连接读取时间
#read.timeout=2000
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleOperationsController.java
@@ -1,7 +1,9 @@
package com.xiaopeng.maintenance.controller;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO;
import com.xiaopeng.api.dto.operation.NewCruiseOrderDto;
import com.xiaopeng.api.feignClient.automaticPilot.VehicleBuriedPointClient;
import com.xiaopeng.api.feignClient.operation.XpCruisePlanClient;
import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
@@ -32,6 +34,8 @@
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
/**
 * <p>
@@ -58,6 +62,8 @@
    private AliOssService aliOssService;
    @Autowired
    private XpCruisePlanClient xpCruisePlanClient;
    @Autowired
    private VehicleBuriedPointClient vehicleBuriedPointClient;
    /**
     * 车辆详情-车辆调度-发车 收车
@@ -77,11 +83,38 @@
        if(vehiclePosition==null || vehiclePosition.getPoint()==null){
            return R.fail("车辆位置信息不存在");
        }
        Integer departureStatus = dto.getDepartureStatus();
        XpVehicle vehicle1 = new XpVehicle();
        vehicle1.setOperatingStatus(dto.getDepartureStatus());
        vehicle1.setOperatingStatus(departureStatus);
        vehicle1.setId(xpVehicle.getId());
        xpVehicleClient.updateVehicleById(vehicle1);
        // 封装埋点消息实体
        VehicleEventDTO vehicleEventDTO = new VehicleEventDTO();
        vehicleEventDTO.setVin(xpVehicle.getVehicleVin());
        vehicleEventDTO.setXpuId("");
        vehicleEventDTO.setOrderId("");
        vehicleEventDTO.setEventKey("RT_web_vehicle_status_changed");
        vehicleEventDTO.setEventTime(System.currentTimeMillis());
        Map<String,Object> attributes = new HashMap<>();
        attributes.put("vin",xpVehicle.getVehicleVin());
        attributes.put("order_id","");
        attributes.put("timestamp",vehicleEventDTO.getEventTime());
        if(departureStatus == 1){
            attributes.put("main_status","ONLINE");
            // TODO 预留位置 目前无状态
            attributes.put("sub_status","");
            attributes.put("prev_sub_status","");
        }else {
            attributes.put("main_status","OFFLINE");
            // TODO 预留位置 目前无状态
            attributes.put("sub_status","");
            attributes.put("prev_sub_status","");
        }
        vehicleEventDTO.setAttributes(attributes);
        vehicleBuriedPointClient.sendVehicleEvent(vehicleEventDTO);
        // 发车
        if(dto.getDepartureStatus()==1){
            // 找车辆的任务  生成巡游单子 下发命令
@@ -123,7 +156,6 @@
            if(returnCruisePoint!=null){
                xpCruiseOrderClient.addCruiseOrder(returnCruisePoint);
            }
        }
        return R.ok();
    }
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -152,7 +152,8 @@
            if (StringUtils.isNotBlank(vehiclePictures)) {
                JSONObject jsonObject = JSONObject.parseObject(vehiclePictures);
                //1
                    String downloadUrl = jsonObject.getString("url");;
                String downloadUrl = jsonObject.getString("url");
                ;
                try {
                    downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (UnsupportedEncodingException e) {
@@ -209,7 +210,6 @@
        pageInfo.setRecords(list);
        return pageInfo;
    }
    @Override
@@ -448,7 +448,8 @@
                if (Objects.isNull(jsonObject)) {
                    continue;
                }
                String downloadUrl = jsonObject.getString("url");;
                String downloadUrl = jsonObject.getString("url");
                ;
                try {
                    downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (UnsupportedEncodingException e) {
@@ -461,6 +462,7 @@
        return R.ok(res);
    }
    @ShardingSphereTransactionType(TransactionType.BASE)
    @Transactional(rollbackFor = Exception.class)
    @Override
@@ -554,7 +556,8 @@
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                // 1
                String downloadUrl = jsonObject.getString("url");;
                String downloadUrl = jsonObject.getString("url");
                ;
                try {
                    downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (UnsupportedEncodingException e) {
@@ -613,7 +616,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
@@ -628,8 +632,6 @@
            res.setEndRemainingBattery(chargingRecord.getEndRemainingBattery());
            String endChargingPicture = chargingRecord.getEndChargingPicture();
            if (StringUtils.isNotBlank(endChargingPicture)) {
                JSONArray jsonArray = JSONArray.parseArray(endChargingPicture);
@@ -638,7 +640,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
@@ -709,7 +712,6 @@
            res.setRepairReason(vehicleRepair.getRepairReason());
            String startRepairPicture = vehicleRepair.getStartRepairPicture();
            if (StringUtils.isNotBlank(startRepairPicture)) {
                JSONArray jsonArray = JSONArray.parseArray(startRepairPicture);
@@ -718,7 +720,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
@@ -855,7 +858,6 @@
            res.setSensorCleaning(vehicleDetection.getSensorCleaning());
            String SensorCleaningPicture = vehicleDetection.getSensorCleaningPicture();
            if (StringUtils.isNotBlank(SensorCleaningPicture)) {
                JSONArray jsonArray = JSONArray.parseArray(SensorCleaningPicture);
@@ -876,10 +878,8 @@
            }
            res.setInteractiveScreen(vehicleDetection.getInteractiveScreen());
            String InteractiveScreenPicture =vehicleDetection.getInteractiveScreenPicture();
            String InteractiveScreenPicture = vehicleDetection.getInteractiveScreenPicture();
            if (StringUtils.isNotBlank(InteractiveScreenPicture)) {
                JSONArray jsonArray = JSONArray.parseArray(InteractiveScreenPicture);
                for (int i = 0; i < jsonArray.size(); i++) {
@@ -887,7 +887,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
@@ -899,13 +900,10 @@
            }
            res.setHelpButton(vehicleDetection.getHelpButton());
            String HelpButtonPicture =vehicleDetection.getHelpButtonPicture();
            String HelpButtonPicture = vehicleDetection.getHelpButtonPicture();
            if (StringUtils.isNotBlank(HelpButtonPicture)) {
                JSONArray jsonArray = JSONArray.parseArray(HelpButtonPicture);
                for (int i = 0; i < jsonArray.size(); i++) {
@@ -913,7 +911,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
@@ -927,8 +926,7 @@
            res.setPaymentFunction(vehicleDetection.getPaymentFunction());
            String PaymentFunctionPicture =vehicleDetection.getPaymentFunctionPicture();
            String PaymentFunctionPicture = vehicleDetection.getPaymentFunctionPicture();
            if (StringUtils.isNotBlank(PaymentFunctionPicture)) {
                JSONArray jsonArray = JSONArray.parseArray(PaymentFunctionPicture);
                for (int i = 0; i < jsonArray.size(); i++) {
@@ -936,7 +934,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
@@ -950,7 +949,7 @@
            res.setSystemCheck(vehicleDetection.getSystemCheck());
            String SystemCheckPicture =vehicleDetection.getSystemCheckPicture();
            String SystemCheckPicture = vehicleDetection.getSystemCheckPicture();
            if (StringUtils.isNotBlank(SystemCheckPicture)) {
                JSONArray jsonArray = JSONArray.parseArray(SystemCheckPicture);
                for (int i = 0; i < jsonArray.size(); i++) {
@@ -958,7 +957,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
@@ -1056,7 +1056,6 @@
            res.setHandleTime(vehicleDetection.getCreateTime());
            res.setTaskImage(vehicleDetection.getTaskImage());
            String taskImage = res.getTaskImage();
@@ -1067,7 +1066,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
@@ -1289,7 +1289,7 @@
        for (XpTaskRecordVO record : records) {
            String taskImage =record.getTaskImage();
            String taskImage = record.getTaskImage();
            if (StringUtils.isNotBlank(taskImage)) {
                JSONArray jsonArray = JSONArray.parseArray(taskImage);
                for (int i = 0; i < jsonArray.size(); i++) {
@@ -1297,7 +1297,8 @@
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");;
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        // 1
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
@@ -1310,7 +1311,6 @@
            }
        }
        pageInfo.setRecords(records);
@@ -1341,10 +1341,10 @@
        PageInfo<TaskManagementPageListVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        List<TaskManagementPageListVO> list = this.baseMapper.pageListManagement(pageInfo, query);
        for (TaskManagementPageListVO taskManagementPageListVO : list) {
            if (org.springframework.util.StringUtils.hasLength(taskManagementPageListVO.getHandleUserId())){
            if (org.springframework.util.StringUtils.hasLength(taskManagementPageListVO.getHandleUserId())) {
                String[] split = taskManagementPageListVO.getHandleUserId().split(",");
                List<XpOperationsUser> users = operationUserClient.listByIds(Arrays.stream(split).map(Long::parseLong).collect(Collectors.toList())).getData();
                if (users!=null){
                if (users != null) {
                    StringBuilder handleUserName = new StringBuilder();
                    for (XpOperationsUser user : users) {
                        handleUserName.append(user.getNickName()).append(";");
@@ -1415,10 +1415,10 @@
    public List<TaskManagementPageListVO> exportList(TaskManagementPageListQuery query) {
        List<TaskManagementPageListVO> list = this.baseMapper.exportList(query);
        for (TaskManagementPageListVO taskManagementPageListVO : list) {
            if (org.springframework.util.StringUtils.hasLength(taskManagementPageListVO.getHandleUserId())){
            if (org.springframework.util.StringUtils.hasLength(taskManagementPageListVO.getHandleUserId())) {
                String[] split = taskManagementPageListVO.getHandleUserId().split(",");
                List<XpOperationsUser> users = operationUserClient.listByIds(Arrays.stream(split).map(Long::parseLong).collect(Collectors.toList())).getData();
                if (users!=null){
                if (users != null) {
                    StringBuilder handleUserName = new StringBuilder();
                    for (XpOperationsUser user : users) {
                        handleUserName.append(user.getNickName()).append(";");
@@ -1619,15 +1619,15 @@
                    taskManagementDetectionDetailVO.setVehicleVin(vehicle.getVehicleVin());
                    taskManagementDetectionDetailVO.setVehicleLocation(task.getVehicleLocation());
                    if(vehicle.getVehiclePictures()!=null){
                    if (vehicle.getVehiclePictures() != null) {
                        JSONObject jsonObject = JSONObject.parseObject(vehicle.getVehiclePictures());
                        // 1
                            String downloadUrl = jsonObject.getString("url");;
                try {
                    downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (UnsupportedEncodingException e) {
                    log.error("获取图片下载地址失败", e);
                }
                        String downloadUrl = jsonObject.getString("url");
                        try {
                            downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                        } catch (UnsupportedEncodingException e) {
                            log.error("获取图片下载地址失败", e);
                        }
                        jsonObject.put("url", downloadUrl);
                        taskManagementDetectionDetailVO.setVehiclePictures(jsonObject.toJSONString());
                    }
@@ -1653,7 +1653,7 @@
                                if (Objects.isNull(jsonObject)) {
                                    continue;
                                }
                                String downloadUrl = jsonObject.getString("url");;
                                String downloadUrl = jsonObject.getString("url");
                                try {
                                    downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                                } catch (UnsupportedEncodingException e) {
@@ -1665,11 +1665,10 @@
                        }
                        taskManagementDetectionDetailVO.setInteractiveScreen(vehicleDetection.getInteractiveScreen());
                        String InteractiveScreenPicture =vehicleDetection.getInteractiveScreenPicture();
                        String InteractiveScreenPicture = vehicleDetection.getInteractiveScreenPicture();
                        if (StringUtils.isNotBlank(InteractiveScreenPicture)) {
                            JSONArray jsonArray = JSONArray.parseArray(InteractiveScreenPicture);
                            for (int i = 0; i < jsonArray.size(); i++) {
@@ -1677,7 +1676,7 @@
                                if (Objects.isNull(jsonObject)) {
                                    continue;
                                }
                                String downloadUrl = jsonObject.getString("url");;
                                String downloadUrl = jsonObject.getString("url");
                                try {
                                    downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                                } catch (UnsupportedEncodingException e) {
@@ -1691,7 +1690,7 @@
                        taskManagementDetectionDetailVO.setHelpButton(vehicleDetection.getHelpButton());
                        String HelpButtonPicture =vehicleDetection.getHelpButtonPicture();
                        String HelpButtonPicture = vehicleDetection.getHelpButtonPicture();
                        if (StringUtils.isNotBlank(HelpButtonPicture)) {
                            JSONArray jsonArray = JSONArray.parseArray(HelpButtonPicture);
                            for (int i = 0; i < jsonArray.size(); i++) {
@@ -1713,7 +1712,7 @@
                        taskManagementDetectionDetailVO.setPaymentFunction(vehicleDetection.getPaymentFunction());
                        String PaymentFunctionPicture =vehicleDetection.getPaymentFunctionPicture();
                        String PaymentFunctionPicture = vehicleDetection.getPaymentFunctionPicture();
                        if (StringUtils.isNotBlank(PaymentFunctionPicture)) {
                            JSONArray jsonArray = JSONArray.parseArray(PaymentFunctionPicture);
                            for (int i = 0; i < jsonArray.size(); i++) {
@@ -1736,7 +1735,7 @@
                        taskManagementDetectionDetailVO.setSystemCheck(vehicleDetection.getSystemCheck());
                        String SystemCheckPicture =vehicleDetection.getSystemCheckPicture();
                        String SystemCheckPicture = vehicleDetection.getSystemCheckPicture();
                        if (StringUtils.isNotBlank(SystemCheckPicture)) {
                            JSONArray jsonArray = JSONArray.parseArray(SystemCheckPicture);
                            for (int i = 0; i < jsonArray.size(); i++) {
@@ -1744,7 +1743,8 @@
                                if (Objects.isNull(jsonObject)) {
                                    continue;
                                }
                                String downloadUrl = jsonObject.getString("url");;
                                String downloadUrl = jsonObject.getString("url");
                                ;
                                try {
                                    downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                                } catch (UnsupportedEncodingException e) {
@@ -1975,7 +1975,27 @@
            res.setErrorTypeList(xpErrorTypes);
            res.setStatus(task.getStatus());
            res.setTaskDescription(task.getTaskDescription());
            res.setTaskImage(task.getTaskImage());
            String taskImage = res.getTaskImage();
            if (StringUtils.isNotBlank(taskImage)) {
                JSONArray jsonArray = JSONArray.parseArray(taskImage);
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (Objects.isNull(jsonObject)) {
                        continue;
                    }
                    String downloadUrl = jsonObject.getString("url");
                    ;
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (UnsupportedEncodingException e) {
                        log.error("获取图片下载地址失败", e);
                    }
                    jsonObject.put("url", downloadUrl);
                }
                res.setTaskImage(JSONArray.toJSONString(jsonArray));
            }
            res.setId(id);
            res.setVehicleId(vehicle.getId());
            res.setTaskUrgencyLevel(task.getTaskUrgencyLevel());
@@ -1984,14 +2004,14 @@
            res.setVehicleCode(vehicle.getVehicleCode());
            res.setVehicleLocation(task.getVehicleLocation());
            res.setVehicleVin(vehicle.getVehicleVin());
            if (task.getReportUserId().equals(0L)){
            if (task.getReportUserId().equals(0L)) {
                // 系统补偿上传车辆异常任务 为系统创建
                res.setReportUserId(0L);
                res.setReportUserName("系统");
                // todo 临时设置 待客户确认默认头像和电话号码
                res.setReportUserPhone("111111");
                res.setReportUserAvatar("[]");
            }else{
            } else {
                if (Objects.nonNull(task.getTaskSource()) && task.getTaskSource().equals(2)) {
                    List<SysUser> list = sysUserClient.listByIds(Lists.newArrayList(task.getReportUserId())).getData();
                    if (CollUtil.isNotEmpty(list)) {
@@ -2000,9 +2020,9 @@
                        res.setReportUserName(sysUser.getNickName());
                        res.setReportUserPhone(sysUser.getPhoneNumber());
                    }
                }else{
                } else {
                    XpOperationsUser data = xpOperationUserClient.queryById(task.getReportUserId()).getData();
                    if (data != null ) {
                    if (data != null) {
                        res.setReportUserId(data.getId());
                        res.setReportUserName(data.getNickName());
                        res.setReportUserPhone(data.getPhoneNumber());
@@ -2011,7 +2031,7 @@
                }
            }
            if (task.getHandleUserId()!=null && task.getHandleUserId().split(",").length == 1) {
            if (task.getHandleUserId() != null && task.getHandleUserId().split(",").length == 1) {
                XpOperationsUser operationsUser = xpOperationUserClient.queryById(Long.valueOf(task.getHandleUserId())).getData();
                if (operationsUser != null) {
                    res.setHandleUserId(operationsUser.getId());
@@ -2037,7 +2057,6 @@
            managementDetailVO.setAccidentDetailVO(res);
        }
        return R.ok(managementDetailVO);
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpTaskMapper.xml
@@ -58,7 +58,7 @@
        updateTime,t1.create_by as createBy,t1.update_by as updateBy,t2.plate_number as plateNumber
        from xp_task t1
        left join xp_vehicle t2 on t1.vehicle_id = t2.id
        where t1.is_deleted = 0 and (t1.task_category =1 and t1.status != 2)
        where t1.is_deleted = 0 and ((t1.task_category = 2 and t1.status != 2) OR t1.task_category = 1)
        <if test="query.taskCategory != null">
            and t1.task_category = #{query.taskCategory}
        </if>
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/exportExcel/XpCruiseOrderExportExcel.java
@@ -22,14 +22,11 @@
    @Excel(name = "下单时间", width = 20, exportFormat = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @Excel(name = "订单来源", width = 15, replace = {"小鹏小程序_1"})
    private String orderSource;
    @Excel(name = "起点", width = 30)
    private String startAddress;
    private String startPointName;
    @Excel(name = "终点", width = 30)
    private String endAddress;
    private String endPointName;
    @Excel(name = "接单车辆", width = 15)
    private String plateNumber;
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -15,6 +15,7 @@
import com.xiaopeng.api.dto.account.UcUserInfo;
import com.xiaopeng.api.dto.account.UseUserCouponDto;
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO;
import com.xiaopeng.api.dto.operation.CruisePointDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
@@ -31,6 +32,7 @@
import com.xiaopeng.api.feignClient.account.UserResourcesClient;
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient;
import com.xiaopeng.api.feignClient.automaticPilot.VehicleBuriedPointClient;
import com.xiaopeng.api.feignClient.maintenance.XpTaskRuleClient;
import com.xiaopeng.api.feignClient.operation.XpCruisePlanClient;
import com.xiaopeng.api.feignClient.operation.XpPointClient;
@@ -153,6 +155,7 @@
    private final XpCruisePlanClient xpCruisePlanClient;
    private final XpPricingUtil xpPricingUtil;
    private final GDMapGeocodingUtil gdMapGeocodingUtil;
    private final VehicleBuriedPointClient vehicleBuriedPointClient;
    private final IXpTestOrderService xpTestOrderService;
@@ -2220,7 +2223,7 @@
    /**
     * 取消订单后的继续巡游任务
     * @param vehicle
     * @param vehicleId
     */
    public void addCruiseMission(Long vehicleId) {
        XpVehicle vehicle = xpVehicleClient.queryById(vehicleId).getData();
@@ -2841,6 +2844,29 @@
                xpCruiseOrder.setVehicleId(null);
                xpCruiseOrderMapper.updateById(xpCruiseOrder);
                log.info("修改巡游单状态,开始执行巡游单 {}", dto.getOrderId());
                // 封装埋点消息实体
                VehicleEventDTO vehicleEventDTO = new VehicleEventDTO();
                vehicleEventDTO.setVin(dto.getXpVehicleVin());
                vehicleEventDTO.setXpuId("");
                vehicleEventDTO.setOrderId(String.valueOf(dto.getOrderId()));
                vehicleEventDTO.setEventKey("RT_xpu_vehicle_trace_upload");
                vehicleEventDTO.setEventTime(System.currentTimeMillis());
                Map<String,Object> attributes = new HashMap<>();
                attributes.put("vin",vehicleEventDTO.getVin());
                attributes.put("order_id",vehicleEventDTO.getOrderId());
                attributes.put("order_type","cruise_order");
                attributes.put("timestamp",vehicleEventDTO.getEventTime());
                attributes.put("current_main_status",OrderStatus.ORDER_STARTED);
                attributes.put("current_sub_status","");
                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(dto.getXpVehicleVin())), VehiclePosition.class);
                if(Objects.nonNull(vehiclePosition)){
                    attributes.put("odometer_km",vehiclePosition.getTotalOdometer());
                }else {
                    attributes.put("odometer_km","");
                }
                vehicleEventDTO.setAttributes(attributes);
                vehicleBuriedPointClient.sendVehicleEvent(vehicleEventDTO);
                log.info("巡游单埋点消息,开始执行推送: {}", dto.getOrderId());
            }
        }
        //乘客单处理逻辑
@@ -2922,6 +2948,33 @@
                //推送乘客车辆到达预约点的导航数据
                sendRoute(addTaxiPassengerVo.getUid(), orderId, "ORDER_NAVIGATION_START_DATA", dto.getXpVehicleVin());
            }
            if(order.getStatus() == 2){
                // 封装埋点消息实体
                VehicleEventDTO vehicleEventDTO = new VehicleEventDTO();
                vehicleEventDTO.setVin(dto.getXpVehicleVin());
                vehicleEventDTO.setXpuId("");
                vehicleEventDTO.setOrderId(String.valueOf(dto.getOrderId()));
                vehicleEventDTO.setEventKey("RT_xpu_vehicle_trace_upload");
                vehicleEventDTO.setEventTime(System.currentTimeMillis());
                Map<String,Object> attributes = new HashMap<>();
                attributes.put("vin",vehicleEventDTO.getVin());
                attributes.put("order_id",vehicleEventDTO.getOrderId());
                attributes.put("order_type","user_order");
                attributes.put("timestamp",vehicleEventDTO.getEventTime());
                attributes.put("current_main_status",OrderStatus.ORDER_EN_ROUTE_TO_PICKUP);
                attributes.put("current_sub_status","");
                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(dto.getXpVehicleVin())), VehiclePosition.class);
                if(Objects.nonNull(vehiclePosition)){
                    attributes.put("odometer_km",vehiclePosition.getTotalOdometer());
                }else {
                    attributes.put("odometer_km","");
                }
                vehicleEventDTO.setAttributes(attributes);
                vehicleBuriedPointClient.sendVehicleEvent(vehicleEventDTO);
                log.info("用户单埋点消息,开始执行推送: {}", dto.getOrderId());
            }
        }
        //测试订单
        if (OrderType.TEST_ORDER.equals(orderType)) {
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpPolicyApplicationServiceImpl.java
@@ -2,6 +2,7 @@
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -19,6 +20,7 @@
import com.xiaopeng.common.core.enums.PolicyApplicationAuditStateEnum;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.utils.SecurityUtils;
import com.xiaopeng.evi.oss.service.AliOssService;
import com.xiaopeng.vehicleConvoy.mapper.XpPolicyApplicationMapper;
import com.xiaopeng.vehicleConvoy.mapper.XpVehicleMapper;
import com.xiaopeng.vehicleConvoy.model.dto.XpPolicyApplicationAuditDTO;
@@ -34,6 +36,7 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
@@ -56,7 +59,7 @@
    private final XpVehicleClient xpVehicleClient;
    private final SysUserClient sysUserClient;
    private final XpVehicleMapper xpVehicleMapper;
    private final AliOssService aliOssService;
    @Override
    public PageInfo<XpPolicyApplicationVO> pageList(XpPolicyApplicationQuery query) {
        PageInfo<XpPolicyApplicationVO> resultPage = new PageInfo<>(query.getPageNum(), query.getPageSize());
@@ -256,8 +259,19 @@
                xpPolicyApplicationVO.setPlateNumber(xpVehicle.getPlateNumber());
                xpPolicyApplicationVO.setVehicleCode(xpVehicle.getVehicleCode());
                xpPolicyApplicationVO.setAuditRemarks(xpPolicyApplication.getAuditRemarks());
                if (xpPolicyApplicationVO.getAuditStatus() == 2) {
                    xpPolicyApplicationVO.setPolicyInformation(xpVehicle.getPolicyInformation());
                if (xpPolicyApplicationVO.getAuditStatus() == 2 && StringUtils.isNotBlank(xpVehicle.getPolicyInformation())) {
                    JSONObject jsonObject = JSONObject.parseObject(xpVehicle.getPolicyInformation());
                    if(jsonObject!=null){
                        String downloadUrl = null;
                        try {
                            // 1
                            downloadUrl= aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        jsonObject.put("url", downloadUrl);
                        xpPolicyApplicationVO.setPolicyInformation(jsonObject.toJSONString());
                    }
                }
            }
            queryPolicyInfoVO.setStatus(xpPolicyApplication.getAuditStatus());
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -35,6 +35,7 @@
import com.xiaopeng.common.core.utils.GeodesyUtil;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.evi.oss.service.AliOssService;
import com.xiaopeng.vehicleConvoy.constant.I18nKeyConstant;
import com.xiaopeng.vehicleConvoy.mapper.XpFleetMapper;
import com.xiaopeng.vehicleConvoy.mapper.XpFleetOperationsMapper;
@@ -108,6 +109,8 @@
    private RedisService redisService;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private AliOssService aliOssService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
@@ -213,6 +216,20 @@
                xpVehicleVO.setCurrentElectricity(0);
                xpVehicleVO.setLongitude(104.056302);
                xpVehicleVO.setLatitude(30.586688);
            }
            if (org.springframework.util.StringUtils.hasLength(xpVehicleVO.getVehiclePictures())) {
                JSONObject jsonObject = JSONObject.parseObject(xpVehicleVO.getVehiclePictures());
                if(jsonObject!=null){
                    String downloadUrl = null;
                    try {
                        // 1
                        downloadUrl= aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    jsonObject.put("url", downloadUrl);
                    xpVehicleVO.setVehiclePictures(jsonObject.toJSONString());
                }
            }
        }
@@ -1015,7 +1032,7 @@
    public Boolean getVehicleTrunkOpenStatus(Long uid, Long id) {
        XpVehicle xpVehicle = this.getById(id);
        try {
            VehicleTemperatureDto vehicleTemperatureDto = vehicleControlUtil.queryVehicleTemperature(uid.toString(), xpVehicle.getVehicleVin());
            VehicleTemperatureDto vehicleTemperatureDto = vehicleControlUtil.queryVehicleTemperature(String.valueOf(uid), xpVehicle.getVehicleVin());
            log.info("查询车辆温度成功:{}", vehicleTemperatureDto);
            VehicleStateVo trunkAjarCloseSt = vehicleTemperatureDto.getStateMap().get("trunkAjarCloseSt");
            if(null == trunkAjarCloseSt){