From 46342ddcf5d52ccbf2ae8d8a9a0b14cc0d29b250 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期四, 16 四月 2026 22:14:20 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/1.0' into 1.0

---
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java                         |    2 
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderWaypoint.java                              |   46 ++
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderWaypointController.java            |   51 ++
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderDetailVO.java                        |   14 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/ActiveOrderController.java                |  146 +++++++
 xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/DateUtils.java                |   13 
 xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/ActiveOrderController.java        |   78 +++
 xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java |   23 -
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java         |    2 
 xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/XpPricingController.java          |    7 
 xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/ActiveOrderService.java              |   13 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mapper/XpOrderWaypointMapper.java                    |   16 
 xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/ActiveOrderServiceImpl.java     |  226 +++++++++++
 xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserController.java              |   34 +
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/map/RouteAndFareDto.java                                  |    7 
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/order/OrderChangeDto.java                                 |   51 ++
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpVehicle.java                            |    2 
 xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java       |   58 +-
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java                    |   27 +
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java          |   11 
 xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/XpPricingService.java                |    2 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java                 |  238 ++++++++---
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java                    |    2 
 xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/dto/XpOrderDto.java                          |    3 
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/service/BootCommonService.java                                |   59 ++
 xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java                                      |   10 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderWaypointServiceImpl.java         |   24 +
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java             |   17 
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderWaypointService.java                 |   16 
 29 files changed, 1,065 insertions(+), 133 deletions(-)

diff --git a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserController.java b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserController.java
index bcf5682..fb87f55 100644
--- a/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserController.java
+++ b/xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserController.java
@@ -1,17 +1,21 @@
 package com.xiaopeng.account.controller;
 
+import com.xiaopeng.account.model.dto.CollectAddrDTO;
 import com.xiaopeng.account.service.IXpAppUserService;
 import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
 import com.xiaopeng.api.dto.statistics.UserStatisticsDTO;
 import com.xiaopeng.api.model.account.XpAppUser;
 import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.util.CollectionUtils;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -69,4 +73,34 @@
         XpAppUser xpAppUser = xpAppUserService.getById(id);
         return R.ok(xpAppUser);
     }
+
+//-----------------------------------------------app接口------------------------------------------
+    /**
+     * 获取免密结果
+     */
+    @PostMapping("/api/v1/mini-program/appUser/getPayPwd")
+    @ApiOperation(value = "个人中心-获取免密结果", tags = {"小程序-获取免密结果"})
+    @XpClientCheck(checkToken = false, checkOtpToken = true)
+    public R<Boolean> appUserGetPayPwd(HttpServletRequest request) {
+        // uid已通过拦截器otp校验,可以直接使用
+        String uid = request.getHeader("XP-Uid");
+        //调用其他接口获取 免密结果
+        Boolean is = true;
+        return R.ok(is);
+    }
+
+    /**
+     * 设置免密结果
+     */
+    @PostMapping("/api/v1/mini-program/appUser/setPayPwd")
+    @ApiOperation(value = "个人中心-设置免密结果", tags = {"小程序-设置免密结果"})
+    @XpClientCheck(checkToken = false, checkOtpToken = true)
+    public R<?> appUserSetPayPwd(HttpServletRequest request) {
+        // uid已通过拦截器otp校验,可以直接使用
+        String uid = request.getHeader("XP-Uid");
+        //调用其他接口设置免密结果
+        return R.ok();
+    }
+//-----------------------------------------------app接口------------------------------------------
+
 }
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/map/RouteAndFareDto.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/map/RouteAndFareDto.java
index dbe5e9d..32ea0c0 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/map/RouteAndFareDto.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/map/RouteAndFareDto.java
@@ -9,6 +9,10 @@
 @lombok.Data
 @ApiModel(description = "线路和运费Dto")
 public class RouteAndFareDto {
+
+    @ApiModelProperty(value = "订单id")
+    private Long orderId;
+
     @ApiModelProperty(value = "出发地")
     @NotNull(message = "出发地不能为空")
     private LonLatDto origin;
@@ -32,8 +36,5 @@
 
     @ApiModelProperty("车辆id")
     private Long vehicleId;
-
-    public RouteAndFareDto() {
-    }
 
 }
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/order/OrderChangeDto.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/order/OrderChangeDto.java
new file mode 100644
index 0000000..c9ca6f4
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/order/OrderChangeDto.java
@@ -0,0 +1,51 @@
+package com.xiaopeng.api.dto.order;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class OrderChangeDto  {
+
+
+    @ApiModelProperty(value = "订单Id")
+    @NotNull(message = "订单Id不能为空")
+    private Long orderId;
+
+    @ApiModelProperty("终点站点id")
+    @NotNull(message = "终点站点id不能为空")
+    private Long endPointId;
+    /*
+    @ApiModelProperty(value = "目的地经度")
+    @NotNull(message = "目的地经度不能为空")
+    private Double endLon;
+    @ApiModelProperty(value = "目的地纬度")
+    @NotNull(message = "目的地纬度不能为空")
+    private Double endLat;
+    @ApiModelProperty(value = "目的地地点")
+    @NotNull(message = "目的地地点不能为空")
+    private String endAddress;
+    */
+
+    @ApiModelProperty(value = "优惠券id")
+    private Long couponId;
+
+
+    @ApiModelProperty("多路线快照 ID(选路线下单时与 selectedRouteId 同时传)")
+    private String navigationSnapshotId;
+
+    @ApiModelProperty("选中的路径唯一标识(高德 routeID)")
+    private String selectedRouteId;
+
+    @ApiModelProperty("选中路线对应的高德 strategy,用于推单队列;多路线下单时由服务端写入")
+    private Integer selectedRoutePlanRule;
+
+
+
+    @ApiModelProperty(value = "距离 米")
+    private Integer distance = 0;
+    @ApiModelProperty(value = "时间 秒")
+    private Integer duration = 0;
+
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java
index 7f0e8be..412433f 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java
@@ -28,7 +28,7 @@
             }
 
             @Override
-            public R<XpPricing> getPricingByCid(Long cityId) {
+            public R<XpPricing> getPricingByCid(Long cityId,String vehicleModel) {
                 log.error("根据开通城市获取定价失败", cause);
                 return R.ok(null);
             }
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java
index a70e500..723f877 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java
@@ -22,7 +22,7 @@
 
     // 根据开通城市 获取定价
     @GetMapping("/logan/inner/v1/getPricingByCid")
-     R<XpPricing> getPricingByCid(@RequestParam Long cityId);
+     R<XpPricing> getPricingByCid(@RequestParam Long cityId,@RequestParam(required = false) String vehicleModelId);
 
     /**
      * 保存XpGeoQueryEntity
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java
index 653b28c..24c7003 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrder.java
@@ -36,7 +36,7 @@
     @ApiModelProperty(value = "用户id")
     @TableField(updateStrategy = FieldStrategy.NEVER)
     private Long appUserId;
-    @ApiModelProperty(value = "用户id")
+    @ApiModelProperty(value = "开通城市id")
     private Long cityId;
     @ApiModelProperty(value = "车辆id")
     private Long vehicleId;
@@ -183,7 +183,7 @@
     @ApiModelProperty(value = "下单城市编码")
     private String cityCode;
 
-    @ApiModelProperty(value = "下单站点id")
+    @ApiModelProperty(value = "起点站点id")
     @TableField("start_point_id")
     private Long startPointId;
 
@@ -191,7 +191,7 @@
     @TableField("end_point_id")
     private Long endPointId;
 
-    @ApiModelProperty(value = "下单站点名称")
+    @ApiModelProperty(value = "起点站点名称")
     @TableField("start_point_name")
     private String startPointName;
 
@@ -239,4 +239,8 @@
     @ApiModelProperty(value = "车辆是否故障 0-否 1-是")
     private Boolean carAbnormal;
 
+
+    @ApiModelProperty(value = "订单修改目的地的次数 默认0")
+    private Integer orderChange;
+
 }
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderWaypoint.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderWaypoint.java
new file mode 100644
index 0000000..cb56b0d
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderWaypoint.java
@@ -0,0 +1,46 @@
+package com.xiaopeng.api.model.order;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("xp_order_waypoint")
+@ApiModel(value="xp_order_waypoint", description="订单途经点")
+public class XpOrderWaypoint {
+
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.NONE)
+    private Long id;
+
+    @ApiModelProperty(value = "订单id")
+    @NotNull(message = "订单id不能为空")
+    private Long orderId;
+
+    @ApiModelProperty(value = "途经点点位id")
+    @NotNull(message = "途经点点位id不能为空")
+    private Long pointId;
+    @ApiModelProperty(value = "途经点名称")
+    @NotNull(message = "途经点名称不能为空")
+    private String pointName;
+
+    @ApiModelProperty(value = "经度")
+    @NotNull(message = "经度不能为空")
+    private Double longitude;
+
+    @ApiModelProperty(value = "纬度")
+    @NotNull(message = "纬度不能为空")
+    private Double latitude;
+
+}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpVehicle.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpVehicle.java
index 106d235..85e6e17 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpVehicle.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpVehicle.java
@@ -47,7 +47,7 @@
     @ApiModelProperty(value = "车牌号")
     private String plateNumber;
 
-    @ApiModelProperty(value = "型号")
+    @ApiModelProperty(value = "型号 关联车辆型号表id")
     private String vehicleModel;
 
     @ApiModelProperty(value = "车辆颜色")
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/service/BootCommonService.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/service/BootCommonService.java
new file mode 100644
index 0000000..03c819a
--- /dev/null
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/service/BootCommonService.java
@@ -0,0 +1,59 @@
+package com.xiaopeng.api.service;
+
+import com.xiaopeng.api.feignClient.operation.XpPricingClient;
+import com.xiaopeng.api.feignClient.order.XpOrderClient;
+import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
+import com.xiaopeng.api.model.operation.XpPricing;
+import com.xiaopeng.api.model.order.XpOrder;
+import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
+import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.common.core.exception.ServiceException;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class BootCommonService {
+
+    @Resource
+    private  XpPricingClient xpPricingClient;
+    @Resource
+    private  XpVehicleClient xpVehicleClient;
+    @Resource
+    private XpOrderClient xpOrderClient;
+
+
+    public XpPricing getXpPricing(Long orderId) {
+
+        XpOrder xpOrder = xpOrderClient.queryOrderById(orderId).getData();
+        return getXpPricing(xpOrder.getCityId(),xpOrder.getVehicleId());
+    }
+
+    public XpPricing getXpPricing(Long cityId, Long vehicleId) {
+        String vehicleModelId = null;
+        if(vehicleId != null){
+            XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
+            if(null != xpVehicle){
+                vehicleModelId = xpVehicle.getVehicleModel();
+            }
+        }
+        R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(cityId,vehicleModelId);
+        return pricingByCityId.getData();
+    }
+
+
+
+    public String getVehicleModelId(Long orderId) {
+        if(orderId!= null){
+            R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(orderId);
+            if (xpOrderR.getCode() != R.SUCCESS || xpOrderR.getData() == null) {
+                throw new ServiceException("订单不存在");
+            }
+            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrderR.getData().getVehicleId()).getData();
+            return xpVehicle.getVehicleModel();
+        }
+        return null;
+    }
+
+
+}
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 5f5c3e9..d81cf34 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
@@ -443,7 +443,7 @@
                     // 给连环派单的用户推送
                     Long nextOrderId = redisService.getCacheObject(CacheConstants.nextOrder(order_id));
                     if (null != nextOrderId){
-                        dto.setOrderId(orderId);
+                        dto.setOrderId(nextOrderId);
                         xpPushMessageClient.pushOrderRoute(dto);
                     }
                     xpOrderClient.saveVehicleLocation(orderTrajectory);
@@ -1202,26 +1202,6 @@
                     log.info("到达目的地,不做任何处理:{}", orderId);
                     break;
                 case ORDER_WAITING_FOR_DROPOFF:
-                    Long id = redisService.getCacheObject(CacheConstants.nextOrder(orderId));
-                    if(id != null){
-                        scheduler.schedule(() -> {
-                            XpOrder xpOrder = xpOrderClient.queryOrderById(id).getData();
-                            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
-                            PushOrderDto pushOrderDto = new PushOrderDto();
-                            pushOrderDto.setOrderId(xpOrder.getId().toString());
-                            pushOrderDto.setStartLatitude(xpOrder.getStartLat());
-                            pushOrderDto.setStartLongitude(xpOrder.getStartLon());
-                            pushOrderDto.setEndLatitude(xpOrder.getEndLat());
-                            pushOrderDto.setEndLongitude(xpOrder.getEndLon());
-                            pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
-                            pushOrderDto.setOrderType(OrderType.USER_ORDER);
-                            pushOrderDto.setStage(1);
-                            pushOrderDto.setVin(xpVehicle.getVehicleVin());
-                            orderMissionClient.pushOrder(pushOrderDto);
-                        }, 3, TimeUnit.MINUTES);
-                        break;
-                    }
-
                     //等待乘客下车,开始倒计时发下巡游单
                     if(!orderId.contains("XU")){
                         if(orderId.contains("TEST")){
@@ -1231,7 +1211,6 @@
                             xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode());
                         }
                     }
-
                     break;
                 case ORDER_DROPOFF_COMPLETED:
                     //下车完成,不需要处理状态,由后续的乘客主动触发或者定时任务触发
diff --git a/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/DateUtils.java b/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/DateUtils.java
index 15c85f4..cd8cd2c 100644
--- a/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/DateUtils.java
+++ b/xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/DateUtils.java
@@ -443,4 +443,17 @@
         return count;
 
     }
+
+    /**
+     * 获取指定时间的 毫秒
+     * @return
+     */
+    public static long getMilliseconds(LocalDateTime localDateTime){
+    // 转换为毫秒时间戳(需指定时区)
+    Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
+    long timestamp = instant.toEpochMilli();
+    return timestamp;
+}
+
+
 }
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/ActiveOrderController.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/ActiveOrderController.java
new file mode 100644
index 0000000..75d1684
--- /dev/null
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/ActiveOrderController.java
@@ -0,0 +1,78 @@
+package com.xiaopeng.itinerary.controller;
+
+import com.xiaopeng.api.dto.map.RouteAndFareDto;
+import com.xiaopeng.api.dto.order.OrderChangeDto;
+import com.xiaopeng.api.vo.operation.RouteAndFareVo;
+import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.itinerary.service.ActiveOrderService;
+import com.xiaopeng.itinerary.service.XpPricingService;
+import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.List;
+
+
+/**
+ * <p>
+ * 订单行程
+ * </p>
+ */
+
+@Slf4j
+@RestController
+@RequestMapping("")
+@Api(tags = "费用管理")
+public class ActiveOrderController {
+
+    @Resource
+    private ActiveOrderService activeOrderService;
+    @Resource
+    private  XpPricingService xpPricingService;
+
+    /**
+     * 在行程中修改目的地-获取路线和费用
+     * @param routeAndFareDto
+     * @param request
+     * @return
+     */
+    @PostMapping("/api/v1/mini-program/activeOrder/route-and-fare")
+    @ApiOperation(value = "导航-获取路线和费用", tags = {"小程序-获取路线和费用"}, response = RouteAndFareVo.class)
+    @XpClientCheck(checkToken = false, checkOtpToken = true)
+    public R<List<RouteAndFareVo>> getRouteAndFare(@RequestBody @Valid RouteAndFareDto routeAndFareDto, HttpServletRequest request) {
+        if(null == routeAndFareDto.getOrderId()){
+            return R.fail("订单id不能为空");
+        }
+        // uid已通过拦截器otp校验,可以直接使用
+        String uid = request.getHeader("XP-Uid");
+        return R.ok(xpPricingService.getRouteAndFare(routeAndFareDto, uid));
+    }
+
+    /**
+     * 行程中 修改目的地 确认按钮
+     * 修改目的地,
+     * 1.重新确认路线
+     * 2.确认价格
+     */
+    @ApiOperation(value = "行程中 修改目的地 确认按钮", notes = "", tags = {"小程序-行程中修改目的地"})
+    @PostMapping("/api/v1/mini-program/order/orderChange")
+    @XpClientCheck(checkToken = false, checkOtpToken = true)
+    public R<?> orderChange(@RequestBody @Validated OrderChangeDto dto, HttpServletRequest request) {
+
+        String uid = request.getHeader("XP-Uid");
+        activeOrderService.orderChange(dto, uid);
+        return R.ok();
+    }
+
+
+
+}
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/XpPricingController.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/XpPricingController.java
index 26e0921..0c129bd 100644
--- a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/XpPricingController.java
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/XpPricingController.java
@@ -7,6 +7,7 @@
 import com.xiaopeng.api.dto.map.RoutePreferenceSaveDto;
 import com.xiaopeng.api.dto.map.RouteStaleCheckDto;
 import com.xiaopeng.api.dto.map.SelectNavigationRouteDto;
+import com.xiaopeng.api.dto.order.OrderChangeDto;
 import com.xiaopeng.api.model.order.XpOrder;
 import com.xiaopeng.api.vo.operation.MultiRouteAndFareVo;
 import com.xiaopeng.api.vo.operation.RoutePreferenceItemVo;
@@ -18,6 +19,7 @@
 import com.xiaopeng.common.core.web.controller.BaseController;
 import com.xiaopeng.common.redis.service.RedisService;
 import com.xiaopeng.itinerary.dto.XpOrderDto;
+import com.xiaopeng.itinerary.service.ActiveOrderService;
 import com.xiaopeng.itinerary.service.IXpGeoQueryEntityService;
 import com.xiaopeng.itinerary.service.XpPricingService;
 import com.xiaopeng.api.vo.HotFixInfoVo;
@@ -31,6 +33,7 @@
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 import java.util.List;
@@ -137,6 +140,10 @@
         return R.ok(saveOrderVo);
     }
 
+
+
+
+
     /**
      * 获取热修复信息
      * @param
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/dto/XpOrderDto.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/dto/XpOrderDto.java
index 3656600..8ecfc34 100644
--- a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/dto/XpOrderDto.java
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/dto/XpOrderDto.java
@@ -48,6 +48,9 @@
     @NotNull(message = "下单地址不能为空")
     private String placementAddress;
 
+    @ApiModelProperty("路线规划规则")
+    @NotNull(message = "路线规划规则不能为空")
+    private Integer routePlanRule;
 
     @ApiModelProperty("用户优惠券主键:null 或 0 表示不使用券;>0 为具体券 id")
     private Long userCouponId;
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/ActiveOrderService.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/ActiveOrderService.java
new file mode 100644
index 0000000..fb8de09
--- /dev/null
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/ActiveOrderService.java
@@ -0,0 +1,13 @@
+package com.xiaopeng.itinerary.service;
+
+import com.xiaopeng.api.dto.order.OrderChangeDto;
+
+/**
+ * 行驶中的订单
+ */
+public interface ActiveOrderService {
+
+    void orderChange(OrderChangeDto dto, String uid);
+
+
+}
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/XpPricingService.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/XpPricingService.java
index b2be913..2d767f2 100644
--- a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/XpPricingService.java
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/XpPricingService.java
@@ -60,6 +60,8 @@
      */
     String saveOrder(XpOrderDto dto, String uid);
 
+    Boolean isInOperationTime(String operationStrategy);
+
     /**
      * 多策略路径规划合并、计价与快照
      */
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/ActiveOrderServiceImpl.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/ActiveOrderServiceImpl.java
new file mode 100644
index 0000000..7523f84
--- /dev/null
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/ActiveOrderServiceImpl.java
@@ -0,0 +1,226 @@
+package com.xiaopeng.itinerary.service.impl;
+
+
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.xiaopeng.api.dto.order.OrderChangeDto;
+import com.xiaopeng.api.feignClient.map.XpMapClient;
+import com.xiaopeng.api.feignClient.operation.XpPointClient;
+import com.xiaopeng.api.feignClient.order.XpOrderClient;
+import com.xiaopeng.api.model.operation.XpElectronicFence;
+import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
+import com.xiaopeng.api.model.operation.XpPoint;
+import com.xiaopeng.api.model.operation.XpRoutePlan;
+import com.xiaopeng.api.model.order.XpOrder;
+import com.xiaopeng.api.vo.operation.RouteOptionVo;
+import com.xiaopeng.api.vo.operation.RouteVo;
+import com.xiaopeng.common.core.constant.CacheConstants;
+import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.common.core.exception.ServiceException;
+import com.xiaopeng.common.redis.service.RedisService;
+import com.xiaopeng.itinerary.constant.I18nKeyConstant;
+import com.xiaopeng.itinerary.mapper.XpElectronicFenceAreaMapper;
+import com.xiaopeng.itinerary.mapper.XpElectronicFenceMapper;
+import com.xiaopeng.itinerary.mapper.XpOpenCityMapper;
+import com.xiaopeng.itinerary.mapper.XpRoutePlanMapper;
+import com.xiaopeng.itinerary.navigation.MultiRouteSnapshotPayload;
+import com.xiaopeng.itinerary.service.ActiveOrderService;
+import com.xiaopeng.itinerary.service.XpPointService;
+import com.xiaopeng.itinerary.service.XpPricingService;
+import com.xiaopeng.itinerary.utils.map.GDMapGeocodingUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+
+@Slf4j
+@Service
+public class ActiveOrderServiceImpl implements ActiveOrderService {
+
+
+    @Resource
+    private GDMapGeocodingUtil gdMapGeocodingUtil;
+    @Resource
+    private XpOpenCityMapper xpOpenCityMapper;
+    @Resource
+    private XpOrderClient xpOrderClient;
+    @Resource
+    private  XpPricingService xpPricingService;
+    @Resource
+    private XpMapClient xpMapClient;
+    @Resource
+    private XpElectronicFenceAreaMapper xpElectronicFenceAreaMapper;
+    @Autowired
+    private XpElectronicFenceMapper xpElectronicFenceMapper;
+    @Autowired
+    private XpPointService xpPointService;
+    @Resource
+    private XpPointClient xpPointClient;
+    @Resource
+    private RedisService redisService;
+    @Resource
+    private XpRoutePlanMapper xpRoutePlanMapper;
+
+
+    /*
+    public void getRouteAndFareParamValidate(RouteAndFareDto routeAndFareDto, String userId) {
+        //获取订单信息
+
+        R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(routeAndFareDto.getOrderId());
+
+        if (xpOrderR.getCode() != R.SUCCESS || xpOrderR.getData() == null) {
+            throw new ServiceException("订单不存在");
+        }
+        // 1. 基础数据查询
+        Map<String, String> geocode = gdMapGeocodingUtil.geocode(routeAndFareDto.getOrigin().getLongitude().toString(), routeAndFareDto.getOrigin().getLatitude().toString());
+        if(null == geocode){
+            throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND);
+        }
+        Long cityCode = routeAndFareDto.getOpenCityId();
+        XpOpenCity openCities = xpOpenCityMapper.selectById(cityCode);
+        if (openCities == null ) {
+            throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND);
+        }
+        XpPricing xpPricing = xpPricingService.getOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, routeAndFareDto.getOpenCityId()));
+        if (xpPricing == null) {
+            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
+        }
+
+        routeAndFareDto.setRoutePlanRule(xpOrderR.getData().getRoutePlanRule());
+        // 算距离
+        R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+        if (distanceAndDuration.getCode() != 200) {
+            throw new ServiceException("获取导肮信息失败", I18nKeyConstant.PATH_NOT_FOUND);
+        }
+        RouteVo routeVo = distanceAndDuration.getData();
+    }
+     */
+
+    @Override
+    public void orderChange(OrderChangeDto dto, String uid){
+
+        //获取订单信息
+        R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(dto.getOrderId());
+        if (xpOrderR.getCode() != R.SUCCESS || xpOrderR.getData() == null) {
+            throw new ServiceException("订单不存在");
+        }
+        Integer orderChange = 2;//todo yyy 从配置文件读取 修改订单目的地次数
+        XpOrder order = xpOrderR.getData();
+        //判断订单修改的次数
+        if(order.getOrderChange() > orderChange){
+            throw new ServiceException("目的地修改次数已超上限");
+        }
+
+        // 是否在运营区域时间内
+        XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(order.getXpElectronicFenceAreaId());
+        XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(xpElectronicFenceArea.getElectronicId());
+        String operationStrategy = xpElectronicFence.getOperationStrategy();
+        Boolean inOperationTime = xpPricingService.isInOperationTime(operationStrategy);
+        if (!inOperationTime && xpElectronicFence.getFailureType()!=1) {
+            log.info("当前区域暂未开通,下单失败 {}", uid);
+            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
+        }
+        boolean inTime = xpPointClient.nowInTimePoint(dto.getEndPointId()).getData();
+        if (!inTime) {
+            throw new ServiceException("终点点位未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
+        }
+        // 终点
+        XpPoint endXpPoint = xpPointService.getById(dto.getEndPointId());
+        if(endXpPoint ==null || endXpPoint.getOperationStatus()!=2){
+            throw new ServiceException("该站点已停止运营", 200,I18nKeyConstant.NO_CURRENT_POINT);
+        }
+
+        //修改订单数据
+        XpOrder xpOrder = new XpOrder();
+        xpOrder.setId(order.getId());
+        xpOrder.setEndLon(endXpPoint.getPointLon());
+        xpOrder.setEndLat(endXpPoint.getPointLat());
+        xpOrder.setEndAddress(endXpPoint.getPointAddress());
+        xpOrder.setEndPointId(dto.getEndPointId());
+        xpOrder.setEndPointName(endXpPoint.getPointName());
+
+        Long couponRef = dto.getCouponId();
+        xpOrder.setCouponId(couponRef != null && couponRef > 0L ? couponRef : null);
+        xpOrder.setUpdateTime(LocalDateTime.now());
+        xpOrder.setOrderChange(order.getOrderChange()+1);
+        xpOrderClient.updateOrder(xpOrder);
+
+        //获取距离和时间
+        this.getDD(uid,dto);
+
+        //将修改信息存入到redis,
+        // 获取起点经纬度
+        XpPoint xpPoint = xpPointService.getById(order.getStartPointId());
+        XpRoutePlan xpRoutePlan = xpRoutePlanMapper.selectOne(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getAuditStatus, 2).eq(XpRoutePlan::getCityCode, order.getCityCode()));
+        final Integer planRuleForQueue = dto.getSelectedRoutePlanRule() != null ? dto.getSelectedRoutePlanRule()
+                : (xpRoutePlan != null ? xpRoutePlan.getRoutePlanRule() : null);
+
+//        order.getId() + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + order.getOrderNumber() + "_" + dto.getDistance() + "_" + dto.getDuration() + "_" + null
+        StringJoiner points = new StringJoiner("_");
+        points.add(order.getId().toString());
+        points.add(xpPoint.getPointLon() + "," + xpPoint.getPointLat());
+        points.add("0");
+        points.add(uid);
+        points.add(order.getOrderNumber());
+        points.add(dto.getDistance()+"");
+        points.add(dto.getDuration()+"");
+
+        String key = CacheConstants.QUEUE_POINT_ID + "-" + xpPoint.getId() + "-" + xpPoint.getPointLon() + "," + xpPoint.getPointLat();
+        if (planRuleForQueue == null) {
+            redisService.addToTail(key,points+"_"+null);
+        } else {
+            redisService.addToTail(key,points+"_"+planRuleForQueue);
+        }
+        log.info("订单推单:{}   {}", key, redisService.getCacheList(key));
+        xpOrder.setQueueName(key);
+        xpOrderClient.updateOrder(xpOrder);
+    }
+
+    /**
+     * 获取距离和时间
+     * @param uid
+     * @param dto
+     */
+    public void getDD (String uid, OrderChangeDto dto ){
+
+        Integer distance = 0;
+        Integer duration = 0;
+        if (dto.getNavigationSnapshotId() != null && dto.getSelectedRouteId() != null) {
+            String snap = redisService.getCacheObject(CacheConstants.ORDER_MULTI_ROUTE_SNAPSHOT + uid + ":" + dto.getNavigationSnapshotId());
+            if (snap != null) {
+                MultiRouteSnapshotPayload snapPayload = JSON.parseObject(snap, MultiRouteSnapshotPayload.class);
+                RouteOptionVo opt = snapPayload.getRoutes().stream()
+                        .filter(r2 -> dto.getSelectedRouteId().equals(r2.getPathFingerprint()))
+                        .findFirst()
+                        .orElse(null);
+                if (opt != null && opt.getRoute() != null) {
+                    distance = opt.getRoute().getDistance();
+                    duration = opt.getRoute().getDuration();
+                    redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + uid, JSON.toJSONString(opt.getRoute()), 24L, TimeUnit.HOURS);
+                    if (dto.getSelectedRoutePlanRule() == null) {
+                        dto.setSelectedRoutePlanRule(opt.getPrimaryRoutePlanRule());
+                    }
+                }
+            }
+        }
+        if (distance == 0 && duration == 0) {
+            Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_END_DATA:" + uid);
+            if (cacheObject != null) {
+                RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
+                distance = routeVo.getDistance();
+                duration = routeVo.getDuration();
+            }
+        }
+
+        dto.setDistance(distance);
+        dto.setDuration(duration);
+    }
+
+
+
+}
diff --git a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
index 39a1834..8c34a74 100644
--- a/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
+++ b/xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -7,21 +7,21 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xiaopeng.api.dto.account.GetUserCouponDto;
-import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
 import com.xiaopeng.api.dto.map.RouteAndFareDto;
 import com.xiaopeng.api.dto.map.RouteStaleCheckDto;
 import com.xiaopeng.api.dto.map.SelectNavigationRouteDto;
-import com.xiaopeng.api.dto.operation.LonLatDto;
 import com.xiaopeng.api.enums.RouteStrategyKind;
-import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
 import com.xiaopeng.api.feignClient.account.XpAppUserClient;
 import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
 import com.xiaopeng.api.feignClient.map.XpMapClient;
 import com.xiaopeng.api.feignClient.operation.XpPointClient;
 import com.xiaopeng.api.feignClient.order.XpOrderClient;
 import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
+import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
 import com.xiaopeng.api.model.operation.*;
 import com.xiaopeng.api.model.order.XpOrder;
+import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
+import com.xiaopeng.api.service.BootCommonService;
 import com.xiaopeng.api.vo.account.UserCouponVo;
 import com.xiaopeng.api.vo.operation.FareVo;
 import com.xiaopeng.api.vo.operation.MultiRouteAndFareVo;
@@ -85,6 +85,8 @@
     private XpMapClient xpMapClient;
 
     @Resource
+    private BootCommonService bootCommonService;
+    @Resource
     private XpOpenCityMapper xpOpenCityMapper;
 
     @Resource
@@ -101,6 +103,8 @@
 
     @Resource
     private XpOrderClient xpOrderClient;
+    @Resource
+    private XpVehicleClient xpVehicleClient;
 
     @Resource
     private XpTradingStrategyMapper xpTradingStrategyMapper;
@@ -200,6 +204,17 @@
         return hour + "-" + (hour + 1);
     }
 
+    public XpPricing getInfo(Long cityId,String vehicleModel){
+
+        LambdaQueryWrapper<XpPricing> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(XpPricing::getDeleted, 0);
+        queryWrapper.eq(XpPricing::getCityId, cityId);
+        if(vehicleModel != null){
+            queryWrapper.eq(XpPricing::getVehicleModel, vehicleModel);
+        }
+        return super.getOne(queryWrapper,true);
+    }
+
 
     @Override
     public List<RouteAndFareVo> getRouteAndFare(RouteAndFareDto routeAndFareDto, String userId) {
@@ -213,7 +228,6 @@
 //            RouteAndFareVo RouteAndFareVo = JSONObject.parseObject(jsonStr, RouteAndFareVo.class);
 //            return (RouteAndFareVo);
 //        }
-
         ArrayList<RouteAndFareVo> routeAndFareVos = new ArrayList<>(3);
 
         // 1. 基础数据查询
@@ -226,6 +240,15 @@
         if (openCities == null ) {
             throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND);
         }
+        //根据订单获取车型 获取定价策略
+        String vehicleModel = bootCommonService.getVehicleModelId(routeAndFareDto.getOrderId());
+
+        XpPricing xpPricing = this.getInfo(routeAndFareDto.getOpenCityId(),vehicleModel);
+        if (xpPricing == null) {
+            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
+        }
+
+
         XpOpenCity xpOpenCity = openCities;
         routeAndFareDto.setOpenCityId(xpOpenCity.getId());
         List<XpRoutePlan> xpRoutePlan = xpRoutePlanMapper.selectList(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getAuditStatus, 2).eq(XpRoutePlan::getCityCode, cityCode));
@@ -233,7 +256,6 @@
         // 找出用户偏好
         Object cacheObject = redisService.getCacheObject(CacheConstants.USER_ROUTE_PREFERENCE + userId);
         for (XpRoutePlan routePlan : xpRoutePlan) {
-
 
             if (xpRoutePlan != null) {
                 routeAndFareDto.setRoutePlanRule(routePlan.getRoutePlanRule());
@@ -246,12 +268,6 @@
                     // keep city default
                 }
             }
-
-            XpPricing xpPricing = this.baseMapper.selectOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, routeAndFareDto.getOpenCityId()));
-            if (xpPricing == null) {
-                throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
-            }
-
 
             // 算距离
             R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
@@ -409,7 +425,7 @@
 
             // 11. 生成订单ID并缓存
             String id = CacheConstants.ORD + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8);
-            redisService.setCacheObject(CacheConstants.ORD + id + userId, xpPricingCardVo, 1l, TimeUnit.DAYS);
+            redisService.setCacheObject(CacheConstants.ORD + id + userId, xpPricingCardVo, 1L, TimeUnit.DAYS);
             fareVo.setId(id);
 
             // 12. 设置费用信息
@@ -612,24 +628,23 @@
         xpOrder.setPlacementAddress(dto.getPlacementAddress());
 
         xpOrder.setCityId(dto.getOpenCityId());
+        xpOrder.setXpElectronicFenceAreaId(dto.getXpElectronicFenceAreaId());
 
+        xpOrder.setStartPointId(dto.getStartPointId());
         xpOrder.setStartLon(xpPoint.getPointLon());
         xpOrder.setStartLat(xpPoint.getPointLat());
         xpOrder.setBoardingLon(xpPoint.getPointLon());
         xpOrder.setBoardingLat(xpPoint.getPointLat());
         xpOrder.setBoardingAddress(xpPoint.getPointAddress());
+        xpOrder.setStartAddress(xpPoint.getPointAddress());
+        xpOrder.setStartPointName(xpPoint.getPointName());
 
+        xpOrder.setEndPointId(dto.getEndPointId());
         xpOrder.setEndLon(endXpPoint.getPointLon());
         xpOrder.setEndLat(endXpPoint.getPointLat());
-
-        xpOrder.setStartAddress(xpPoint.getPointAddress());
         xpOrder.setEndAddress(endXpPoint.getPointAddress());
-
-        xpOrder.setXpElectronicFenceAreaId(dto.getXpElectronicFenceAreaId());
-        xpOrder.setStartPointId(dto.getStartPointId());
-        xpOrder.setEndPointId(dto.getEndPointId());
-        xpOrder.setStartPointName(xpPoint.getPointName());
         xpOrder.setEndPointName(endXpPoint.getPointName());
+
 
         // 当前时段
         String currentTimeSlot = DateUtils.getCurrentTimeSlot();
@@ -732,7 +747,6 @@
                 xpGeoQueryEntity.setStatus(0);
                 xpGeoQueryEntity.setTimestamp(System.currentTimeMillis());
                 geoQueryEntityService.save(xpGeoQueryEntity);
-
                 return orderId.toString();
             }
         }
@@ -760,8 +774,8 @@
         return orderId.toString();
     }
 
-
-    private Boolean isInOperationTime(String operationStrategy) {
+    @Override
+    public Boolean isInOperationTime(String operationStrategy) {
         JSONArray jsonArray = JSONArray.parseArray(operationStrategy);
         Integer holidayToday = holidayUtil.isHolidayToday();
         for (Object o : jsonArray) {
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
index de12c26..5ef65be 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
@@ -80,12 +80,19 @@
     }
     // 根据开通城市 获取定价
     @GetMapping("/logan/inner/v1/getPricingByCid")
-    public R<XpPricing> getPricingByCid(@RequestParam Long cityId) {
-        XpPricing pricing = xpPricingService.lambdaQuery().eq(XpPricing::getCityId, cityId).last("limit 1").one();
+    public R<XpPricing> getPricingByCid(@RequestParam Long cityId,@RequestParam(required = false) String vehicleModelId) {
+        LambdaQueryWrapper<XpPricing> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(XpPricing::getCityId, cityId);
+        if(null != vehicleModelId){
+            queryWrapper.eq(XpPricing::getVehicleModel, vehicleModelId);
+        }
+        XpPricing pricing = xpPricingService.getOne(queryWrapper);
+
         return R.ok(pricing);
     }
 
 
+
     @GetMapping("/base/v1/mini-program/pricing/rules/{openCityId}")
     @XpClientCheck(checkToken = false, checkOtpToken = true)
     @ApiOperation(value = "获取费用规则(弃用)", tags = {"小程序-根据开通城市获取费用规则(弃用)"}, response = String.class)
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/ActiveOrderController.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/ActiveOrderController.java
new file mode 100644
index 0000000..ab0caa8
--- /dev/null
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/ActiveOrderController.java
@@ -0,0 +1,146 @@
+package com.xiaopeng.order.controller;
+
+import com.xiaopeng.api.dto.QueryOrderRouteDTO;
+import com.xiaopeng.api.feignClient.operation.XpPointClient;
+import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
+import com.xiaopeng.api.model.operation.XpPoint;
+import com.xiaopeng.api.model.order.XpOrder;
+import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
+import com.xiaopeng.api.vo.operation.RouteVo;
+import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.order.model.vo.XpOrderDetailVO;
+import com.xiaopeng.order.service.IXpOrderService;
+import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.Nullable;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.Duration;
+import java.time.LocalDateTime;
+
+@RestController
+@Api(tags = "订单")
+@RequiredArgsConstructor(onConstructor_ = @Lazy)
+public class ActiveOrderController {
+
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    @Resource
+    XpOrderController xpOrderController;
+    @Resource
+    private final IXpOrderService xpOrderService;
+    @Resource
+    private final XpPointClient xpPointClient;
+    @Resource
+    private final XpVehicleClient xpVehicleClient;
+
+    @Nullable
+    private R<XpOrder> getOrderTripEnd(String orderId) {
+        XpOrder xpOrder = xpOrderService.getById(orderId);
+        if(xpOrder == null){
+            return R.fail("订单不存在");
+        }
+        if(xpOrder.getTripEnd() != null){
+            Duration duration = Duration.between(xpOrder.getTripEnd(), LocalDateTime.now());
+            if(duration.toHours()>=24){
+                return R.fail("行程结束已超过24小时查看行程信息,请联系客服");
+            }
+        }
+        return R.ok(xpOrder);
+    }
+
+
+    /**
+     * 分享行程接口1-订单查询实时轨迹路线
+     */
+    @ApiOperation(value = "分享行程接口1 订单查询实时轨迹路线")
+    @GetMapping("/base/v1/mini-program/orderActive/share/queryOrderRoute")
+    @XpClientCheck(checkToken = false, checkOtpToken = false)
+    public R<RouteVo> queryOrderRoute(@RequestParam String orderId, HttpServletRequest request) {
+        // 查询订单信息
+        if(StringUtils.isBlank(orderId) ){
+            return R.fail("参数不能为空");
+        }
+        R r = getOrderTripEnd(orderId);
+        if (r != null && r.getCode() != 200) {
+            return r;
+        }
+        QueryOrderRouteDTO dto = new QueryOrderRouteDTO();
+        return xpOrderController.queryOrderRoute(dto,request);
+    }
+
+    /**
+     * 分享行程接口2-订单查询轨迹路线
+     */
+    @ApiOperation(value = "分享行程接口2-订单查询轨迹路线")
+    @GetMapping("/base/v1/mini-program/orderActive/share/queryOrderTrajectory")
+    @XpClientCheck(checkToken = false, checkOtpToken = false)
+    public R<RouteVo> queryOrderTrajectory(@RequestParam String orderId,HttpServletRequest request) {
+        if(StringUtils.isBlank(orderId) ){
+            return R.fail("参数不能为空");
+        }
+        R r = getOrderTripEnd(orderId);
+        if (r != null && r.getCode() != 200) {
+            return r;
+        }
+        return xpOrderController.queryOrderTrajectory(orderId,request);
+    }
+
+
+    /**
+     * 分享行程接口3-订单信息
+     */
+    @ApiOperation(value = "分享行程接口3-订单查询实时轨迹路线")
+    @GetMapping("/base/v1/mini-program/orderActive/share/orderInfo")
+    @XpClientCheck(checkToken = false, checkOtpToken = false)
+    public R<XpOrderDetailVO> shareOrderInfo(@RequestParam String orderId, HttpServletRequest request) {
+        // 查询订单信息
+        if(orderId == null){
+            return R.fail("参数不能为空");
+        }
+        R<XpOrder> r = getOrderTripEnd(orderId);
+        if (r != null && r.getCode() != 200) {
+            return R.fail(r.getMsg());
+        }
+
+        XpOrder xpOrder = r.getData();
+        XpOrderDetailVO xpOrderDetailVO = new XpOrderDetailVO();
+        BeanUtils.copyProperties(xpOrder, xpOrderDetailVO);
+
+        R<XpPoint> xpPointR = xpPointClient.queryById(xpOrder.getStartPointId());
+        if (xpPointR.getCode() == R.SUCCESS) {
+            XpPoint startPoint = xpPointR.getData();
+            xpOrderDetailVO.setStartParkingTimeLimit(startPoint.getParkingTimeLimit());
+        }
+
+        R<XpPoint> xpPointR1 = xpPointClient.queryById(xpOrder.getEndPointId());
+        if (xpPointR1.getCode() == R.SUCCESS) {
+            XpPoint endPoint = xpPointR1.getData();
+            xpOrderDetailVO.setEndParkingTimeLimit(endPoint.getParkingTimeLimit());
+        }
+        if (xpOrder.getVehicleId() != null) {
+            R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId());
+            XpVehicle vehicle = xpVehicleR.getData();
+            xpOrderDetailVO.setVehicleId(vehicle.getId());
+            xpOrderDetailVO.setVehicleVin(vehicle.getVehicleVin());
+            xpOrderDetailVO.setVehicleModel(vehicle.getVehicleModel());
+            xpOrderDetailVO.setVehicleColor(vehicle.getVehicleColor());
+            xpOrderDetailVO.setPlateNumber(vehicle.getPlateNumber());
+            xpOrderDetailVO.setVehiclePictures(vehicle.getVehiclePictures());
+        }
+        return R.ok(xpOrderDetailVO);
+    }
+}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
index b399139..5d2f7e6 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -51,6 +51,7 @@
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -79,7 +80,7 @@
     private final RedisService redisService;
     @Autowired
     private MongoTemplate mongoTemplate;
-    @Autowired
+    @Resource
     private XpVehicleClient xpVehicleClient;
 
     /**
@@ -106,7 +107,7 @@
         if (!list.isEmpty()) {
             return R.ok(list.get(0).getId());
         }
-        return R.ok(0l);
+        return R.ok(0L);
 
     }
 
@@ -391,6 +392,17 @@
         return R.ok(xpOrderService.getActiveOrder(uid));
     }
 
+    /**
+     * 获取正在进行中的订单_行程管理
+     */
+    @ApiOperation(value = "获取正在进行中的订单_行程管理", tags = {"小程序-获取正在进行中的订单_行程管理"})
+    @GetMapping("/api/v1/mini-program/order/active_itineraryManage")
+    @XpClientCheck(checkToken = false, checkOtpToken = true)
+    public R<XpOrderDetailVO> getActiveOrder_itineraryManage(HttpServletRequest request) {
+        // uid已通过拦截器otp校验,可以直接使用
+        String uid = request.getHeader("XP-Uid");
+        return R.ok(xpOrderService.getActiveOrder_itineraryManage(uid));
+    }
 
     /**
      * 查询历史订单列表
@@ -421,7 +433,6 @@
      * +
      * 取消订单
      */
-
     @PutMapping("/api/v1/mini-program/order/cancel/{orderId}")
     @ApiOperation(value = "取消订单", tags = {"小程序-取消订单"})
     @XpClientCheck(checkToken = false, checkOtpToken = true)
@@ -555,6 +566,9 @@
     @PostMapping("/api/v1/mini-program/order/queryOrderRoute")
     @XpClientCheck(checkToken = false, checkOtpToken = true)
     public R<RouteVo> queryOrderRoute(@Validated @RequestBody QueryOrderRouteDTO dto, HttpServletRequest request) {
+        if(dto.getOrderId() == null){
+            return R.fail("参数不能为空");
+        }
         String uid = request.getHeader("XP-Uid");
         // 查询订单信息
         XpOrder xpOrder = xpOrderService.getById(dto.getOrderId());
@@ -584,7 +598,9 @@
     @GetMapping("/api/v1/mini-program/order/queryOrderTrajectory")
     @XpClientCheck(checkToken = false, checkOtpToken = true)
     public R<RouteVo> queryOrderTrajectory(@RequestParam String orderId, HttpServletRequest request) {
-        String uid = request.getHeader("XP-Uid");
+        if(orderId == null){
+            return R.fail("参数不能为空");
+        }
         List<OrderTrajectory> trajectories = mongoTemplate.find(
                 new Query(Criteria.where("orderId").is(Long.valueOf(orderId)))
                         .with(Sort.by(Sort.Direction.ASC, "locatetime")),
@@ -621,4 +637,7 @@
         return R.ok((int)count);
     }
 
+
+
+
 }
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderWaypointController.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderWaypointController.java
new file mode 100644
index 0000000..9913ca7
--- /dev/null
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderWaypointController.java
@@ -0,0 +1,51 @@
+package com.xiaopeng.order.controller;
+
+
+import com.xiaopeng.api.model.order.XpOrder;
+import com.xiaopeng.api.model.order.XpOrderWaypoint;
+import com.xiaopeng.common.core.domain.R;
+import com.xiaopeng.order.service.IXpOrderService;
+import com.xiaopeng.order.service.IXpOrderWaypointService;
+import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@RestController
+@Api(tags = "订单途经点")
+@RequiredArgsConstructor(onConstructor_ = @Lazy)
+public class XpOrderWaypointController {
+
+
+    @Resource
+    private final IXpOrderWaypointService xpOrderWaypointService;
+    private final IXpOrderService xpOrderService;
+
+    /**
+     * 添加订单途径点
+     */
+    @PostMapping("/api/v1/mini-program/orderWaypoint/save")
+    @ApiOperation(value = "添加订单途径点", tags = {"小程序-添加订单途径点"})
+    @XpClientCheck(checkToken = false, checkOtpToken = true)
+    public R save(@Validated  @RequestBody XpOrderWaypoint entity) {
+        XpOrder xpOrder = xpOrderService.getById(entity.getOrderId());
+        if(xpOrder == null){
+            return R.fail("订单不存在");
+        }
+        entity.setId(null);
+        boolean b = xpOrderWaypointService.save(entity);
+        if(b){
+            return R.ok();
+        }
+        return R.fail("订单不存在");
+    }
+
+
+}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mapper/XpOrderWaypointMapper.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mapper/XpOrderWaypointMapper.java
new file mode 100644
index 0000000..10177b8
--- /dev/null
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mapper/XpOrderWaypointMapper.java
@@ -0,0 +1,16 @@
+package com.xiaopeng.order.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xiaopeng.api.model.order.XpOrderWaypoint;
+
+/**
+ * <p>
+ * 订单支付记录 Mapper 接口
+ * </p>
+ *
+ * @author mitao
+ * @since 2026-02-03
+ */
+public interface XpOrderWaypointMapper extends BaseMapper<XpOrderWaypoint> {
+
+}
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderDetailVO.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderDetailVO.java
index f1c115e..effb5ea 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderDetailVO.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/model/vo/XpOrderDetailVO.java
@@ -2,13 +2,12 @@
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import com.xiaopeng.api.dto.operation.LonLatDto;
+import com.xiaopeng.api.model.order.XpOrderWaypoint;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.math.BigDecimal;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -47,6 +46,8 @@
 
     @ApiModelProperty(value = "下单城市名称")
     private String cityName;
+    @ApiModelProperty(value = "下单城市编码")
+    private String cityCode;
 
 
     @ApiModelProperty(value = "预计时间")
@@ -131,6 +132,11 @@
     @ApiModelProperty(value = "车辆id")
     private Long vehicleId;
 
+    @ApiModelProperty(value = "车辆vin码")
+    private String vehicleVin;
+
+    @ApiModelProperty(value = "车辆颜色")
+    private String vehicleColor;
     @ApiModelProperty(value = "车牌号")
     private String plateNumber;
 
@@ -205,4 +211,8 @@
     }
     @ApiModelProperty(value = "后备箱状态(1=打开,2=关闭)")
     private Integer openTrunk;
+
+    @ApiModelProperty(value = "途径点信息")
+    private List<XpOrderWaypoint> xpOrderWaypoints;
+
 }
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
index bf5b0a5..811ae4d 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
@@ -226,6 +226,8 @@
 
     R<String> feeDescription(Long orderId, String uid);
 
+    XpOrderDetailVO getActiveOrder_itineraryManage(String uid);
+
     /**
      * 订单改价
      * @param id
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderWaypointService.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderWaypointService.java
new file mode 100644
index 0000000..d35ec23
--- /dev/null
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderWaypointService.java
@@ -0,0 +1,16 @@
+package com.xiaopeng.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.xiaopeng.api.model.order.XpOrderWaypoint;
+
+/**
+ * <p>
+ * 订单支付记录 服务类
+ * </p>
+ *
+ * @author mitao
+ * @since 2026-02-03
+ */
+public interface IXpOrderWaypointService extends IService<XpOrderWaypoint> {
+
+}
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 2edff13..5b8dd17 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
@@ -16,7 +16,7 @@
 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.CruisePointDto;
+import com.xiaopeng.api.dto.map.RouteAndFareDto;
 import com.xiaopeng.api.dto.operation.LonLatDto;
 import com.xiaopeng.api.dto.order.GetOrderNumDto;
 import com.xiaopeng.api.dto.order.HistoryEndPointsDto;
@@ -27,18 +27,13 @@
 import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
 import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
 import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto;
-import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto;
-import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto;
 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.map.XpMapClient;
-import com.xiaopeng.api.feignClient.operation.XpCruisePlanClient;
-import com.xiaopeng.api.feignClient.operation.XpPointClient;
-import com.xiaopeng.api.feignClient.operation.XpPricingClient;
-import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient;
+import com.xiaopeng.api.feignClient.operation.*;
 import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
 import com.xiaopeng.api.feignClient.vehicleConvoy.*;
 import com.xiaopeng.api.model.maintenance.XpTaskRule;
@@ -46,6 +41,7 @@
 import com.xiaopeng.api.model.order.*;
 import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
 import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
+import com.xiaopeng.api.service.BootCommonService;
 import com.xiaopeng.api.vo.OrderType;
 import com.xiaopeng.api.vo.account.UserCouponVo;
 import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
@@ -92,7 +88,6 @@
 import com.xiaopeng.order.utils.GDMapGeocodingUtil;
 import com.xiaopeng.order.utils.TaxiPricingDemoService;
 import com.xiaopeng.order.utils.RegionCodeFilterUtil;
-import com.xiaopeng.order.utils.TaxiPricingDemoService;
 import com.xiaopeng.order.utils.XpPricingUtil;
 import com.xiaopeng.order.utils.holiday.HolidayUtil;
 import com.xiaopeng.order.vo.OrderDetailVo;
@@ -163,6 +158,10 @@
     private final VehicleBuriedPointClient vehicleBuriedPointClient;
     private final IXpTestOrderService xpTestOrderService;
     private final XpMapClient xpMapClient;
+    @Resource
+    private  XpRoutePlanClient xpRoutePlanClient;
+    @Resource
+    private BootCommonService bootCommonService;
 
 
     @Autowired
@@ -1591,11 +1590,11 @@
     @ShardingSphereTransactionType(TransactionType.BASE)
     public void cancelOrder(Long orderId, String uid) {
         XpOrder order = this.getById(orderId);
-        if (order.getStatus() == 0) {
-            return;
-        }
         if (order == null) {
             throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS);
+        }
+        if (order.getStatus() == 0) {
+            return;
         }
         if (!order.getAppUserId().toString().equals(uid)) {
             throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS);
@@ -1603,7 +1602,6 @@
         if (order.getStatus() > 5 || order.getStatus() < 1) {
             throw new ServiceException("订单状态错误", I18nKeyConstant.ORDER_STATUS_ERROR);
         }
-
         try {
             redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
         } catch (Exception e) {
@@ -1625,39 +1623,20 @@
                 }
             }
         }
-
-        if (order.getStatus() == 1) {
-            order.setStatus(0);
-            order.setAppUserId(null);
-            baseMapper.updateById(order);
-            redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS);
-            return;
-        }
-        /*
-        order.setStatus(0);
-        order.setAppUserId(null);
-        baseMapper.updateById(order);
-        redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS);
-        XpOrderCancel xpOrderCancel = new XpOrderCancel();
-        xpOrderCancel.setOrderId(orderId);
-        xpOrderCancel.setUserId(Long.valueOf(uid));
-        xpOrderCancel.setCancelSource(1);
-        xpOrderCancel.setCancelReason("用户取消订单");
-        xpOrderCancelService.save(xpOrderCancel);
-        */
-
-        // 移除mongo数据
-        xpPricingClient.deleteXpGeoQueryEntity(order.getId().toString());
-
-        // 下发命令
-        if (null != order.getVehicleId()) {
+        else{// 下发命令
             R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(order.getVehicleId());
-            // 组装调用车机参数
-            CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo();
             XpVehicle xpVehicle = xpVehicleR.getData();
             if (xpVehicle == null) {
                 throw new ServiceException("车辆不存在", I18nKeyConstant.VEHICLE_NOT_EXISTS);
             }
+            //是否能取消行程
+            boolean cancelShow = this.isCancelShow(order,xpVehicle.getVehicleVin());
+            if(cancelShow){
+                throw new ServiceException("当前订单状态不允许取消,行程即将完成", I18nKeyConstant.ORDER_CANCEL_FAILED);
+            }
+
+            // 组装调用车机参数
+            CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo();
             cancelTaxiPassengerVo.setVin(xpVehicle.getVehicleVin());
             cancelTaxiPassengerVo.setUid(uid);
             cancelTaxiPassengerVo.setOrderNo(order.getOrderNumber());
@@ -1688,7 +1667,19 @@
             //车辆继续巡游
             addCruiseMission(xpVehicle.getId());
         }
+        order.setStatus(0);
+        order.setAppUserId(null);
+        baseMapper.updateById(order);
+        redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS);
 
+        XpOrderCancel xpOrderCancel = new XpOrderCancel();
+        xpOrderCancel.setOrderId(orderId);
+        xpOrderCancel.setUserId(Long.valueOf(uid));
+        xpOrderCancel.setCancelSource(1);
+        xpOrderCancel.setCancelReason("用户取消订单");
+        xpOrderCancelService.save(xpOrderCancel);
+        // 移除mongo数据
+        xpPricingClient.deleteXpGeoQueryEntity(order.getId().toString());
     }
 
     @Override
@@ -1918,6 +1909,8 @@
                         DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(arriveTime)),
                         endTripJobMaps
                 );
+
+
                 // 添加车辆到达终点后限停时间到后驶离的定时任务
                 //时间到后将车辆状态回滚到空闲、添加巡游订单,解绑用户和车辆关系,车辆驶离点位
                 XpPoint point = xpPointClient.queryById(xpOrder.getEndPointId()).getData();
@@ -1927,13 +1920,38 @@
                                 .put("appid", appid)
                                 .put("orderType", OrderType.USER_ORDER)
                                 .build();
-                QuartzManager.addJob(
-                        AddCruiseMissionJob.class,
-                        (AddCruiseMissionJob.name + xpOrder.getId()).toUpperCase(),
-                        TimeJobType.ADD_CRUISE_MISSION,
-                        DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(point.getParkingTimeLimit())),
-                        jobMaps
-                );
+
+                Long id = redisService.getCacheObject(CacheConstants.nextOrder(xpOrder.getId().toString()));
+                if(id != null){
+                    XpOrder nextOrder = getById(id);
+                    XpVehicle nextVehicle = xpVehicleClient.queryById(nextOrder.getVehicleId()).getData();
+                    PushOrderDto pushOrderDto = new PushOrderDto();
+                    pushOrderDto.setOrderId(nextOrder.getId().toString());
+                    pushOrderDto.setStartLatitude(nextOrder.getStartLat());
+                    pushOrderDto.setStartLongitude(nextOrder.getStartLon());
+                    pushOrderDto.setEndLatitude(nextOrder.getEndLat());
+                    pushOrderDto.setEndLongitude(nextOrder.getEndLon());
+                    pushOrderDto.setEndPoiName(nextOrder.getEndPointName());
+                    pushOrderDto.setOrderType(OrderType.USER_ORDER);
+                    pushOrderDto.setStage(1);
+                    pushOrderDto.setVin(nextVehicle.getVehicleVin());
+                    orderMissionClient.pushOrder(pushOrderDto);
+                    QuartzManager.addJob(
+                            AddCruiseMissionJob.class,
+                            (AddCruiseMissionJob.name + nextOrder.getId()).toUpperCase(),
+                            TimeJobType.ADD_CRUISE_MISSION,
+                            DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(point.getParkingTimeLimit())),
+                            jobMaps
+                    );
+                } else {
+                    QuartzManager.addJob(
+                            AddCruiseMissionJob.class,
+                            (AddCruiseMissionJob.name + xpOrder.getId()).toUpperCase(),
+                            TimeJobType.ADD_CRUISE_MISSION,
+                            DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(point.getParkingTimeLimit())),
+                            jobMaps
+                    );
+                }
                 break;
             default:
                 break;
@@ -2031,11 +2049,13 @@
         redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 8, 24L, TimeUnit.HOURS);
 
         // 根据订单所属开通城市id 查询定价
-        R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId());
-        XpPricing pricing = pricingByCityId.getData();
+        XpPricing pricing = bootCommonService.getXpPricing(order.getCityId(),order.getVehicleId());
         if (pricing == null) {
             throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS);
         }
+
+
+
         // 费用
         // 查询订单轨迹
         List<OrderTrajectory> trajectories = mongoTemplate.find(
@@ -2407,7 +2427,7 @@
      *
      * @param order
      */
-
+    @Override
     public void addCruiseMission(Long vehicleId, XpOrder order) {
         XpVehicle vehicle = xpVehicleClient.queryById(vehicleId).getData();
         log.info("添加巡游订单 {}", vehicle.getPlateNumber());
@@ -3109,12 +3129,11 @@
     @Override
     public R<String> feeDescription(Long orderId, String uid) {
         XpOrder order = this.getById(orderId);
-        R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId());
-        XpPricing pricing = pricingByCityId.getData();
-        if (pricing == null) {
+        XpPricing xpPricing = bootCommonService.getXpPricing(order.getCityId(), order.getVehicleId());
+        if (xpPricing == null) {
             throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS);
         } else {
-            return R.ok(pricing.getPriceRule());
+            return R.ok(xpPricing.getPriceRule());
         }
     }
 
@@ -3451,6 +3470,9 @@
         if (xpOrder.getVehicleId() != null) {
             R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId());
             XpVehicle vehicle = xpVehicleR.getData();
+            xpOrderDetailVO.setVehicleVin(vehicle.getVehicleVin());
+            xpOrderDetailVO.setVehicleModel(vehicle.getVehicleModel());
+            xpOrderDetailVO.setVehicleColor(vehicle.getVehicleColor());
             xpOrderDetailVO.setPlateNumber(vehicle.getPlateNumber());
             xpOrderDetailVO.setVehiclePictures(vehicle.getVehiclePictures());
         }
@@ -3462,24 +3484,118 @@
             xpOrder.setAppUserId(null);
             this.updateById(xpOrder);
         }
-        Boolean cancelShow = true; //是否能取消行程
-        xpOrderDetailVO.setCancelShow(cancelShow);
-
-
-
         return xpOrderDetailVO;
     }
 
+    @Override
+    public XpOrderDetailVO getActiveOrder_itineraryManage(String uid){
+        XpOrderDetailVO xpOrderDetailVO = new XpOrderDetailVO();
+        XpOrder xpOrder = this.baseMapper.selectOne(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, Long.parseLong(uid)).in(XpOrder::getStatus, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 1"));
+        if (xpOrder == null) {
+            return null;
+        }
+        BeanUtils.copyProperties(xpOrder, xpOrderDetailVO);
+        if (xpOrder.getVehicleId() != null) {
+            R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId());
+            XpVehicle vehicle = xpVehicleR.getData();
+            xpOrderDetailVO.setVehicleVin(vehicle.getVehicleVin());
+            xpOrderDetailVO.setVehicleModel(vehicle.getVehicleModel());
+            xpOrderDetailVO.setVehicleColor(vehicle.getVehicleColor());
+            xpOrderDetailVO.setPlateNumber(vehicle.getPlateNumber());
+
+            xpOrderDetailVO.setVehiclePictures(vehicle.getVehiclePictures());
+        }
+        Boolean cancelShow = isCancelShow(xpOrder,xpOrderDetailVO.getVehicleVin()); //是否能取消行程
+        xpOrderDetailVO.setCancelShow(cancelShow);
+        return xpOrderDetailVO;
+    }
     /**
      * 取消行程:若处于“送驾中”且离目的地小于10分钟路程(后台配置),【取消行程】按钮应置灰;
      * 修改行程:
      * 1. 当前剩余里程 < 800米 (后台配置)或 剩余时间 < 5分钟(后台配置)(以先到者为准),禁止修改,按钮置灰。
      * 2. 单次行程最多允许修改 2次 (后台配置)目的地,防恶意高频调用
+     * 特殊豁免:若系统检测到车辆在当前坐标时速 < 3km/h 且持续时间 > 3分钟(后台配置)(判定为极度拥堵或异常停滞),此时解除限制,允许用户修改目的地或新增途径点以寻找更近的下车位置。
      * @return
      */
-    private Boolean isCancelShow(){
+    private boolean isCancelShow(XpOrder xpOrder,String vehicleVin) {
+        boolean isCancel = false;
+        //获取配置文件
+        int sylc = 800;//单位米 todo yyy 需要读取后台配置文件
+        int sysj = 5;//单位分钟 todo yyy 需要读取后台配置文件
+        // 减少3分钟 获取3分账内的 行程数据
+        long minute =3;//todo yyy 需要读取后台配置文件
 
-        return true;
+
+        List<OrderTrajectory> orderTrajectories = queryOrderTrajectories(xpOrder.getId());
+        if(!orderTrajectories.isEmpty()){// 减少3分钟 获取3分账内的 行程数据
+            //3千米/小时 转换成分钟 50米/分钟
+            BigDecimal suduDefault = new BigDecimal("3");//3千米/小时
+            BigDecimal suduDefault1 = suduDefault.multiply(BigDecimal.valueOf(1000)) ;
+            BigDecimal suduDefaultNew =suduDefault1.divide(BigDecimal.valueOf(60),2,RoundingMode.HALF_EVEN);
+
+            LocalDateTime minutesBefore = LocalDateTime.now().minusMinutes(minute);
+            long milliseconds = DateUtils.getMilliseconds(minutesBefore);
+            List<OrderTrajectory> orderTrajectoriesNew = new ArrayList<>();
+            for (OrderTrajectory orderTrajectory : orderTrajectories) {
+                if(orderTrajectory.getLocatetime() > milliseconds){
+                    orderTrajectoriesNew.add(orderTrajectory);
+                }
+            }
+            /*
+            获取最近3分钟的 数据 速度、平均
+             */
+            //计算行驶总距离和时长
+            Double reduce = orderTrajectoriesNew.stream().map(OrderTrajectory::getDistance).reduce(0.0, Double::sum);
+            BigDecimal xcsudu = new BigDecimal(reduce).divide(new BigDecimal(minute),2, RoundingMode.HALF_EVEN);//米/分钟
+
+            //特殊豁免:若系统检测到车辆在当前坐标时速 < 3km/h 且持续时间 > 3分钟(后台配置)(判定为极度拥堵或异常停滞),此时解除限制,允许用户修改目的地或新增途径点以寻找更近的下车位置。
+            if(xcsudu.compareTo(suduDefaultNew)<0){
+                return true;
+            }
+        }
+        RouteVo routeVo = this.getRouteVo(xpOrder, vehicleVin);
+        if(routeVo.getDistance() <sylc){
+            isCancel = true;
+        }
+        if(routeVo.getDuration() < sysj){
+            isCancel = true;
+        }
+
+        return isCancel;
+    }
+
+    /**
+     * 获取两个点位车的距离 和时间
+     * @param xpOrder
+     * @param vehicleVin
+     * @return
+     */
+    private RouteVo getRouteVo(XpOrder xpOrder,String vehicleVin){
+
+        VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vehicleVin)), VehiclePosition.class);
+        // 计算距离 和 时间
+        RouteAndFareDto routeAndFareDto = new RouteAndFareDto();
+        LonLatDto lonLatDto = new LonLatDto();
+        lonLatDto.setLongitude(vehiclePosition.getPoint().getX());//经度
+        lonLatDto.setLatitude(vehiclePosition.getPoint().getY());
+        routeAndFareDto.setOrigin(lonLatDto);
+
+        LonLatDto lonLatDto1 = new LonLatDto();
+        lonLatDto1.setLongitude(xpOrder.getEndLon());
+        lonLatDto1.setLatitude(xpOrder.getEndLat());
+        routeAndFareDto.setDestination(lonLatDto1);
+
+//        XpOpenCity xpOpenCity = xpOpenCityMapper.selectById(dto.getOpenCityId());
+//        xpRoutePlanClient.
+        XpRoutePlan xpRoutePlan = xpRoutePlanClient.getXpRoutePlanOpenCityId(xpOrder.getCityId()).getData();
+        if (xpRoutePlan != null) {
+            routeAndFareDto.setRoutePlanRule(xpRoutePlan.getRoutePlanRule());
+        }
+        R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+        if(distanceAndDuration.getCode()!=200){
+            throw new ServiceException("未找到路径", I18nKeyConstant.PATH_NOT_FOUND);
+        }
+        return distanceAndDuration.getData();
     }
 
 
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderWaypointServiceImpl.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderWaypointServiceImpl.java
new file mode 100644
index 0000000..d735413
--- /dev/null
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderWaypointServiceImpl.java
@@ -0,0 +1,24 @@
+package com.xiaopeng.order.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xiaopeng.api.model.order.XpOrderWaypoint;
+import com.xiaopeng.order.mapper.XpOrderWaypointMapper;
+import com.xiaopeng.order.service.IXpOrderWaypointService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 订单支付记录 服务实现类
+ * </p>
+ *
+ * @author mitao
+ * @since 2026-02-03
+ */
+@Service
+public class XpOrderWaypointServiceImpl extends ServiceImpl<XpOrderWaypointMapper, XpOrderWaypoint> implements IXpOrderWaypointService {
+
+
+
+
+
+}
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 3b26897..b37e8ab 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
@@ -9,12 +9,10 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.ImmutableMap;
-import com.xiaopeng.api.dto.account.GetUserCouponDto;
 import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
 import com.xiaopeng.api.dto.map.RouteAndFareDto;
 import com.xiaopeng.api.dto.operation.LonLatDto;
 import com.xiaopeng.api.dto.order.GetOrderNumDto;
-import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
 import com.xiaopeng.api.feignClient.account.UserResourcesClient;
 import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
 import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient;
@@ -31,16 +29,14 @@
 import com.xiaopeng.api.model.order.*;
 import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
 import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
+import com.xiaopeng.api.service.BootCommonService;
 import com.xiaopeng.api.vo.OrderType;
-import com.xiaopeng.api.vo.SystemEventType;
-import com.xiaopeng.api.vo.account.UserCouponVo;
 import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
 import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType;
 import com.xiaopeng.api.vo.operation.RouteVo;
 import com.xiaopeng.api.vo.order.FareBreakdownDetailVo;
 import com.xiaopeng.api.vo.order.XpPricingCardVo;
 import com.xiaopeng.common.core.constant.CacheConstants;
-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.exception.ServiceException;
@@ -54,7 +50,6 @@
 import com.xiaopeng.order.constant.I18nKeyConstant;
 import com.xiaopeng.order.job.base.QuartzManager;
 import com.xiaopeng.order.job.base.TimeJobType;
-import com.xiaopeng.order.job.jobs.AddCruiseMissionJob;
 import com.xiaopeng.order.job.jobs.EndTripJob;
 import com.xiaopeng.order.job.jobs.OrderCancelJob;
 import com.xiaopeng.order.mangodb.model.OrderTrajectory;
@@ -88,14 +83,13 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
+import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.ZoneOffset;
 import java.util.*;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -145,6 +139,8 @@
     private final XpTestPointClient testPointClient;
 
 
+    @Resource
+    private BootCommonService bootCommonService;
 
 
 
@@ -192,7 +188,7 @@
         if (openCity == null) {
             throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
         }
-        XpPricing xpPricing = xpPricingClient.getPricingByCid(openCity.getId()).getData();
+        XpPricing xpPricing = bootCommonService.getXpPricing(openCity.getId(),null);
         if (xpPricing == null) {
             throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
         }
@@ -995,8 +991,7 @@
         redisService.setCacheObject("TEST_ORDER_STATUS:" + order.getId(), 8, 24L, TimeUnit.HOURS);
 
         // 根据订单所属开通城市id 查询定价
-        R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId());
-        XpPricing pricing = pricingByCityId.getData();
+        XpPricing pricing = bootCommonService.getXpPricing(order.getCityId(),order.getVehicleId());
         if (pricing == null) {
             throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS);
         }

--
Gitblit v1.7.1