From 9adef3dd7723930d44f72713c3cf28e50b002055 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期三, 01 四月 2026 15:45:19 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi
---
xp-robotaxi-remote-driving-boot/pom.xml | 4
xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties | 3
xp-robotaxi-order-boot/pom.xml | 4
xp-robotaxi-automatic-pilot-boot/pom.xml | 4
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java | 303 +++++++++++++++----
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java | 24
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java | 148 +++++++++
xp-robotaxi-maintenance-boot/pom.xml | 9
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java | 2
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpTestPlanAddDTO.java | 6
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java | 14
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/enums/CancelOrderSceneEnum.java | 31 ++
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java | 53 ++-
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/MapMatchingUtil.java | 15
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java | 4
xp-robotaxi-operation-boot/pom.xml | 4
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpTestPlanServiceImpl.java | 7
xp-robotaxi-payment-boot/pom.xml | 4
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java | 9
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java | 89 +++--
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java | 28 +
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java | 26 +
xp-robotaxi-push-message-boot/pom.xml | 4
xp-robotaxi-vehicle-convoy-boot/pom.xml | 4
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrackPoint.java | 26 +
xp-robotaxi-itinerary-boot/pom.xml | 4
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpTestOrderController.java | 2
xp-robotaxi-account-boot/pom.xml | 4
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java | 37 +
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpTestPlanPoint.java | 3
xp-robotaxi-map-boot/pom.xml | 4
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/PushOrderDto.java | 6
32 files changed, 696 insertions(+), 189 deletions(-)
diff --git a/xp-robotaxi-account-boot/pom.xml b/xp-robotaxi-account-boot/pom.xml
index 7334e2a..8223ed1 100644
--- a/xp-robotaxi-account-boot/pom.xml
+++ b/xp-robotaxi-account-boot/pom.xml
@@ -119,6 +119,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/PushOrderDto.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/PushOrderDto.java
index c10d4c1..2fa1af6 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/PushOrderDto.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/PushOrderDto.java
@@ -12,6 +12,9 @@
@AllArgsConstructor
@NoArgsConstructor
public class PushOrderDto {
+ @ApiModelProperty("任务id")
+ private String taskId;
+
@ApiModelProperty("车辆vin")
private String vin;
@@ -41,4 +44,7 @@
* 订单操作类型
*/
private OrderOperationType operation_type;
+
+ @ApiModelProperty("取消场景")
+ private String cancelScene;
}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpTestPlanPoint.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpTestPlanPoint.java
index 18a7e8a..5f90909 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpTestPlanPoint.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpTestPlanPoint.java
@@ -44,9 +44,6 @@
@ApiModelProperty(value = "是否停车 0-否 1-是")
private Integer stopFlag;
- @ApiModelProperty(value = "测试订单id")
- private Long testOrderId;
-
@ApiModelProperty(value = "测试订单类型(1=测试单,2=巡游单)")
private Long testOrderType;
diff --git a/xp-robotaxi-automatic-pilot-boot/pom.xml b/xp-robotaxi-automatic-pilot-boot/pom.xml
index da3ab04..944d2da 100644
--- a/xp-robotaxi-automatic-pilot-boot/pom.xml
+++ b/xp-robotaxi-automatic-pilot-boot/pom.xml
@@ -116,6 +116,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
index a60ebd0..c8612f4 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -26,6 +26,7 @@
import com.xiaopeng.api.vo.order.OrderTrajectoryVo;
import com.xiaopeng.automaticPilot.util.XPUUtil;
import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.common.core.enums.CancelOrderSceneEnum;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.common.core.utils.StringUtils;
@@ -265,13 +266,7 @@
if(null != mqttPublishDto && mqttPublishDto.getCode() == 200){
JSONObject jsonObject = new JSONObject();
jsonObject.put("event", SystemEventType.CREATE_ORDER);
- if(dto.getOrderId().contains("XU")){
- jsonObject.put("orderType", com.xiaopeng.api.vo.OrderType.CRUISE_ORDER);
- }else if(dto.getOrderId().contains("TEST")){
- jsonObject.put("orderType", com.xiaopeng.api.vo.OrderType.TEST_ORDER);
- }else {
- jsonObject.put("orderType", com.xiaopeng.api.vo.OrderType.USER_ORDER);
- }
+ jsonObject.put("orderType", dto.getOrderType());
jsonObject.put("orderId", dto.getOrderId());
jsonObject.put("vin", dto.getVin());
redisService.setCacheObject("CREATE_ORDER:" + dto.getOrderId().toString(), jsonObject.toJSONString(),30L, TimeUnit.MINUTES);
@@ -282,9 +277,10 @@
@PostMapping("/inner/cancelOrder")
R<Boolean> cancelOrder(@RequestBody PushOrderDto dto) {
+ String taskId = StringUtils.isNotEmpty(dto.getTaskId()) ? dto.getTaskId() : snowflake.nextId() + "";
OrderOperation.Builder operationBuilder = OrderOperation.newBuilder();
operationBuilder.setOrderId(dto.getOrderId().toString());
- operationBuilder.setTaskId(snowflake.nextId() + "");
+ operationBuilder.setTaskId(taskId);
if (dto.getOperation_type() != null) {
operationBuilder.setOperationType(OrderOperationType.forNumber(dto.getOperation_type().getNumber()));
}
@@ -294,8 +290,16 @@
if (mqttPublishDto.getCode() == 200) {
if(!dto.getOrderId().contains("XU")){
- // 正常订单处理
- redisService.setCacheObject(String.valueOf(sequence), "cancelOrder_" + dto.getOrderId() + "_" + dto.getVin(), 30l, TimeUnit.MINUTES);
+ Map<String, Object> cancelContext = new HashMap<>();
+ cancelContext.put("orderId", dto.getOrderId());
+ cancelContext.put("vin", dto.getVin());
+ cancelContext.put("cancelScene", StringUtils.isNotEmpty(dto.getCancelScene())
+ ? dto.getCancelScene()
+ : CancelOrderSceneEnum.NORMAL_CANCEL.getCode());
+ redisService.setCacheObject("CANCEL_ORDER_CONTEXT:" + taskId,
+ JSONObject.toJSONString(cancelContext), 30L, TimeUnit.MINUTES);
+ log.info("记录取消订单上下文成功,orderId: {}, vin: {}, taskId: {}, cancelScene: {}",
+ dto.getOrderId(), dto.getVin(), taskId, cancelContext.get("cancelScene"));
}
return R.ok(true);
}
diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
index 73ad12f..b79d9e2 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -42,6 +42,7 @@
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.constant.Constants;
import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.common.core.enums.CancelOrderSceneEnum;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.common.core.utils.StringUtils;
@@ -71,6 +72,8 @@
@Slf4j
@Service
public class KafkaConsumerService {
+ private static final String CANCEL_ORDER_CONTEXT_PREFIX = "CANCEL_ORDER_CONTEXT:";
+
@Resource
private XpMapClient xpMapClient;
@@ -441,6 +444,7 @@
}
}else if(orderId.contains("TEST")){
//测试订单故障则取消订单
+ testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), 0);
XpTestOrder testOrder = testOrderClient.queryOrderById(Long.parseLong(orderId.substring(4))).getData();
vehicle = xpVehicleClient.queryById(testOrder.getVehicleId()).getData();
if (vehicle != null) {
@@ -591,6 +595,79 @@
vehicleId = xpCruiseOrder.getVehicleId();
+ } else if(orderId.contains("TEST")){
+ R<XpTestOrder> cruiseOrder = testOrderClient.queryOrderById(Long.parseLong(orderId.substring(4)));
+ XpTestOrder testOrder = cruiseOrder.getData();
+ //区分测试单和测试巡游单
+ if(1 == testOrder.getOrderType()){
+ orderType = OrderType.TEST_ORDER;
+ //驶往上车点的行程
+ if (3 == testOrder.getStatus()) {
+ //查询司机当前位置到起点的线路
+ origin.setLongitude(longitude);
+ origin.setLatitude(latitude);
+ destination.setLongitude(testOrder.getStartLon());
+ destination.setLatitude(testOrder.getStartLat());
+
+ OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
+ dto.setOrderId(Long.parseLong(orderId.substring(4)));
+ dto.setOrigin(origin);
+ dto.setDestination(destination);
+ dto.setRouteType(1);
+ R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
+ if (200 != routeVoR.getCode()) {
+ throw new RuntimeException("获取订单线路和运费失败");
+ }
+ RouteVo routeVo = routeVoR.getData();
+ routeID = routeVo.getRouteID();
+ //缓存数据,用于后续推给乘客导航线路
+ redisService.setCacheObject("TEST_ORDER_NAVIGATION_START_DATA:" + testOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
+ }
+ //驶往下车点的行程
+ if (6 == testOrder.getStatus()) {
+ origin.setLongitude(longitude);
+ origin.setLatitude(latitude);
+ destination.setLongitude(testOrder.getEndLon());
+ destination.setLatitude(testOrder.getEndLat());
+
+ OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
+ dto.setOrderId(Long.parseLong(orderId.substring(4)));
+ dto.setOrigin(origin);
+ dto.setDestination(destination);
+ dto.setRouteType(2);
+ R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
+ if (200 != routeVoR.getCode()) {
+ throw new RuntimeException("获取订单线路和运费失败");
+ }
+ RouteVo routeVo = routeVoR.getData();
+ routeID = routeVo.getRouteID();
+ //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据
+ redisService.setCacheObject("TEST_ORDER_NAVIGATION_END_DATA:" + testOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
+ }
+
+ }else{
+ orderType = OrderType.TEST_CRUISE_ORDER;
+
+ //构建导航数据给到车端
+ origin.setLongitude(longitude);
+ origin.setLatitude(latitude);
+ destination.setLongitude(testOrder.getEndLon());
+ destination.setLatitude(testOrder.getEndLat());
+
+ OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
+ dto.setOrderId(Long.parseLong(orderId.substring(4)));
+ dto.setOrigin(origin);
+ dto.setDestination(destination);
+ dto.setRouteType(3);
+ R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
+ if (200 != routeVoR.getCode()) {
+ throw new RuntimeException("获取订单线路和运费失败");
+ }
+ RouteVo routeVo = routeVoR.getData();
+ routeID = routeVo.getRouteID();
+
+ vehicleId = testOrder.getVehicleId();
+ }
} else {
orderType = OrderType.USER_ORDER;
//正常单
@@ -701,77 +778,100 @@
vehicleId = xpCruiseOrder.getVehicleId();
}
} else if(orderId.contains("TEST")){
- orderType = OrderType.TEST_ORDER;
- //正常单
- R<XpTestOrder> xpOrderR = testOrderClient.queryOrderById(Long.parseLong(orderId.substring(4)));
- if (200 != xpOrderR.getCode()) {
- throw new RuntimeException("订单不存在 " + orderId);
- }
- XpTestOrder xpOrder = xpOrderR.getData();
- XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
- //驶往上车点的行程
- if (orderPhase.equals(OrderPhase.ROUTE_TO_PICKUP)) {
- //直接取缓存中的导航数据推送给车端和乘客
- Object cacheObject = redisService.getCacheObject("TEST_ORDER_NAVIGATION_START_DATA:" + xpOrder.getVehicleId());
- if(null == cacheObject){
- //没有缓存数据,重新规划线路
- //查询车辆位置
- VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class);
- if (Objects.isNull(vehiclePosition)) {
- throw new RuntimeException("车辆位置信息不存在");
+ R<XpTestOrder> cruiseOrder = testOrderClient.queryOrderById(Long.parseLong(orderId.substring(4)));
+ XpTestOrder testOrder = cruiseOrder.getData();
+ XpVehicle xpVehicle = xpVehicleClient.queryById(testOrder.getVehicleId()).getData();
+ //区分测试单和测试巡游单
+ if(1 == testOrder.getOrderType()){
+ orderType = OrderType.TEST_ORDER;
+ //驶往上车点的行程
+ if (orderPhase.equals(OrderPhase.ROUTE_TO_PICKUP)) {
+ //直接取缓存中的导航数据推送给车端和乘客
+ Object cacheObject = redisService.getCacheObject("TEST_ORDER_NAVIGATION_START_DATA:" + testOrder.getVehicleId());
+ if(null == cacheObject){
+ //没有缓存数据,重新规划线路
+ //查询车辆位置
+ VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class);
+ if (Objects.isNull(vehiclePosition)) {
+ throw new RuntimeException("车辆位置信息不存在");
+ }
+ origin.setLongitude(vehiclePosition.getPoint().getX());
+ origin.setLatitude(vehiclePosition.getPoint().getY());
+ destination.setLongitude(testOrder.getStartLon());
+ destination.setLatitude(testOrder.getStartLat());
+ OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
+ dto.setOrderId(Long.parseLong(orderId.substring(4)));
+ dto.setOrigin(origin);
+ dto.setDestination(destination);
+ dto.setRouteType(2);
+ R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
+ if (200 != routeVoR.getCode()) {
+ throw new RuntimeException("获取订单线路和运费失败");
+ }
+ RouteVo routeVo = routeVoR.getData();
+ routeID = routeVo.getRouteID();
+ //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据
+ redisService.setCacheObject("TEST_ORDER_NAVIGATION_START_DATA:" + testOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
+ }else{
+ RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
+ routeID = routeVo.getRouteID();
}
- origin.setLongitude(vehiclePosition.getPoint().getX());
- origin.setLatitude(vehiclePosition.getPoint().getY());
- destination.setLongitude(xpOrder.getStartLon());
- destination.setLatitude(xpOrder.getStartLat());
+ }
+ //驶往下车点的行程
+ if (orderPhase.equals(OrderPhase.ROUTE_TO_DESTINATION)) {
+ //直接取缓存中的导航数据推送给车端和乘客
+ Object cacheObject = redisService.getCacheObject("TEST_ORDER_NAVIGATION_END_DATA:" + testOrder.getVehicleId());
+ if(null == cacheObject){
+ //没有缓存数据,重新规划线路
+ //查询起点到终点的线路
+ origin.setLongitude(testOrder.getStartLon());
+ origin.setLatitude(testOrder.getStartLat());
+ destination.setLongitude(testOrder.getEndLon());
+ destination.setLatitude(testOrder.getEndLat());
+ OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
+ dto.setOrderId(Long.parseLong(orderId.substring(4)));
+ dto.setOrigin(origin);
+ dto.setDestination(destination);
+ dto.setRouteType(2);
+ R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
+ if (200 != routeVoR.getCode()) {
+ throw new RuntimeException("获取订单线路和运费失败");
+ }
+ RouteVo routeVo = routeVoR.getData();
+ routeID = routeVo.getRouteID();
+ //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据
+ redisService.setCacheObject("TEST_ORDER_NAVIGATION_END_DATA:" + testOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
+ }else{
+ RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
+ routeID = routeVo.getRouteID();
+ }
+ }
+
+ }else{
+ orderType = OrderType.TEST_CRUISE_ORDER;
+
+ //巡游单
+ if (orderPhase.equals(OrderPhase.ROUTE_TO_CRUISE)) {
+ /* 构建导航数据给到车端 */
+ origin.setLongitude(testOrder.getStartLon());
+ origin.setLatitude(testOrder.getStartLat());
+ destination.setLongitude(testOrder.getEndLon());
+ destination.setLatitude(testOrder.getEndLat());
+
OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
- dto.setOrderId(Long.parseLong(orderId));
+ dto.setOrderId(Long.parseLong(orderId.substring(4)));
dto.setOrigin(origin);
dto.setDestination(destination);
- dto.setRouteType(2);
+ dto.setRouteType(3);
R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
if (200 != routeVoR.getCode()) {
throw new RuntimeException("获取订单线路和运费失败");
}
RouteVo routeVo = routeVoR.getData();
routeID = routeVo.getRouteID();
- //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据
- redisService.setCacheObject("TEST_ORDER_NAVIGATION_START_DATA:" + xpOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
- }else{
- RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
- routeID = routeVo.getRouteID();
}
}
- //驶往下车点的行程
- if (orderPhase.equals(OrderPhase.ROUTE_TO_DESTINATION)) {
- //直接取缓存中的导航数据推送给车端和乘客
- Object cacheObject = redisService.getCacheObject("TEST_ORDER_NAVIGATION_END_DATA:" + xpOrder.getVehicleId());
- if(null == cacheObject){
- //没有缓存数据,重新规划线路
- //查询起点到终点的线路
- origin.setLongitude(xpOrder.getStartLon());
- origin.setLatitude(xpOrder.getStartLat());
- destination.setLongitude(xpOrder.getEndLon());
- destination.setLatitude(xpOrder.getEndLat());
- OrderRouteAndFareDto dto = new OrderRouteAndFareDto();
- dto.setOrderId(Long.parseLong(orderId));
- dto.setOrigin(origin);
- dto.setDestination(destination);
- dto.setRouteType(2);
- R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto);
- if (200 != routeVoR.getCode()) {
- throw new RuntimeException("获取订单线路和运费失败");
- }
- RouteVo routeVo = routeVoR.getData();
- routeID = routeVo.getRouteID();
- //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据
- redisService.setCacheObject("TEST_ORDER_NAVIGATION_END_DATA:" + xpOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
- }else{
- RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
- routeID = routeVo.getRouteID();
- }
- }
- vehicleId = xpOrder.getVehicleId();
+ vehicleId = testOrder.getVehicleId();
}else{
orderType = OrderType.USER_ORDER;
//正常单
@@ -1024,10 +1124,6 @@
case ORDER_DROPOFF_COMPLETED:
//下车完成,不需要处理状态,由后续的乘客主动触发或者定时任务触发
log.info("乘客已下车,不做任何处理:{}", orderId);
-// if(!orderId.contains("XU")){
-// buildPushOrderStatus(orderId, OrderStatusEnum.APPROVAL_REJECTION, sequence);
-// xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.APPROVAL_REJECTION.getCode());
-// }
break;
case ORDER_COMPLETED:
//已完成
@@ -1069,17 +1165,36 @@
case ORDER_CANCELLED:
//已取消
if(!orderId.contains("XU")){
+ String taskId = orderStatusInfo.getTaskId();
+ JSONObject cancelContext = getCancelOrderContext(taskId);
+ if (shouldSkipCancelForReassign(cancelContext)) {
+ log.info("改派旧车取消回调,跳过订单取消处理,orderId: {}, taskId: {}, cancelScene: {}, context: {}",
+ orderId, taskId, cancelContext.getString("cancelScene"), cancelContext);
+ //响应消息
+ responseMessage(sequence, cancelContext.getString("vin"));
+ return;
+ }
if(orderId.contains("TEST")){
//判断订单状态,已经取消的不作处理
- Object cacheObject = redisService.getCacheObject("ORDER_STATUS:" + orderId.substring(4));
+ Object cacheObject = redisService.getCacheObject("TEST_ORDER_STATUS:" + orderId.substring(4));
if(null != cacheObject){
int order_status = Integer.parseInt(cacheObject.toString());
if(0 == order_status){
return;
}
}
+ XpTestOrder testOrder = testOrderClient.queryOrderById(Long.valueOf(orderId.substring(4))).getData();
+ if(testOrder.getStatus() == 0 || testOrder.getStatus() >= 8){
+ return;
+ }
//行程中取消订单,按照行程结束处理
- testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.SEE_OFF_GUESTS.getCode());
+ if(testOrder.getStatus() > 5 && testOrder.getStatus() < 8){
+ testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.SEE_OFF_GUESTS.getCode());
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + orderId.substring(4), OrderStatusEnum.SEE_OFF_GUESTS.getCode(), 24L, TimeUnit.HOURS);
+ }else{
+ testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.CANCELED.getCode());
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + orderId.substring(4), OrderStatusEnum.CANCELED.getCode(), 24L, TimeUnit.HOURS);
+ }
}else{
//判断订单状态,已经取消的不作处理
Object cacheObject = redisService.getCacheObject("ORDER_STATUS:" + orderId);
@@ -1089,9 +1204,20 @@
return;
}
}
- //行程中取消订单,按照行程结束处理
- buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence);
- xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode());
+ XpOrder xpOrder = xpOrderClient.queryOrderById(Long.parseLong(orderId)).getData();
+ if(xpOrder.getStatus() == 0 || xpOrder.getStatus() >= 8){
+ return;
+ }
+ if(xpOrder.getStatus() > 5 && xpOrder.getStatus() < 8){
+ //行程中取消订单,按照行程结束处理
+ buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence);
+ xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode());
+ redisService.setCacheObject("ORDER_STATUS:" + orderId.substring(4), OrderStatusEnum.SEE_OFF_GUESTS.getCode(), 24L, TimeUnit.HOURS);
+ }else{
+ buildPushOrderStatus(orderId, OrderStatusEnum.CANCELED, sequence);
+ xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.CANCELED.getCode());
+ redisService.setCacheObject("ORDER_STATUS:" + orderId.substring(4), OrderStatusEnum.CANCELED.getCode(), 24L, TimeUnit.HOURS);
+ }
}
}
break;
@@ -1132,8 +1258,16 @@
}
}
}else if(orderId.contains("TEST")){
- //测试巡游单处理逻辑
- testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.COMPLETED.getCode());
+ //测试巡游单完成状态
+ XpTestOrder testOrder = testOrderClient.queryOrderById(Long.parseLong(orderId.substring(4))).getData();
+ if(testOrder.getOrderType() == 2){
+ XpVehicle xpVehicle = xpVehicleClient.queryById(testOrder.getVehicleId()).getData();
+ //响应消息
+ responseMessage(sequence, xpVehicle.getVehicleVin());
+ //测试巡游单处理逻辑
+ testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.COMPLETED.getCode());
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + orderId.substring(4), OrderStatusEnum.COMPLETED.getCode(), 24L, TimeUnit.HOURS);
+ }
}
break;
case ORDER_PAUSED:
@@ -1248,6 +1382,35 @@
}
/**
+ * 根据taskId获取订单取消的上下文信息
+ * @param taskId
+ * @return
+ */
+ private JSONObject getCancelOrderContext(String taskId) {
+ if (StringUtils.isEmpty(taskId)) {
+ return null;
+ }
+ Object cacheObject = redisService.getCacheObject(CANCEL_ORDER_CONTEXT_PREFIX + taskId);
+ if (cacheObject == null) {
+ return null;
+ }
+ return JSON.parseObject(cacheObject.toString());
+ }
+
+ /**
+ * 判断是否是改派旧车取消回调,是则跳过订单取消处理
+ * @param cancelContext
+ * @return
+ */
+ private boolean shouldSkipCancelForReassign(JSONObject cancelContext) {
+ if (cancelContext == null) {
+ return false;
+ }
+ return CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE == CancelOrderSceneEnum.fromCode(
+ cancelContext.getString("cancelScene"));
+ }
+
+ /**
* 云端下发导航到XPU
* @param requestId XPU请求id
* @param routeId 高德导航id
diff --git a/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/enums/CancelOrderSceneEnum.java b/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/enums/CancelOrderSceneEnum.java
new file mode 100644
index 0000000..aa84da2
--- /dev/null
+++ b/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/enums/CancelOrderSceneEnum.java
@@ -0,0 +1,31 @@
+package com.xiaopeng.common.core.enums;
+
+import lombok.Getter;
+
+/**
+ * 取消订单场景
+ */
+public enum CancelOrderSceneEnum {
+
+ NORMAL_CANCEL("NORMAL_CANCEL"),
+ REASSIGN_OLD_VEHICLE("REASSIGN_OLD_VEHICLE");
+
+ @Getter
+ private final String code;
+
+ CancelOrderSceneEnum(String code) {
+ this.code = code;
+ }
+
+ public static CancelOrderSceneEnum fromCode(String code) {
+ if (code == null) {
+ return null;
+ }
+ for (CancelOrderSceneEnum scene : values()) {
+ if (scene.code.equals(code)) {
+ return scene;
+ }
+ }
+ return null;
+ }
+}
diff --git a/xp-robotaxi-itinerary-boot/pom.xml b/xp-robotaxi-itinerary-boot/pom.xml
index b5b31c0..640664f 100644
--- a/xp-robotaxi-itinerary-boot/pom.xml
+++ b/xp-robotaxi-itinerary-boot/pom.xml
@@ -112,6 +112,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-maintenance-boot/pom.xml b/xp-robotaxi-maintenance-boot/pom.xml
index 9b9987e..ad9cac3 100644
--- a/xp-robotaxi-maintenance-boot/pom.xml
+++ b/xp-robotaxi-maintenance-boot/pom.xml
@@ -154,6 +154,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
@@ -167,6 +171,11 @@
<version>1.33</version>
</dependency>
<dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.25.3</version>
+ </dependency>
+ <dependency>
<groupId>com.xiaopeng.logan</groupId>
<artifactId>xp-evi-oss-sdk</artifactId>
<version>1.0.1-SNAPSHOT</version>
diff --git a/xp-robotaxi-map-boot/pom.xml b/xp-robotaxi-map-boot/pom.xml
index beb307b..100d103 100644
--- a/xp-robotaxi-map-boot/pom.xml
+++ b/xp-robotaxi-map-boot/pom.xml
@@ -204,6 +204,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
index 182f38d..e230a15 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
@@ -139,15 +139,6 @@
if(routeVo==null){
return R.fail("没有找到路线");
}
-
- // 存储redis
- redisService.setCacheObject(CacheConstants.ORDER_ROUTE + "_" + dto.getOrderId() + "_" +dto.getRouteType(), routeVo);
- // 存储路线偏离缓存,后续进行轨迹截取
-// redisService.setCacheObject(CacheConstants.ORDER_ROUTE_CAPTURE + "_" + dto.getOrderId() + "_" +dto.getRouteType(), routeVo);
-
- // 存储路线偏离缓存,后续进行轨迹截取
- redisService.setCacheObject(CacheConstants.ORDER_ROUTE_CAPTURE + "_" + dto.getOrderId() + "_" +dto.getRouteType(), routeVo);
-
return R.ok(routeVo);
}
diff --git a/xp-robotaxi-operation-boot/pom.xml b/xp-robotaxi-operation-boot/pom.xml
index d73641b..10d12fd 100644
--- a/xp-robotaxi-operation-boot/pom.xml
+++ b/xp-robotaxi-operation-boot/pom.xml
@@ -192,6 +192,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpTestPlanAddDTO.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpTestPlanAddDTO.java
index e98e653..252ab8f 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpTestPlanAddDTO.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/dto/XpTestPlanAddDTO.java
@@ -40,6 +40,12 @@
@ApiModelProperty(value = "点位ID")
private Long endTestPointId;
+
+ @ApiModelProperty("是否停车")
+ private Integer stopFlag;
+
+ @ApiModelProperty("订单类型(1=测试单,2=巡游单)")
+ private Long testOrderType;
}
}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpTestPlanServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpTestPlanServiceImpl.java
index 2418c05..32de1e0 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpTestPlanServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpTestPlanServiceImpl.java
@@ -77,12 +77,12 @@
.list().stream().collect(Collectors.groupingBy(XpTestPlanVehicle::getTestPlanId)) : Collections.emptyMap();
page.getRecords().forEach(plan -> {
if(pointMap.size() > 0){
- plan.setPointNum(pointMap.get(plan.getId()).size());
+ plan.setPointNum(null == pointMap.get(plan.getId()) ? 0 : pointMap.get(plan.getId()).size());
}else{
plan.setPointNum(0);
}
if(vehicleMap.size() > 0){
- plan.setVehicleNum(vehicleMap.get(plan.getId()).size());
+ plan.setVehicleNum(null == vehicleMap.get(plan.getId()) ? 0 : vehicleMap.get(plan.getId()).size());
}else{
plan.setVehicleNum(0);
}
@@ -217,6 +217,7 @@
vo.setEndTestPointName(point1.getPointName());
vo.setEndTestPointAddress(point1.getPointAddress());
}
+ vo.setStopFlag(planPoint.getStopFlag());
return vo;
}).collect(Collectors.toList());
@@ -380,6 +381,8 @@
point.setTestPlanId(planId);
point.setStartTestPointId(pointDTO.getStartTestPointId());
point.setEndTestPointId(pointDTO.getEndTestPointId());
+ point.setStopFlag(pointDTO.getStopFlag());
+ point.setTestOrderType(pointDTO.getTestOrderType());
result.add(point);
}
return result;
diff --git a/xp-robotaxi-order-boot/pom.xml b/xp-robotaxi-order-boot/pom.xml
index b6759fe..7fa953a 100644
--- a/xp-robotaxi-order-boot/pom.xml
+++ b/xp-robotaxi-order-boot/pom.xml
@@ -119,6 +119,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpTestOrderController.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpTestOrderController.java
index ac8a695..a0fa8b5 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpTestOrderController.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpTestOrderController.java
@@ -85,7 +85,7 @@
* @param orderId 订单id
* @return 订单详情
*/
- @PostMapping("/inner/testOrder/queryOrderById")
+ @PostMapping("/inner/v1/testOrder/queryOrderById")
public R<XpTestOrder> queryOrderById(@RequestParam Long orderId){
XpTestOrder xpTestOrder = xpTestOrderService.getById(orderId);
return R.ok(xpTestOrder);
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java
index b66ea0b..0cbb1dd 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java
@@ -1,6 +1,7 @@
package com.xiaopeng.order.job.base;
import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient;
+import com.xiaopeng.api.feignClient.order.XpTestOrderClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
@@ -8,6 +9,7 @@
import com.xiaopeng.order.service.IXpCruiseOrderService;
import com.xiaopeng.order.service.IXpOrderService;
import com.xiaopeng.order.job.utils.SpringContextsUtil;
+import com.xiaopeng.order.service.IXpTestOrderService;
import com.xiaopeng.order.service.XpOrderTimeoutLogService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
@@ -28,6 +30,7 @@
protected OrderMissionClient orderMissionClient;
protected XpVehicleClient xpVehicleClient;
protected UserVehicleClient userVehicleClient;
+ protected IXpTestOrderService testOrderService;
public AbstractJob(){
this.xpOrderService = SpringContextsUtil.getBean(IXpOrderService.class);
this.xpPushMessageClient = SpringContextsUtil.getBean(XpPushMessageClient.class);
@@ -36,6 +39,7 @@
this.orderMissionClient = SpringContextsUtil.getBean(OrderMissionClient.class);
this.xpVehicleClient = SpringContextsUtil.getBean(XpVehicleClient.class);
this.userVehicleClient = SpringContextsUtil.getBean(UserVehicleClient.class);
+ this.testOrderService = SpringContextsUtil.getBean(IXpTestOrderService.class);
}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java
index 151dbb1..6a51bfe 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java
@@ -5,7 +5,9 @@
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.order.XpOrderTimeoutLog;
+import com.xiaopeng.api.model.order.XpTestOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
+import com.xiaopeng.api.vo.OrderType;
import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo;
import com.xiaopeng.common.core.constant.Constants;
import com.xiaopeng.common.core.domain.R;
@@ -39,49 +41,60 @@
throws JobExecutionException {
JobDataMap maps = context.getMergedJobDataMap();
Long orderId = maps.getLong("id");
+ String orderType = maps.getString("orderType");
try {
log.info("开始执行自动结束行程任务");
- XpOrder xpOrder = xpOrderService.getById(orderId);
- if(xpOrder.getStatus() == 7){
- xpOrderService.endTrip(xpOrder.getId(), String.valueOf(xpOrder.getAppUserId()));
- // 消息推送
- Map<String, Object> params = new HashMap<>();
- Map<String, Object> content = new HashMap<>();
- content.put("orderId", xpOrder.getId().toString());
- content.put("status", OrderStatusEnum.APPROVAL_REJECTION.getCode());
- params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
- params.put("content", com.alibaba.fastjson2.JSONObject.toJSONString(content));
- params.put("timestamp", new Date().getTime() + "");
- String message = JSONObject.toJSONString(params);
- SendMessageDTO sendMessageDTO = new SendMessageDTO();
- sendMessageDTO.setMessage(message);
- sendMessageDTO.setAppUserId(String.valueOf(xpOrder.getAppUserId()));
- R<String> stringR = xpPushMessageClient.sendStatus(sendMessageDTO);
- //推送失败,重试3次
- if(stringR.getCode() != Constants.SUCCESS){
- ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
- executor.execute(() -> {
- for (int i = 0; i < 3; i++) {
- R<String> stringR1 = xpPushMessageClient.sendStatus(sendMessageDTO);
- if(stringR1.getCode() == Constants.SUCCESS){
- break;
+ //用户订单
+ if(orderType.equals(OrderType.USER_ORDER)){
+ XpOrder xpOrder = xpOrderService.getById(orderId);
+ if(xpOrder.getStatus() == 7){
+ xpOrderService.endTrip(xpOrder.getId(), String.valueOf(xpOrder.getAppUserId()));
+ // 消息推送
+ Map<String, Object> params = new HashMap<>();
+ Map<String, Object> content = new HashMap<>();
+ content.put("orderId", xpOrder.getId().toString());
+ content.put("status", OrderStatusEnum.APPROVAL_REJECTION.getCode());
+ params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
+ params.put("content", com.alibaba.fastjson2.JSONObject.toJSONString(content));
+ params.put("timestamp", new Date().getTime() + "");
+ String message = JSONObject.toJSONString(params);
+ SendMessageDTO sendMessageDTO = new SendMessageDTO();
+ sendMessageDTO.setMessage(message);
+ sendMessageDTO.setAppUserId(String.valueOf(xpOrder.getAppUserId()));
+ R<String> stringR = xpPushMessageClient.sendStatus(sendMessageDTO);
+ //推送失败,重试3次
+ if(stringR.getCode() != Constants.SUCCESS){
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
+ executor.execute(() -> {
+ for (int i = 0; i < 3; i++) {
+ R<String> stringR1 = xpPushMessageClient.sendStatus(sendMessageDTO);
+ if(stringR1.getCode() == Constants.SUCCESS){
+ break;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ log.info("定时任务结束订单后,退订订单状态消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(sendMessageDTO), xpOrder.getOrderNumber());
}
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- log.info("定时任务结束订单后,退订订单状态消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(sendMessageDTO), xpOrder.getOrderNumber());
- }
- });
+ });
+ }
+ }
+ log.info("结束执行自动结束行程任务");
+ // 添加超时记录
+ XpOrderTimeoutLog xpOrderTimeoutLog = new XpOrderTimeoutLog();
+ xpOrderTimeoutLog.setOrderId(xpOrder.getId());
+ xpOrderTimeoutLog.setUserId(xpOrder.getAppUserId());
+ xpOrderTimeoutLogService.save(xpOrderTimeoutLog);
+ }
+ //测试订单
+ if(orderType.equals(OrderType.TEST_ORDER)){
+ XpTestOrder xpTestOrder = testOrderService.getById(orderId);
+ if(xpTestOrder.getStatus() == 7) {
+ testOrderService.endTrip(xpTestOrder.getId());
}
}
- log.info("结束执行自动结束行程任务");
- // 添加超时记录
- XpOrderTimeoutLog xpOrderTimeoutLog = new XpOrderTimeoutLog();
- xpOrderTimeoutLog.setOrderId(xpOrder.getId());
- xpOrderTimeoutLog.setUserId(xpOrder.getAppUserId());
- xpOrderTimeoutLogService.save(xpOrderTimeoutLog);
}catch(Exception e){
e.printStackTrace();
}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
index e645156..d2d3593 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -59,6 +59,7 @@
import com.xiaopeng.common.core.constant.Constants;
import com.xiaopeng.common.core.constant.HttpStatus;
import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.common.core.enums.CancelOrderSceneEnum;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.common.core.exception.ServiceException;
@@ -962,11 +963,14 @@
// 6.1.1 取消原订单指令
PushOrderDto cancelDto = new PushOrderDto();
+ cancelDto.setTaskId(IdUtil.getSnowflakeNextIdStr());
cancelDto.setOrderId(order.getId().toString());
cancelDto.setVin(oldVehicle.getVehicleVin());
cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
+ cancelDto.setCancelScene(CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE.getCode());
orderMissionClient.cancelOrder(cancelDto);
- log.info("已取消原车辆订单指令,订单ID: {}, VIN: {}", orderId, oldVehicle.getVehicleVin());
+ log.info("已取消原车辆订单指令,订单ID: {}, VIN: {}, taskId: {}, cancelScene: {}",
+ orderId, oldVehicle.getVehicleVin(), cancelDto.getTaskId(), cancelDto.getCancelScene());
// 6.1.2 解绑乘客与原车辆关系
if (Objects.nonNull(order.getAppUserId())) {
@@ -1673,6 +1677,7 @@
new ImmutableMap.Builder<String, String>()
.put("id", xpOrder.getId().toString())
.put("appid", appid)
+ .put("orderType", OrderType.USER_ORDER)
.build();
QuartzManager.addJob(
EndTripJob.class,
@@ -1688,6 +1693,7 @@
new ImmutableMap.Builder<String, String>()
.put("id", xpOrder.getId().toString())
.put("appid", appid)
+ .put("orderType", OrderType.USER_ORDER)
.build();
QuartzManager.addJob(
AddCruiseMissionJob.class,
@@ -3025,7 +3031,25 @@
xpTestOrder.setStartTestPointId(null);
xpTestOrderService.updateById(xpTestOrder);
- redisService.setCacheObject("ORDER_STATUS:" + xpTestOrder.getId(), 2, 24L, TimeUnit.HOURS);
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + xpTestOrder.getId(), 2, 24L, TimeUnit.HOURS);
+ }
+ }
+ if (OrderType.TEST_CRUISE_ORDER.equals(orderType)) {
+ XpTestOrder xpTestOrder = xpTestOrderService.getById(orderId);
+ //订单为待接单状态
+ if (xpTestOrder.getStatus() < 4) {
+ xpTestOrder.setAcceptanceTime(LocalDateTime.now());
+ R<XpVehicle> byVehicleVin = xpVehicleClient.findByVehicleVin(dto.getXpVehicleVin());
+ XpVehicle vehicle = null;
+ if (byVehicleVin.getCode() == 200) {
+ vehicle = byVehicleVin.getData();
+ xpTestOrder.setVehicleId(vehicle.getId());
+ xpTestOrder.setFleetId(vehicle.getFleetId());
+ }
+ xpTestOrder.setStatus(6);
+ xpTestOrder.setStartTestPointId(null);
+ xpTestOrderService.updateById(xpTestOrder);
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + xpTestOrder.getId(), 6, 24L, TimeUnit.HOURS);
}
}
}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java
index 7cf9015..1b41300 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java
@@ -264,7 +264,7 @@
xpOrder.setVehicleId(vehicleId);
xpOrder.setFleetId(xpVehicle.getFleetId());
this.save(xpOrder);
- redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), 1, 24L, TimeUnit.HOURS);
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + xpOrder.getId(), 1, 24L, TimeUnit.HOURS);
//缓存导航数据,用于下单后推送导航给车端和乘客端
redisService.setCacheObject("TEST_ORDER_NAVIGATION_END_DATA:" + vehicleId, JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
//下发XPU消息
@@ -590,7 +590,6 @@
* 取消订单
*/
private void cancelOrder(XpTestOrder order) {
- redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
//判断还原车辆状态
if (null == order.getVehicleId()) {
Object cacheObject1 = redisService.getCacheObject("CREATE_ORDER:" + order.getId().toString());
@@ -671,7 +670,7 @@
order.setDuration(new BigDecimal(duration).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
order.setStartTestPointId(null);
this.updateById(order);
- redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 7, 24L, TimeUnit.HOURS);
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + order.getId(), 7, 24L, TimeUnit.HOURS);
//给XPU推送订单取消的报文
PushOrderDto pushOrderDto = new PushOrderDto();
@@ -720,9 +719,9 @@
// 运营状态:1=运营中 2=维修中 3=已收车 4=车辆异常
// 当前模式:1=接单 2=测试
// 模式状态:1=开始接单/开始测试 2=停止接单/停止测试
- if (Objects.isNull(newVehicle.getStatus()) || newVehicle.getStatus() == 3) {
- throw new ServiceException("新车辆保险或年检已过期,无法接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_STATUS_INVALID);
- }
+// if (Objects.isNull(newVehicle.getStatus()) || newVehicle.getStatus() == 3) {
+// throw new ServiceException("新车辆保险或年检已过期,无法接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_STATUS_INVALID);
+// }
if (Objects.isNull(newVehicle.getOperatingStatus()) || newVehicle.getOperatingStatus() != 1) {
throw new ServiceException("新车辆运营状态异常,无法接单", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_OPERATING_STATUS_INVALID);
}
@@ -911,6 +910,7 @@
case 6:
// 行程开始时间
xpOrder.setTripBegin(LocalDateTime.now());
+ redisService.deleteObject("TEST_ORDER_NAVIGATION_START_DATA:" + xpOrder.getVehicleId());
break;
case 7:
xpOrder.setGetoffTime(LocalDateTime.now());
@@ -931,19 +931,36 @@
xpOrder.setMileageKilometers(new BigDecimal(reduce).divide(new BigDecimal(1000)).setScale(4, RoundingMode.HALF_EVEN).doubleValue());
long duration = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) - xpOrder.getTripBegin().toEpochSecond(ZoneOffset.of("+8"));
xpOrder.setDuration(new BigDecimal(duration).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
+
+ //创建定时结束订单和等待结束后下发巡游单的定时任务
+ Integer arriveTime = xpSystemSettingClient.getOrderFinishTime().getData();
+ // 添加自动结束行程定时任务job
+ Map<String, ? extends Object> endTripJobMaps =
+ new ImmutableMap.Builder<String, String>()
+ .put("id", xpOrder.getId().toString())
+ .put("orderType", OrderType.TEST_ORDER)
+ .build();
+ QuartzManager.addJob(
+ EndTripJob.class,
+ (EndTripJob.name + xpOrder.getId()).toUpperCase(),
+ TimeJobType.END_TRIP,
+ DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(arriveTime)),
+ endTripJobMaps
+ );
break;
}
xpOrder.setStatus(status);
xpOrder.setStartTestPointId(null);
this.updateById(xpOrder);
- redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), status, 24L, TimeUnit.HOURS);
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + xpOrder.getId(), status, 24L, TimeUnit.HOURS);
}else{
+ //测试巡游单,只需要修改状态
if(status == 10){
xpOrder.setStatus(status);
xpOrder.setStartTestPointId(null);
this.updateById(xpOrder);
- redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), status, 24L, TimeUnit.HOURS);
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + xpOrder.getId(), status, 24L, TimeUnit.HOURS);
}
}
return R.ok();
@@ -972,7 +989,7 @@
order.setStartTestPointId(null);
order.setTripEnd(LocalDateTime.now());
baseMapper.updateById(order);
- redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 8, 24L, TimeUnit.HOURS);
+ redisService.setCacheObject("TEST_ORDER_STATUS:" + order.getId(), 8, 24L, TimeUnit.HOURS);
// 根据订单所属开通城市id 查询定价
R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId());
@@ -1340,7 +1357,7 @@
@Override
public void saveVehicleLocation(OrderTrajectory orderTrajectory) {
// 查询订单信息
- Integer status = redisService.getCacheObject("ORDER_STATUS:" + orderTrajectory.getOrderId());
+ Integer status = redisService.getCacheObject("TEST_ORDER_STATUS:" + orderTrajectory.getOrderId());
if(status < 6 || status > 8){
return;
}
diff --git a/xp-robotaxi-payment-boot/pom.xml b/xp-robotaxi-payment-boot/pom.xml
index 1e98154..d49cad8 100644
--- a/xp-robotaxi-payment-boot/pom.xml
+++ b/xp-robotaxi-payment-boot/pom.xml
@@ -118,6 +118,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-push-message-boot/pom.xml b/xp-robotaxi-push-message-boot/pom.xml
index c0dff74..6862b9e 100644
--- a/xp-robotaxi-push-message-boot/pom.xml
+++ b/xp-robotaxi-push-message-boot/pom.xml
@@ -106,6 +106,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java
index 1142952..b6631d2 100644
--- a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java
+++ b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java
@@ -17,6 +17,8 @@
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.pushMessage.utils.MapMatchingUtil;
+import com.xiaopeng.pushMessage.utils.TrackPoint;
+import com.xiaopeng.pushMessage.utils.TrajectoryDensifier;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.powermock.core.ListMap;
@@ -27,6 +29,7 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import java.time.Instant;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
@@ -50,7 +53,7 @@
* 给乘客端推送剩余轨迹和剩余里程时长
* @return
*/
- @PostMapping("/inner/v1/order/pushOrderRoute")
+ @PostMapping("/logan/inner/v1/order/pushOrderRoute")
public R<String> pushOrderRoute(@Validated @RequestBody PushOrderRouteDTO dto) {
Integer routeType = dto.getRouteType();
//正常订单
@@ -66,8 +69,33 @@
}
Object cacheObject = redisService.getCacheObject(key);
RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
-
+ log.info("缓存获取的轨迹 {}", JSON.toJSONString(routeVo));
if(Objects.nonNull(routeVo)){
+ //开始对轨迹进行点位补全,然后更新缓存中的轨迹数据
+ if(xpOrder.getStatus() == 2 || xpOrder.getStatus() == 5){
+ List<LonLatDto> polyline = routeVo.getPolyline();
+ List<LonLatDto> new_polyline = new ArrayList<>();
+ for (int i = 0; i < polyline.size(); i++) {
+ if(i == polyline.size() - 1){
+ new_polyline.add(polyline.get(i));
+ break;
+ }
+ LonLatDto lonLatDto = polyline.get(i);
+ LonLatDto lonLatDto1 = polyline.get(i + 1);
+ //对两个点位进行坐标补全
+ List<TrackPoint> track = new ArrayList<>();
+ // 模拟数据:两个点相差 20 秒
+ track.add(new TrackPoint(lonLatDto.getLatitude(), lonLatDto.getLongitude(), null));
+ track.add(new TrackPoint(lonLatDto1.getLatitude(), lonLatDto1.getLongitude(), null));
+ //10米补全一个点位
+ List<TrackPoint> densified = TrajectoryDensifier.densifyByTime(track, 10);
+ for (TrackPoint trackPoint : densified) {
+ new_polyline.add(new LonLatDto(trackPoint.getLongitude(), trackPoint.getLatitude()));
+ }
+ }
+ routeVo.setPolyline(new_polyline);
+ redisService.setCacheObject(key, JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
+ }
Integer distance = dto.getDistance();
Integer duration = dto.getDuration();
// 计算实时点位到线段的最优截取
@@ -86,31 +114,16 @@
List<LonLatDto> lonLatDtos1 = remainingNavigation.get("served");
routeVo.setPolyline(lonLatDtos);
routeVo.setServed(lonLatDtos1);
-
+ log.info("线路截取后存储的轨迹 {}", JSON.toJSONString(routeVo));
// 存储最新路线偏离缓存,后续进行轨迹截取
redisService.setCacheObject(key, JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
- // 封装轨迹点位集合
- List<Map<String, Object>> polyline = new ArrayList<>();
- for (LonLatDto lonLatDto : lonLatDtos) {
- Map<String, Object> polylineMap = new HashMap<>();
- polylineMap.put("longitude",lonLatDto.getLongitude());
- polylineMap.put("latitude",lonLatDto.getLatitude());
- polyline.add(polylineMap);
- }
- List<Map<String, Object>> served = new ArrayList<>();
- for (LonLatDto lonLatDto : lonLatDtos1) {
- Map<String, Object> polylineMap = new HashMap<>();
- polylineMap.put("longitude",lonLatDto.getLongitude());
- polylineMap.put("latitude",lonLatDto.getLatitude());
- served.add(polylineMap);
- }
// 封装路由详情
Map<String, Object> route = new HashMap<>();
route.put("distance",distance);
route.put("duration",duration);
- route.put("polyline",JSONObject.toJSONString(polyline));
- route.put("served",JSONObject.toJSONString(served));
+ route.put("polyline",JSONObject.toJSONString(lonLatDtos));
+ route.put("served",JSONObject.toJSONString(lonLatDtos1));
Map<String, Object> content = new HashMap<>();
content.put("orderId",dto.getOrderId().toString());
diff --git a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/MapMatchingUtil.java b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/MapMatchingUtil.java
index 7bddf2b..422ed98 100644
--- a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/MapMatchingUtil.java
+++ b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/MapMatchingUtil.java
@@ -43,8 +43,6 @@
return map;
}
//大于5米的情况,将车子当前位置添加进结果中
- lonLatDto = new LonLatDto(longitude, latitude);
- polyline.add(0, lonLatDto);
map.put("unserved", polyline);
map.put("served", Collections.emptyList());
return map;
@@ -65,6 +63,9 @@
public static Map<String, List<LonLatDto>> getRecentlyPoint(List<LonLatDto> polyline, Double longitude, Double latitude){
Map<String, List<LonLatDto>> map = new HashMap<>();
for (int i = 0; i < polyline.size(); i++) {
+ if(i == polyline.size() - 1){
+ break;
+ }
LonLatDto lonLatDto1 = polyline.get(i);
GlobalCoordinates source1 = new GlobalCoordinates(lonLatDto1.getLatitude(), lonLatDto1.getLongitude());
@@ -86,17 +87,15 @@
//判断当前位置是否处于两个点位之间
if((distance1 + distance2) == distance3 || (distance1 + distance2) <= distance3 + 5){
- //剩余未服务的点位
- List<LonLatDto> lonLatDtos = polyline.subList(i + 1, polyline.size());
- lonLatDtos.add(0, new LonLatDto(longitude, latitude));
- //已经服务的点位,给到前端处理
- List<LonLatDto> lonLatDtos1 = polyline.subList(0, i + 1);
+ //剩余未服务的点位(创建新副本避免修改原列表)
+ List<LonLatDto> lonLatDtos = new ArrayList<>(polyline.subList(i + 1, polyline.size()));
+ //已经服务的点位,给到前端处理(创建新副本避免修改原列表)
+ List<LonLatDto> lonLatDtos1 = new ArrayList<>(polyline.subList(0, i + 1));
map.put("unserved", lonLatDtos);
map.put("served", lonLatDtos1);
return map;
}
}
- polyline.add(0, new LonLatDto(longitude, latitude));
map.put("unserved", polyline);
map.put("served", Collections.emptyList());
return map;
diff --git a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrackPoint.java b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrackPoint.java
new file mode 100644
index 0000000..896d4db
--- /dev/null
+++ b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrackPoint.java
@@ -0,0 +1,26 @@
+package com.xiaopeng.pushMessage.utils;
+
+import java.time.Instant;
+
+public class TrackPoint {
+
+ private double latitude; // 纬度
+ private double longitude; // 经度
+ private Instant timestamp; // 时间戳
+
+ public TrackPoint(double latitude, double longitude, Instant timestamp) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.timestamp = timestamp;
+ }
+
+ public double getLatitude() { return latitude; }
+ public double getLongitude() { return longitude; }
+ public Instant getTimestamp() { return timestamp; }
+
+ @Override
+ public String toString() {
+ return String.format("Point[%.6f, %.6f, %s]", latitude, longitude, timestamp);
+ }
+
+}
diff --git a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java
new file mode 100644
index 0000000..a8d033d
--- /dev/null
+++ b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java
@@ -0,0 +1,148 @@
+package com.xiaopeng.pushMessage.utils;
+
+import org.gavaghan.geodesy.Ellipsoid;
+import org.gavaghan.geodesy.GeodeticCalculator;
+import org.gavaghan.geodesy.GeodeticCurve;
+import org.gavaghan.geodesy.GlobalCoordinates;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TrajectoryDensifier {
+
+
+ /**
+ * 轨迹补密主方法
+ * @param originalPoints 原始轨迹点列表(必须按时间排序)
+ * @param distance 补密的间隔距离,例如每 5 米补一个点
+ * @return 补密后的轨迹列表
+ */
+ public static List<TrackPoint> densifyByTime(List<TrackPoint> originalPoints, int distance) {
+ List<TrackPoint> result = new ArrayList<>();
+ if (originalPoints == null || originalPoints.size() < 2) {
+ return originalPoints;
+ }
+
+ // 添加第一个点
+ result.add(originalPoints.get(0));
+
+ for (int i = 0; i < originalPoints.size() - 1; i++) {
+ TrackPoint start = originalPoints.get(i);
+ TrackPoint end = originalPoints.get(i + 1);
+
+ GlobalCoordinates source1 = new GlobalCoordinates(start.getLatitude(), start.getLongitude());
+ GlobalCoordinates target1 = new GlobalCoordinates(end.getLatitude(), end.getLongitude());
+ GeodeticCurve geoCurve1 = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.WGS84, source1, target1);
+ double distance1 =geoCurve1.getEllipsoidalDistance();
+
+ // 如果两点间时间差小于间隔,说明不需要补密,直接添加终点(在循环结束后添加)
+ if (distance1 <= distance) {
+ // 这里不做处理,等待下一轮或直接添加终点
+ } else {
+ // 计算需要插入多少个点
+ long steps = (long) (distance1 / distance);
+
+ for (long j = 1; j <= steps; j++) {
+
+ // 计算插值比例 t (0.0 ~ 1.0)
+ double fraction = (double) (j * distance) / distance1;
+
+ // 线性插值计算经纬度
+ double newLat = start.getLatitude() + fraction * (end.getLatitude() - start.getLatitude());
+ double newLon = start.getLongitude() + fraction * (end.getLongitude() - start.getLongitude());
+
+ result.add(new TrackPoint(newLat, newLon, null));
+ }
+ }
+
+ // 确保每一段的终点被添加(除了最后一次循环,因为循环结束后会添加最后一个点)
+ // 为了避免重复添加,我们只在循环最后添加最后一个点,或者在这里判断
+ }
+
+ // 添加最后一个点
+ result.add(originalPoints.get(originalPoints.size() - 1));
+
+ return result;
+ }
+
+
+
+ /**
+ * 轨迹补密主方法
+ * @param originalPoints 原始轨迹点列表(必须按时间排序)
+ * @param intervalSeconds 补密的时间间隔(秒),例如每 5 秒补一个点
+ * @return 补密后的轨迹列表
+ */
+ public static List<TrackPoint> densifyByTime(List<TrackPoint> originalPoints, long intervalSeconds) {
+ List<TrackPoint> result = new ArrayList<>();
+ if (originalPoints == null || originalPoints.size() < 2) {
+ return originalPoints;
+ }
+
+ // 添加第一个点
+ result.add(originalPoints.get(0));
+
+ for (int i = 0; i < originalPoints.size() - 1; i++) {
+ TrackPoint start = originalPoints.get(i);
+ TrackPoint end = originalPoints.get(i + 1);
+
+ long timeDiffMillis = end.getTimestamp().toEpochMilli() - start.getTimestamp().toEpochMilli();
+ long intervalMillis = intervalSeconds * 1000;
+
+ // 如果两点间时间差小于间隔,说明不需要补密,直接添加终点(在循环结束后添加)
+ if (timeDiffMillis <= intervalMillis) {
+ // 这里不做处理,等待下一轮或直接添加终点
+ } else {
+ // 计算需要插入多少个点
+ long steps = timeDiffMillis / intervalMillis;
+
+ for (long j = 1; j <= steps; j++) {
+ // 计算当前插入点的时间
+ Instant newTime = start.getTimestamp().plusMillis(j * intervalMillis);
+
+ // 如果计算出的时间超过了终点时间,则停止(防止浮点数误差或边界问题)
+ if (newTime.isAfter(end.getTimestamp())) {
+ break;
+ }
+
+ // 计算插值比例 t (0.0 ~ 1.0)
+ double fraction = (double) (j * intervalMillis) / timeDiffMillis;
+
+ // 线性插值计算经纬度
+ double newLat = start.getLatitude() + fraction * (end.getLatitude() - start.getLatitude());
+ double newLon = start.getLongitude() + fraction * (end.getLongitude() - start.getLongitude());
+
+ result.add(new TrackPoint(newLat, newLon, newTime));
+ }
+ }
+
+ // 确保每一段的终点被添加(除了最后一次循环,因为循环结束后会添加最后一个点)
+ // 为了避免重复添加,我们只在循环最后添加最后一个点,或者在这里判断
+ }
+
+ // 添加最后一个点
+ result.add(originalPoints.get(originalPoints.size() - 1));
+
+ return result;
+ }
+
+ // 主函数测试
+ public static void main(String[] args) {
+ List<TrackPoint> track = new ArrayList<>();
+ // 模拟数据:两个点相差 20 秒
+ track.add(new TrackPoint(39.9042, 116.4074, Instant.parse("2026-03-28T10:00:00Z"))); // 北京
+ track.add(new TrackPoint(39.9050, 116.4080, Instant.parse("2026-03-28T10:00:20Z")));
+
+ // 每 5 秒补一个点
+ List<TrackPoint> densified = densifyByTime(track, 10);
+
+ System.out.println("原始点数: " + track.size());
+ System.out.println("补密后点数: " + densified.size());
+ System.out.println("轨迹详情:");
+ for (TrackPoint p : densified) {
+ System.out.println("[" + p.getLongitude() + ", " + p.getLatitude() + "]");
+ }
+ }
+
+}
diff --git a/xp-robotaxi-remote-driving-boot/pom.xml b/xp-robotaxi-remote-driving-boot/pom.xml
index 62c2f34..5440e18 100644
--- a/xp-robotaxi-remote-driving-boot/pom.xml
+++ b/xp-robotaxi-remote-driving-boot/pom.xml
@@ -106,6 +106,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-vehicle-convoy-boot/pom.xml b/xp-robotaxi-vehicle-convoy-boot/pom.xml
index b90b8ac..cefbe0b 100644
--- a/xp-robotaxi-vehicle-convoy-boot/pom.xml
+++ b/xp-robotaxi-vehicle-convoy-boot/pom.xml
@@ -106,6 +106,10 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
index c3ebd12..dfeca09 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -42,10 +42,7 @@
import com.xiaopeng.vehicleConvoy.service.IXpFleetVehicleService;
import com.xiaopeng.vehicleConvoy.service.IXpVehicleAnnualRecordService;
import com.xiaopeng.vehicleConvoy.service.IXpVehicleService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -836,9 +833,12 @@
*/
@ApiOperation(value = "查询可改派的车辆列表", tags = {"管理后台-订单管理"})
@GetMapping("/api/v1/vehicle/availableList")
- @ApiImplicitParam(name = "orderId", value = "订单ID", required = true, dataTypeClass = Long.class)
- public R<List<XpVehicle>> listAvailableVehicles(@RequestParam Long orderId) {
- List<XpVehicle> list = xpVehicleService.listAvailableVehicles(orderId);
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "orderId", value = "订单ID", required = true, dataTypeClass = Long.class),
+ @ApiImplicitParam(name = "orderType", value = "订单类型(1=用户单,2=测试单)", required = true, dataTypeClass = Integer.class)
+ })
+ public R<List<XpVehicle>> listAvailableVehicles(@RequestParam Long orderId, Integer orderType) {
+ List<XpVehicle> list = xpVehicleService.listAvailableVehicles(orderId, orderType);
return R.ok(list);
}
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java
index 0058922..cc85f09 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java
@@ -34,7 +34,7 @@
*
* @return 车辆列表
*/
- List<XpVehicle> listAvailableVehicles(Long orderId);
+ List<XpVehicle> listAvailableVehicles(Long orderId, Integer orderType);
/**
* 查询车辆列表接口-地图
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
index 8ed352f..f016164 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -16,10 +16,12 @@
import com.xiaopeng.api.feignClient.operation.XpElectronicClient;
import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
+import com.xiaopeng.api.feignClient.order.XpTestOrderClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
import com.xiaopeng.api.model.order.XpOrder;
+import com.xiaopeng.api.model.order.XpTestOrder;
import com.xiaopeng.api.model.vehicleConvoy.*;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.operation.ElectronicFenceDetailVo;
@@ -115,6 +117,8 @@
private RedisTemplate redisTemplate;
@Autowired
private XpPushMessageClient xpPushMessageClient;
+ @Resource
+ private XpTestOrderClient xpTestOrderClient;
@Override
public List<XpVehicle> listByIds(List<Long> ids) {
@@ -125,16 +129,22 @@
}
@Override
- public List<XpVehicle> listAvailableVehicles(Long orderId) {
+ public List<XpVehicle> listAvailableVehicles(Long orderId, Integer orderType) {
// 1. 通过订单ID查询订单信息,获取区域ID
- R<XpOrder> orderResult = xpOrderClient.queryOrderById(orderId);
- if (orderResult == null || orderResult.getData() == null) {
- log.warn("查询订单失败,orderId: {}", orderId);
- return Collections.emptyList();
- }
+ Long areaId = null;
+ if(null == orderType || 1 == orderType){
+ R<XpOrder> orderResult = xpOrderClient.queryOrderById(orderId);
+ if (orderResult == null || orderResult.getData() == null) {
+ log.warn("查询订单失败,orderId: {}", orderId);
+ return Collections.emptyList();
+ }
- XpOrder order = orderResult.getData();
- Long areaId = order.getXpElectronicFenceAreaId();
+ XpOrder order = orderResult.getData();
+ areaId = order.getXpElectronicFenceAreaId();
+ }else{
+ XpTestOrder testOrder = xpTestOrderClient.queryOrderById(orderId).getData();
+ areaId = testOrder.getXpElectronicFenceAreaId();
+ }
if (areaId == null) {
log.warn("订单区域ID为空,orderId: {}", orderId);
diff --git a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties
index bf07c98..994dbfc 100644
--- a/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties
+++ b/xp-robotaxi-vehicle-convoy-boot/src/main/resources/i18n/messages.properties
@@ -41,3 +41,6 @@
vehicle.import.code.exists=第{0}行车辆编码已存在:{1}
vehicle.import.vin.exists=第{0}行车辆VIN码已存在:{1}
vehicle.import.plate.exists=第{0}行车牌号已存在:{1}
+vehicle.distance.too.long=距离过远,无法打开
+vehicle.delete.has.bound.fleet=当前车辆已关联车队:{0}
+vehicle.not.p.gear=车辆非P档,无法开启后备箱
--
Gitblit v1.7.1