From c96fbe6b0aeb413a17c429133ee6d81d138144b9 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期二, 09 六月 2026 10:58:52 +0800
Subject: [PATCH] Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.0

---
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java |  694 +++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 565 insertions(+), 129 deletions(-)

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 3ebda38..43d69ba 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
@@ -4,6 +4,7 @@
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Snowflake;
 import cn.hutool.core.util.DesensitizedUtil;
+import cn.hutool.core.util.IdUtil;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
@@ -33,6 +34,7 @@
 import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto;
 import com.xiaopeng.api.feignClient.account.SysGroupMenuClient;
 import com.xiaopeng.api.feignClient.account.UserResourcesClient;
+import com.xiaopeng.api.feignClient.account.XpAppUserClient;
 import com.xiaopeng.api.feignClient.account.XpAppUserCollectAddrClient;
 import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
 import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient;
@@ -48,6 +50,7 @@
 import com.xiaopeng.api.feignClient.vehicleConvoy.*;
 import com.xiaopeng.api.model.maintenance.XpTaskRule;
 import com.xiaopeng.api.model.operation.*;
+import com.xiaopeng.api.model.account.XpAppUser;
 import com.xiaopeng.api.model.order.*;
 import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
 import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
@@ -87,6 +90,7 @@
 import com.xiaopeng.common.redis.service.RedisService;
 import com.xiaopeng.common.security.service.TokenService;
 import com.xiaopeng.common.security.utils.SecurityUtils;
+import com.xiaopeng.order.config.MinistryTransportProperties;
 import com.xiaopeng.order.constant.I18nKeyConstant;
 import com.xiaopeng.order.dto.MileageDto;
 import com.xiaopeng.order.dto.UserOrderListDto;
@@ -98,6 +102,9 @@
 import com.xiaopeng.order.mapper.XpCruiseOrderMapper;
 import com.xiaopeng.order.mapper.XpOrderDetailMapper;
 import com.xiaopeng.order.mapper.XpOrderMapper;
+import com.xiaopeng.order.model.dto.CreditPaySuccessCallDto;
+import com.xiaopeng.order.model.dto.RegulationOrderCreateInfoDTO;
+import com.xiaopeng.order.model.dto.RegulationOrderMatchInfoDTO;
 import com.xiaopeng.order.model.dto.XpOrderCommentDto;
 import com.xiaopeng.order.model.dto.XpOrderPayDto;
 import com.xiaopeng.order.model.query.XpHistoryOrderListQuery;
@@ -105,6 +112,7 @@
 import com.xiaopeng.order.model.query.XpOrderPageQuery;
 import com.xiaopeng.order.model.vo.*;
 import com.xiaopeng.order.service.*;
+import com.xiaopeng.order.utils.MinistryOfTransportOrderReporter;
 import com.xiaopeng.order.utils.*;
 import com.xiaopeng.order.utils.holiday.HolidayUtil;
 import com.xiaopeng.order.vo.*;
@@ -161,10 +169,12 @@
     private final UserResourcesClient userResourcesClient;
     private final XpPointClient xpPointClient;
     private final XpVehicleClient xpVehicleClient;
+    private final XpAppUserClient xpAppUserClient;
     private final XpAppUserCouponClient xpAppUserCouponClient;
     private final XpFleetClient xpFleetClient;
     private final XpFleetVehicleClient xpFleetVehicleClient;
     private final UserVehicleClient userVehicleClient;
+    private final MinistryTransportProperties ministryTransportProperties;
     @Lazy
     @Autowired
     private IXpOrderEvaluateService xpOrderEvaluateService;
@@ -189,6 +199,7 @@
     @Autowired
     private IXpTestOrderService xpTestOrderService;
     private final XpMapClient xpMapClient;
+    private final MinistryOfTransportOrderReporter ministryOfTransportOrderReporter;
     @Resource
     private XpRoutePlanClient xpRoutePlanClient;
     @Resource
@@ -224,6 +235,9 @@
 
     @Resource
     private XpFrdXfipEventClient xpFrdXfipEventClient;
+
+    @Resource
+    private XpTargetedServiceClient targetedServiceClient;
 
     @Value("${robotaxi.appId:xp_robotaxi_api}")
     private String appid;
@@ -516,7 +530,6 @@
         if (Objects.nonNull(query.getEndTime())) {
             wrapper.le(XpOrder::getCreateTime, LocalDateTime.of(query.getEndTime(), LocalTime.MAX));
         }
-        wrapper.orderByDesc(XpOrder::getCreateTime);
         return wrapper;
     }
 
@@ -701,7 +714,9 @@
      * 取消订单
      */
     private void cancelOrder(XpOrder order) {
-        redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
+        if(StringUtils.isNotEmpty(order.getQueueName())){
+            redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
+        }
 
         Long userId = order.getAppUserId();
         Integer status = order.getStatus();
@@ -861,6 +876,7 @@
 
                 // 下发命令
                 PushOrderDto pushOrderDto = new PushOrderDto();
+                pushOrderDto.setEndTaskId(order.getStatus() < 6 ? order.getXpuStartTaskId() : order.getXpuEndTaskId());
                 pushOrderDto.setOrderId(order.getId().toString());
                 pushOrderDto.setVin(xpVehicle.getVehicleVin());
                 pushOrderDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
@@ -1011,6 +1027,17 @@
         }
 
         if (order.getOfficialPartnerId() == null) {
+            //给车端发送取消靠边停车的报文
+            PushOrderDto cancelDto = new PushOrderDto();
+            cancelDto.setStartTaskId(order.getXpuStartTaskId());
+            cancelDto.setEndTaskId(order.getXpuEndTaskId());
+            cancelDto.setOrderId(order.getId().toString());
+            cancelDto.setVin(vin);
+            cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
+            cancelDto.setCancelScene(CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE.getCode());
+            orderMissionClient.cancelOrder(cancelDto);
+
+
             //创建定时任务执行延迟驶离终点和下发巡游单
             XpPoint point = xpPointClient.queryById(order.getEndPointId()).getData();
             Integer parkingTimeLimit = point.getParkingTimeLimit();
@@ -1352,7 +1379,11 @@
                 returnOrder.setOrderReverse(lastCruise.getOrderReverse());
                 log.info("巡游订单状态为{},默认返回原出发点", lastCruise.getStatus());
             }
-
+            R<XpCruiseOrder> orderR = xpCruisePlanClient.findReturnCruisePoint(returnOrder);
+            if(null != orderR && 200 != orderR.getCode()){
+                log.error(orderR.getMsg());
+                return;
+            }
             xpCruiseOrderMapper.insert(returnOrder);
 
             // 下发巡游订单到原车辆
@@ -1880,7 +1911,9 @@
             throw new ServiceException("订单状态错误", I18nKeyConstant.ORDER_STATUS_ERROR);
         }
         try {
-            redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
+            if(StringUtils.isNotEmpty(order.getQueueName())){
+                redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
+            }
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -1973,6 +2006,39 @@
                     e.printStackTrace();
                 }
 
+                //判断是否有连环单
+                String json = redisService.getCacheObject(CacheConstants.nextOrder(order.getId().toString()));
+                if (StringUtils.isNotEmpty(json)) {
+                    JSONObject jsonObject = JSON.parseObject(json);
+                    Long id = jsonObject.getLong("orderId");
+                    //判断订单状态
+                    XpOrder xpOrder1 = this.getById(id);
+                    if (2 == xpOrder1.getStatus()) {
+                        //开始推送订单给车端
+                        // 下发命令
+                        PushOrderDto pushOrderDto = new PushOrderDto();
+                        pushOrderDto.setStartTaskId(xpOrder1.getXpuStartTaskId());
+                        pushOrderDto.setEndTaskId(xpOrder1.getXpuEndTaskId());
+                        pushOrderDto.setVin(vin);
+                        pushOrderDto.setOrderId(xpOrder1.getId().toString());
+                        pushOrderDto.setStartWaypointId(xpOrder1.getStartPointId());
+                        pushOrderDto.setEndWaypointId(xpOrder1.getEndPointId());
+                        pushOrderDto.setStartLatitude(xpOrder1.getStartLat());
+                        pushOrderDto.setStartLongitude(xpOrder1.getStartLon());
+                        pushOrderDto.setEndLatitude(xpOrder1.getEndLat());
+                        pushOrderDto.setEndLongitude(xpOrder1.getEndLon());
+                        pushOrderDto.setEndPoiName(xpOrder1.getEndPointName());
+                        pushOrderDto.setOrderType(OrderType.USER_ORDER);
+                        pushOrderDto.setStage(1);
+                        pushOrderDto.setLastOrderId(order.getId().toString());
+                        pushOrderDto.setLastXpuTaskId(status == 1 ? order.getXpuStartTaskId() : order.getXpuEndTaskId());
+                        pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
+                        // 调用推送服务  orderId + carVin
+                        orderMissionClient.pushOrder(pushOrderDto);
+                        log.info("开始推送 {} 订单到XPU。单号 {}", xpOrder1.getOrderNumber(), xpOrder1.getOrderNumber());
+                        return;
+                    }
+                }
                 //车辆继续巡游
                 addCruiseMission(order, status);
             }
@@ -2027,7 +2093,9 @@
         xpOrderCancel.setCreateTime(LocalDateTime.now());
         xpOrderCancelService.save(xpOrderCancel);
 
-        redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
+        if(StringUtils.isNotEmpty(order.getQueueName())){
+            redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
+        }
 
         // 消息推送
         Map<String, Object> params = new HashMap<>();
@@ -2555,7 +2623,7 @@
             log.info("计算价格-保存费用明细 {} {}", orderId, JSON.toJSONString(xpOrderDetails));
 
             // 默认费率1
-            double priceRate = 1;
+            double priceRate = 100;
             if (pricing.getIsDynamicPrice() == 1) {
                 // 先判断是否已经调价过了
                 Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid);
@@ -2563,60 +2631,55 @@
                     // 是否调价过了
                     priceRate = Double.parseDouble(userDynamicPriceObj.toString());
                 } else {
-                    //是否触发动态调价 redis获取
-                    Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + order.getCityId());
-                    if (dynamicPriceObj != null) {
-                        JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
-                        // 触发动态调价
-                        // value=时间
-                        String timeStr = dynamicPriceObj.toString();
-                        // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
-                        Integer num = this.getOrderNum(new GetOrderNumDto(timeStr, order.getCityId()));
-                        // X单上升一次调价
-                        Integer orderNum = getOrderNum(jsonObject, 4);
-                        // 需要调价的次数
-                        int count = num / orderNum;
-                        if (count > 0) {
-                            // 计算每次上升的费率
-                            Integer upRate = getOrderNum(jsonObject, 5);
-                            BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
-                            for (int i = count; i > 0; i--) {
-                                // 当前费率+(费率*上升百分比)
-                                priceRate = new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
-                            }
-                            if(priceRate > 1){
-                                // 冷却时间
-                                Integer time = getOrderNum(jsonObject, 6);
-                                // 触发调价了
-                                redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
-                            }
+                    JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
+                    Integer num1 = jsonObject.getInteger("num1");
+                    String timeStr = LocalDateTime.now().minusMinutes(num1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
+                    Integer num = this.getOrderNum(new GetOrderNumDto(timeStr, order.getCityId()));
+                    // X单上升一次调价
+                    Integer orderNum = getOrderNum(jsonObject, 4);
+                    // 需要调价的次数
+                    int count = num / orderNum;
+                    if (count > 0) {
+                        // 计算每次上升的费率
+                        Integer upRate = getOrderNum(jsonObject, 5);
+                        BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
+                        for (int i = count; i > 0; i--) {
+                            // 当前费率+(费率*上升百分比)
+                            priceRate = new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                        }
+                        if(priceRate > 1){
+                            // 冷却时间
+                            Integer time = getOrderNum(jsonObject, 6);
+                            // 触发调价了
+                            redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
                         }
                     }
                 }
+                log.info("供需后的费率 {}", priceRate);
 
                 //是否触发动态调价 redis获取
-                Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + order.getCityId());
-                if (dynamicPriceObj != null) {
-                    JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
-                    // 天气预报动态调价
-                    JSONArray ws = jsonObject.getJSONArray("weatherRules");
-                    if (null != ws) {
-                        WeatherDTO data = xpMapClient.wether(order.getCityCode()).getData();
-                        List<WeatherDTO.Lives> lives = data.getLives();
-                        if (lives != null && !lives.isEmpty()) {
-                            String w = lives.get(0).getWeather();
-                            for (Object o : ws) {
-                                JSONObject ele = JSONObject.parseObject(o.toString());
-                                if (w.contains(ele.getString("weatherType")) || ele.getString("weatherType").contains(w)) {
-                                    double floatRate = ele.getDouble("ratio");
-                                    priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
-                                    break;
-                                }
+                JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
+                // 天气预报动态调价
+                JSONArray ws = jsonObject.getJSONArray("weatherRules");
+                if (null != ws) {
+                    WeatherDTO data = xpMapClient.wether(order.getCityCode()).getData();
+                    List<WeatherDTO.Lives> lives = data.getLives();
+                    if (lives != null && !lives.isEmpty()) {
+                        String w = lives.get(0).getWeather();
+                        for (Object o : ws) {
+                            JSONObject ele = JSONObject.parseObject(o.toString());
+                            if (w.contains(ele.getString("weatherType")) || ele.getString("weatherType").contains(w)) {
+                                double floatRate = ele.getDouble("ratio");
+                                priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
+                                break;
                             }
                         }
                     }
                 }
             }
+            priceRate = new BigDecimal(priceRate).divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
+            log.info("浮动费率 {}", priceRate);
             log.info("计算价格-计算费率 {} {}", orderId, priceRate);
             order.setOrderMoney(totalPrice.multiply(new BigDecimal(priceRate)));
             order.setAppUserId(null);
@@ -2684,7 +2747,7 @@
             log.info("应付总额: " + totalAmount + " 元");
             BigDecimal startMoney = BigDecimal.ZERO;
             // 默认费率1
-            double priceRate = 1;
+            double priceRate = 100;
             if (pricing.getIsDynamicPrice() == 1) {
                 // 先判断是否已经调价过了
                 Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid);
@@ -2692,60 +2755,55 @@
                     // 是否调价过了
                     priceRate = Double.parseDouble(userDynamicPriceObj.toString());
                 } else {
-                    //是否触发动态调价 redis获取
-                    Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + order.getCityId());
-                    if (dynamicPriceObj != null) {
-                        JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
-                        // 触发动态调价
-                        // value=时间
-                        String timeStr = dynamicPriceObj.toString();
-                        // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
-                        Integer num = this.getOrderNum(new GetOrderNumDto(timeStr, order.getCityId()));
-                        // X单上升一次调价
-                        Integer orderNum = getOrderNum(jsonObject, 4);
-                        // 需要调价的次数
-                        int count = num / orderNum;
-                        if (count > 0) {
-                            // 计算每次上升的费率
-                            Integer upRate = getOrderNum(jsonObject, 5);
-                            BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
-                            for (int i = count; i > 0; i--) {
-                                // 当前费率+(费率*上升百分比)
-                                priceRate = new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
-                            }
-                            if(priceRate > 1){
-                                // 冷却时间
-                                Integer time = getOrderNum(jsonObject, 6);
-                                // 触发调价了
-                                redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
-                            }
+                    JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
+                    Integer num1 = jsonObject.getInteger("num1");
+                    String timeStr = LocalDateTime.now().minusMinutes(num1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
+                    Integer num = this.getOrderNum(new GetOrderNumDto(timeStr, order.getCityId()));
+                    // X单上升一次调价
+                    Integer orderNum = getOrderNum(jsonObject, 4);
+                    // 需要调价的次数
+                    int count = num / orderNum;
+                    if (count > 0) {
+                        // 计算每次上升的费率
+                        Integer upRate = getOrderNum(jsonObject, 5);
+                        BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
+                        for (int i = count; i > 0; i--) {
+                            // 当前费率+(费率*上升百分比)
+                            priceRate = new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                        }
+                        if(priceRate > 1){
+                            // 冷却时间
+                            Integer time = getOrderNum(jsonObject, 6);
+                            // 触发调价了
+                            redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
                         }
                     }
                 }
+                log.info("供需后的费率 {}", priceRate);
 
                 //是否触发动态调价 redis获取
-                Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + order.getCityId());
-                if (dynamicPriceObj != null) {
-                    JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
-                    // 天气预报动态调价
-                    JSONArray ws = jsonObject.getJSONArray("weatherRules");
-                    if (null != ws) {
-                        WeatherDTO data = xpMapClient.wether(order.getCityCode()).getData();
-                        List<WeatherDTO.Lives> lives = data.getLives();
-                        if (lives != null && !lives.isEmpty()) {
-                            String w = lives.get(0).getWeather();
-                            for (Object o : ws) {
-                                JSONObject ele = JSONObject.parseObject(o.toString());
-                                if (w.contains(ele.getString("weatherType")) || ele.getString("weatherType").contains(w)) {
-                                    double floatRate = ele.getDouble("ratio");
-                                    priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
-                                    break;
-                                }
+                JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
+                // 天气预报动态调价
+                JSONArray ws = jsonObject.getJSONArray("weatherRules");
+                if (null != ws) {
+                    WeatherDTO data = xpMapClient.wether(order.getCityCode()).getData();
+                    List<WeatherDTO.Lives> lives = data.getLives();
+                    if (lives != null && !lives.isEmpty()) {
+                        String w = lives.get(0).getWeather();
+                        for (Object o : ws) {
+                            JSONObject ele = JSONObject.parseObject(o.toString());
+                            if (w.contains(ele.getString("weatherType")) || ele.getString("weatherType").contains(w)) {
+                                double floatRate = ele.getDouble("ratio");
+                                priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
+                                break;
                             }
                         }
                     }
                 }
             }
+            priceRate = new BigDecimal(priceRate).divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
+            log.info("浮动费率 {}", priceRate);
             log.info("计算价格-计算费率 {} {}", orderId, priceRate);
             // 封装费用明细数据
             for (Map.Entry<String, BigDecimal> stringBigDecimalEntry : bill.entrySet()) {
@@ -2965,8 +3023,23 @@
         // 判断是否有计划
         R<XpCruisePlanVehicle> xpCruisePlanR = xpCruisePlanClient.getCruisePlan(vehicle.getId());
         if (xpCruisePlanR == null || xpCruisePlanR.getData() == null) {
-            log.info("添加巡游单失败,没有符合条件的巡游计划", vehicle.getPlateNumber());
-            return;
+            log.info("未找到匹配的巡游计划,无法执行巡游订单 {}", vehicle.getPlateNumber());
+            //没有巡游计划,判断是否在定向服务里面
+            List<XpTargetedServiceVehicle> data = targetedServiceClient.getAllTargetedServiceVehicleByCityCode(order.getCityCode()).getData();
+            if(data.isEmpty()){
+                log.info("给车端发送取消行程报文 {}", vehicle.getPlateNumber());
+
+                PushOrderDto cancelDto = new PushOrderDto();
+                cancelDto.setStartTaskId(order.getXpuStartTaskId());
+                cancelDto.setEndTaskId(order.getXpuEndTaskId());
+                cancelDto.setOrderId(order.getId().toString());
+                String vin1 = SensitiveDataCryptoUtil.decryptIfPossible(vehicle.getVehicleVin());
+                cancelDto.setVin(vin1);
+                cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
+                cancelDto.setCancelScene(CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE.getCode());
+                orderMissionClient.cancelOrder(cancelDto);
+                return;
+            }
         }
         // 获取配置 根据配置判断是否该收车 如果是则找到收车点位进行收车操作
         R<XpTaskRule> xpTaskRuleR = xpTaskRuleClient.queryDetail();
@@ -3013,11 +3086,14 @@
             xpCruiseOrder.setLastOrderId(xpCruiseOrders.getId());
             xpCruiseOrder.setMissionId(xpCruiseOrders.getMissionId());
         }
+        // 先找计划
+        R<List<XpCruisePlanPoint>> pointList = xpCruisePlanClient.getCruisePlanPointList(vehicle.getId());
+        if(200 != pointList.getCode()){
+            return;
+        }
         //所有没有赋值终点点位的情况,全部导航到巡游计划的第一个点位开始执行巡游任务
         if (null == xpCruiseOrder.getEndPointId()) {
-            // 先找计划
-            List<XpCruisePlanPoint> planPointList = xpCruisePlanClient.getCruisePlanPointList(vehicle.getId()).getData();
-            XpCruisePlanPoint xpCruisePlanPoint = planPointList.get(0);
+            XpCruisePlanPoint xpCruisePlanPoint = pointList.getData().get(0);
             Long endPointId = xpCruisePlanPoint.getPointId();
             XpPoint endPoint = xpPointClient.queryById(endPointId).getData();
             xpCruiseOrder.setEndPointId(endPointId);
@@ -3040,11 +3116,69 @@
                 xpVehicleClient.updateVehicleById(vehicle1);
                 //找到车辆的收车点位 更新终点点位
                 R<XpCruiseOrder> returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder);
-                if (200 != returnCruisePoint.getCode()) {
+                if (200 == returnCruisePoint.getCode()) {
                     xpCruiseOrder = returnCruisePoint.getData();
                     xpCruiseOrder.setOrderType(2);
                     xpCruiseOrder.setOrderReverse(1);
                 }
+            }
+        }else{
+            //获取巡游导航数据,如果无法获取到有效的导航,则继续用下一个点位作为终点
+            LonLatDto destination = new LonLatDto();
+            LonLatDto origin = new LonLatDto();
+            boolean ROUTE_FLAG = false;
+            boolean start = false;
+            if(xpCruiseOrder.getOrderReverse() == 1){
+                for (XpCruisePlanPoint xpCruisePlanPoint1 : pointList.getData()) {
+                    if (start || xpCruisePlanPoint1.getPointId().equals(xpCruiseOrder.getEndPointId())) {
+                        start = true;
+                        origin.setLongitude(xpCruiseOrder.getStartLon());
+                        origin.setLatitude(xpCruiseOrder.getStartLat());
+                        XpPoint xpPoint1 = xpPointClient.queryById(xpCruisePlanPoint1.getPointId()).getData();
+                        destination.setLongitude(xpPoint1.getPointLon());
+                        destination.setLatitude(xpPoint1.getPointLat());
+                        OrderRouteAndFareDto dto1 = new OrderRouteAndFareDto();
+                        dto1.setOrigin(origin);
+                        dto1.setDestination(destination);
+                        dto1.setRouteType(3);
+                        R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto1);
+                        if (200 != routeVoR.getCode()) {
+                            continue;
+                        }
+                        RouteVo routeVo = routeVoR.getData();
+                        redisService.setCacheObject("CRUISE_ROUTE:" + xpCruiseOrder.getVehicleId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
+                        ROUTE_FLAG = true;
+                        break;
+                    }
+                }
+            }else{
+                for (int i = pointList.getData().size() - 1; i >= 0; i--) {
+                    XpCruisePlanPoint xpCruisePlanPoint1 = pointList.getData().get(i);
+                    if(start || xpCruisePlanPoint1.getPointId().equals(xpCruiseOrder.getEndPointId())){
+                        start = true;
+                        origin.setLongitude(xpCruiseOrder.getStartLon());
+                        origin.setLatitude(xpCruiseOrder.getStartLat());
+                        XpPoint xpPoint1 = xpPointClient.queryById(xpCruisePlanPoint1.getPointId()).getData();
+                        destination.setLongitude(xpPoint1.getPointLon());
+                        destination.setLatitude(xpPoint1.getPointLat());
+                        OrderRouteAndFareDto dto1 = new OrderRouteAndFareDto();
+                        dto1.setOrigin(origin);
+                        dto1.setDestination(destination);
+                        dto1.setRouteType(3);
+                        R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto1);
+                        if (200 != routeVoR.getCode()) {
+                            continue;
+                        }
+                        RouteVo routeVo = routeVoR.getData();
+                        redisService.setCacheObject("CRUISE_ROUTE:" + xpCruiseOrder.getVehicleId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
+                        ROUTE_FLAG = true;
+                        break;
+                    }
+                }
+            }
+            if(!ROUTE_FLAG){
+                log.info("巡游计划获取导航信息失败 {}", JSON.toJSONString(vehicle));
+                return;
             }
         }
         xpCruiseOrderMapper.insert(xpCruiseOrder);
@@ -3084,18 +3218,22 @@
         R<XpCruisePlanVehicle> xpCruisePlanR = xpCruisePlanClient.getCruisePlan(vehicle.getId());
         if (xpCruisePlanR == null || xpCruisePlanR.getData() == null) {
             log.info("未找到匹配的巡游计划,无法执行巡游订单 {}", vehicle.getPlateNumber());
-            log.info("给车端发送取消行程报文 {}", vehicle.getPlateNumber());
+            //没有巡游计划,判断是否在定向服务里面
+            List<XpTargetedServiceVehicle> data = targetedServiceClient.getAllTargetedServiceVehicleByCityCode(order.getCityCode()).getData();
+            if(data.isEmpty()){
+                log.info("给车端发送取消行程报文 {}", vehicle.getPlateNumber());
 
-            PushOrderDto cancelDto = new PushOrderDto();
-            cancelDto.setStartTaskId(order.getXpuStartTaskId());
-            cancelDto.setEndTaskId(order.getXpuEndTaskId());
-            cancelDto.setOrderId(order.getId().toString());
-            String vin1 = SensitiveDataCryptoUtil.decryptIfPossible(vehicle.getVehicleVin());
-            cancelDto.setVin(vin1);
-            cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
-            cancelDto.setCancelScene(CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE.getCode());
-            orderMissionClient.cancelOrder(cancelDto);
-            return;
+                PushOrderDto cancelDto = new PushOrderDto();
+                cancelDto.setStartTaskId(order.getXpuStartTaskId());
+                cancelDto.setEndTaskId(order.getXpuEndTaskId());
+                cancelDto.setOrderId(order.getId().toString());
+                String vin1 = SensitiveDataCryptoUtil.decryptIfPossible(vehicle.getVehicleVin());
+                cancelDto.setVin(vin1);
+                cancelDto.setOperation_type(OrderOperationType.CLOUD_CANCEL_ORDER);
+                cancelDto.setCancelScene(CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE.getCode());
+                orderMissionClient.cancelOrder(cancelDto);
+                return;
+            }
         }
         String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehicle.getVehicleVin());
         VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class);
@@ -3144,10 +3282,14 @@
             xpCruiseOrder.setLastOrderId(xpCruiseOrders.getId());
             xpCruiseOrder.setMissionId(xpCruiseOrders.getMissionId());
         }
+        // 先找计划
+        R<List<XpCruisePlanPoint>> pointList = xpCruisePlanClient.getCruisePlanPointList(vehicle.getId());
+        if(200 != pointList.getCode()){
+            return;
+        }
         //所有没有赋值终点点位的情况,全部导航到巡游计划的第一个点位开始执行巡游任务
         if (null == xpCruiseOrder.getEndPointId()) {
-            // 先找计划
-            List<XpCruisePlanPoint> planPointList = xpCruisePlanClient.getCruisePlanPointList(vehicle.getId()).getData();
+            List<XpCruisePlanPoint> planPointList = pointList.getData();
             XpCruisePlanPoint xpCruisePlanPoint = planPointList.get(0);
             Long endPointId = xpCruisePlanPoint.getPointId();
             XpPoint endPoint = xpPointClient.queryById(endPointId).getData();
@@ -3178,6 +3320,64 @@
                     xpCruiseOrder.setOrderType(2);
                     xpCruiseOrder.setOrderReverse(1);
                 }
+            }
+        }else{
+            //获取巡游导航数据,如果无法获取到有效的导航,则继续用下一个点位作为终点
+            LonLatDto destination = new LonLatDto();
+            LonLatDto origin = new LonLatDto();
+            boolean ROUTE_FLAG = false;
+            boolean start = false;
+            if(xpCruiseOrder.getOrderReverse() == 1){
+                for (XpCruisePlanPoint xpCruisePlanPoint1 : pointList.getData()) {
+                    if (start || xpCruisePlanPoint1.getPointId().equals(xpCruiseOrder.getEndPointId())) {
+                        start = true;
+                        origin.setLongitude(xpCruiseOrder.getStartLon());
+                        origin.setLatitude(xpCruiseOrder.getStartLat());
+                        XpPoint xpPoint1 = xpPointClient.queryById(xpCruisePlanPoint1.getPointId()).getData();
+                        destination.setLongitude(xpPoint1.getPointLon());
+                        destination.setLatitude(xpPoint1.getPointLat());
+                        OrderRouteAndFareDto dto1 = new OrderRouteAndFareDto();
+                        dto1.setOrigin(origin);
+                        dto1.setDestination(destination);
+                        dto1.setRouteType(3);
+                        R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto1);
+                        if (200 != routeVoR.getCode()) {
+                            continue;
+                        }
+                        RouteVo routeVo = routeVoR.getData();
+                        redisService.setCacheObject("CRUISE_ROUTE:" + xpCruiseOrder.getVehicleId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
+                        ROUTE_FLAG = true;
+                        break;
+                    }
+                }
+            }else{
+                for (int i = pointList.getData().size() - 1; i >= 0; i--) {
+                    XpCruisePlanPoint xpCruisePlanPoint1 = pointList.getData().get(i);
+                    if(start || xpCruisePlanPoint1.getPointId().equals(xpCruiseOrder.getEndPointId())){
+                        start = true;
+                        origin.setLongitude(xpCruiseOrder.getStartLon());
+                        origin.setLatitude(xpCruiseOrder.getStartLat());
+                        XpPoint xpPoint1 = xpPointClient.queryById(xpCruisePlanPoint1.getPointId()).getData();
+                        destination.setLongitude(xpPoint1.getPointLon());
+                        destination.setLatitude(xpPoint1.getPointLat());
+                        OrderRouteAndFareDto dto1 = new OrderRouteAndFareDto();
+                        dto1.setOrigin(origin);
+                        dto1.setDestination(destination);
+                        dto1.setRouteType(3);
+                        R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto1);
+                        if (200 != routeVoR.getCode()) {
+                            continue;
+                        }
+                        RouteVo routeVo = routeVoR.getData();
+                        redisService.setCacheObject("CRUISE_ROUTE:" + xpCruiseOrder.getVehicleId(), com.alibaba.fastjson.JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
+                        ROUTE_FLAG = true;
+                        break;
+                    }
+                }
+            }
+            if(!ROUTE_FLAG){
+                log.info("巡游计划获取导航信息失败 {}", JSON.toJSONString(vehicle));
+                return;
             }
         }
 
@@ -3502,7 +3702,7 @@
 //            creditOrderCreateDto.setBusinessOrderId(OrderCodeUtil.getOrderCode("MMZF"));
 //            creditOrderCreateDto.setSubject("小鹏集团|robotaxi");
 //            creditOrderCreateDto.setPayType("13");
-              // TODO 需要根据环境补充路径
+        // TODO 需要根据环境补充路径
 //            creditOrderCreateDto.setPayCallbackUrl("");
 //
 //            creditOrderCreateDto.setBusinessExtendData("{\"mainOrderId\":\"" +order.getOrderNumber() + "\"}");
@@ -3604,6 +3804,7 @@
         if (insert <= 0) {
             return false;
         }
+//        pushOrderCreateToMinistry(xpOrder, "新增订单");
         return true;
     }
 
@@ -3876,7 +4077,9 @@
                 // Redis弹出这个队列元素
                 // value 订单Id_经纬度_状态_用户id_订单编号_距离_时间
                 try {
-                    redisService.popFirstElement(order.getQueueName());
+                    if(StringUtils.isNotEmpty(order.getQueueName())){
+                        redisService.removeByPattern(order.getQueueName(), order.getOrderNumber());
+                    }
                 } catch (Exception e) {
                     log.error("Redis弹出队列元素出错");
                 }
@@ -3895,6 +4098,9 @@
                 this.updateById(order);
                 order.setAppUserId(appUserId);
                 bootCommonService.setCache_orderStatus(order.getId(), order, null);
+                if (vehicle != null) {
+//                    pushOrderMatchToMinistry(order, vehicle, appUserId, order.getAcceptanceTime(), "推单成功");
+                }
 
                 //构建推送消息
                 Map<String, Object> params = new HashMap<>();
@@ -4550,6 +4756,8 @@
         if (xpOrder.getStatus() >= 8) {
             return R.fail("订单已结束,无法修改");
         }
+        XpVehicle matchedVehicle = null;
+        LocalDateTime distributeTime = null;
 
         switch (vo.getOrderStatus()) {
             case 2:
@@ -4566,13 +4774,17 @@
                 if (null == xpVehicle) {
                     return R.fail("车牌号不存在");
                 }
+                matchedVehicle = xpVehicle;
                 xpOrder.setOfficialPartnerId(officialPartnerId);
                 xpOrder.setVehicleId(xpVehicle.getId());
                 xpOrder.setAcceptanceTime(vo.getAcceptanceTime());
+                distributeTime = vo.getAcceptanceTime();
                 redisService.setCacheObject("ORDER_STATUS:" + xpOrder.getId(), OrderStatusEnum.READY_DEPART.getCode(), 24L, TimeUnit.HOURS);
                 //将订单弹出队列
                 try {
-                    redisService.popFirstElement(xpOrder.getQueueName());
+                    if(StringUtils.isNotEmpty(xpOrder.getQueueName())){
+                        redisService.removeByPattern(xpOrder.getQueueName(), xpOrder.getOrderNumber());
+                    }
                 } catch (Exception e) {
                     log.error("Redis弹出队列元素出错");
                 }
@@ -4856,6 +5068,9 @@
         }
         xpOrder.setStatus(vo.getOrderStatus());
         this.updateById(xpOrder);
+        if (vo.getOrderStatus() == 2 && matchedVehicle != null) {
+//            pushOrderMatchToMinistry(xpOrder, matchedVehicle, xpOrder.getAppUserId(), distributeTime, "合作商接单成功");
+        }
         //推送订单状态给乘客端
         Map<String, Object> params = new HashMap<>();
         Map<String, Object> content = new HashMap<>();
@@ -4891,6 +5106,185 @@
 
 
         return R.ok();
+    }
+
+    private void pushOrderCreateToMinistry(XpOrder order, String scene) {
+        if (order == null) {
+            return;
+        }
+        try {
+            RegulationOrderCreateInfoDTO dto = buildOrderCreateInfoForMinistry(order);
+            String response = ministryOfTransportOrderReporter.pushOrderCreateInfo(dto);
+            log.info("{}后上报交通部DDFQ完成, orderId={}, orderNo={}, response={}",
+                    scene, order.getId(), order.getOrderNumber(), response);
+        } catch (Exception e) {
+            log.error("{}后上报交通部DDFQ失败, orderId={}, orderNo={}",
+                    scene, order.getId(), order.getOrderNumber(), e);
+        }
+    }
+
+    private void pushOrderMatchToMinistry(XpOrder order, XpVehicle vehicle, Long appUserId, LocalDateTime distributeTime, String scene) {
+        if (order == null || vehicle == null) {
+            return;
+        }
+        try {
+            RegulationOrderMatchInfoDTO dto = buildOrderMatchInfoForMinistry(order, vehicle, appUserId, distributeTime);
+            String response = ministryOfTransportOrderReporter.pushOrderMatchInfo(dto);
+            log.info("{}后上报交通部DDCG完成, orderId={}, orderNo={}, vehicleId={}, response={}",
+                    scene, order.getId(), order.getOrderNumber(), vehicle.getId(), response);
+        } catch (Exception e) {
+            log.error("{}后上报交通部DDCG失败, orderId={}, orderNo={}, vehicleId={}",
+                    scene, order.getId(), order.getOrderNumber(), vehicle.getId(), e);
+        }
+    }
+
+    private RegulationOrderCreateInfoDTO buildOrderCreateInfoForMinistry(XpOrder order) {
+        XpAppUser appUser = queryAppUser(order.getAppUserId());
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime orderTime = defaultIfNull(order.getCreateTime(), now);
+        LocalDateTime departTime = order.getEstimatedTime() != null
+                ? order.getEstimatedTime()
+                : defaultIfNull(order.getRideTime(), orderTime);
+
+        RegulationOrderCreateInfoDTO dto = new RegulationOrderCreateInfoDTO();
+        dto.setCompanyId(ministryTransportProperties.getCompanyId());
+        dto.setAddress(ministryTransportProperties.getAddressCode());
+        dto.setOrderId(defaultIfBlank(order.getOrderNumber(), String.valueOf(order.getId())));
+        dto.setDepartTime(formatTransportTime(departTime));
+        dto.setOrderTime(formatTransportTime(orderTime));
+        dto.setPassengerPhone(appUser == null ? "" : defaultIfBlank(appUser.getPhoneNumber(), ""));
+        dto.setPassengerNote("");
+        dto.setDeparture(defaultIfBlank(order.getStartAddress(), ""));
+        dto.setDepLongitude(formatCoordinate(order.getStartLon()));
+        dto.setDepLatitude(formatCoordinate(order.getStartLat()));
+        dto.setDestination(defaultIfBlank(order.getEndAddress(), ""));
+        dto.setDestLongitude(formatCoordinate(order.getEndLon()));
+        dto.setDestLatitude(formatCoordinate(order.getEndLat()));
+        dto.setEncrypt("1");
+        dto.setFareType(ministryTransportProperties.getFareType());
+        dto.setOrderSource("0");
+        dto.setPsgName(appUser == null ? "乘客" : defaultIfBlank(appUser.getNickName(), "乘客"));
+        dto.setPsgGender(mapPassengerGender(appUser == null ? null : appUser.getGender()));
+        dto.setPsgTotal("1");
+        dto.setIsReserve(order.getEstimatedTime() != null ? "1" : "0");
+        dto.setPreMile(formatDecimal(order.getMileageKilometers(), 0));
+        dto.setPreTime(formatDecimal(order.getDuration(), 0));
+        dto.setPreFare(formatAmount(order.getOrderMoney()));
+        dto.setDepartCity(defaultIfBlank(order.getCityCode(), ministryTransportProperties.getDepartCityDefault()));
+        dto.setDestCity(defaultIfBlank(order.getCityCode(), ministryTransportProperties.getDestCityDefault()));
+        dto.setIsFromThirdPlatform("0");
+        dto.setProtocolVersion(ministryTransportProperties.getProtocolVersion());
+        return dto;
+    }
+
+    private RegulationOrderMatchInfoDTO buildOrderMatchInfoForMinistry(XpOrder order, XpVehicle vehicle, Long appUserId, LocalDateTime distributeTime) {
+        String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehicle.getVehicleVin());
+        VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class);
+        GeoJsonPoint point = vehiclePosition == null ? null : vehiclePosition.getPoint();
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime orderTime = defaultIfNull(order.getCreateTime(), now);
+        LocalDateTime actualDistributeTime = defaultIfNull(distributeTime, defaultIfNull(order.getAcceptanceTime(), now));
+
+        RegulationOrderMatchInfoDTO dto = new RegulationOrderMatchInfoDTO();
+        dto.setCompanyId(ministryTransportProperties.getCompanyId());
+        dto.setAddress(ministryTransportProperties.getAddressCode());
+        dto.setOrderId(defaultIfBlank(order.getOrderNumber(), String.valueOf(order.getId())));
+        dto.setLongitude(formatCoordinate(point == null ? order.getStartLon() : point.getX()));
+        dto.setLatitude(formatCoordinate(point == null ? order.getStartLat() : point.getY()));
+        dto.setEncrypt("1");
+        dto.setLicenseId(ministryTransportProperties.getDriverLicenseId());
+        dto.setDriverPhone(ministryTransportProperties.getDriverPhone());
+        dto.setVehicleNo(defaultIfBlank(vehicle.getPlateNumber(), ""));
+        dto.setPlateColor(getPlateColor(vehicle.getPlateNumber()));
+        dto.setDistributeTime(formatTransportTime(actualDistributeTime));
+        dto.setOrderTime(formatTransportTime(orderTime));
+        dto.setCarCertNo(ministryTransportProperties.getVehicleCertNo());
+        dto.setDriverName(ministryTransportProperties.getDriverName());
+        dto.setIdNo(ministryTransportProperties.getDriverIdNo());
+        dto.setDriCertNo(ministryTransportProperties.getDriverCertNo());
+        dto.setDepartCity(defaultIfBlank(order.getCityCode(), ministryTransportProperties.getDepartCityDefault()));
+        dto.setDestCity(defaultIfBlank(order.getCityCode(), ministryTransportProperties.getDestCityDefault()));
+        dto.setDepartLocale(defaultIfBlank(order.getStartAddress(), ""));
+        dto.setDepartLocaleDetail(defaultIfBlank(order.getStartAddress(), ""));
+        dto.setDepartLon(formatCoordinate(order.getStartLon()));
+        dto.setDepartLat(formatCoordinate(order.getStartLat()));
+        dto.setDesLocale(defaultIfBlank(order.getEndAddress(), ""));
+        dto.setDesLocaleDetail(defaultIfBlank(order.getEndAddress(), ""));
+        dto.setDesLon(formatCoordinate(order.getEndLon()));
+        dto.setDesLat(formatCoordinate(order.getEndLat()));
+        dto.setLatestDestTime(formatTransportTime(actualDistributeTime.minusMinutes(30)));
+        dto.setIsFromThirdPlatform("0");
+        dto.setProtocolVersion(ministryTransportProperties.getProtocolVersion());
+        return dto;
+    }
+
+    private XpAppUser queryAppUser(Long appUserId) {
+        if (appUserId == null) {
+            return null;
+        }
+        try {
+            R<XpAppUser> result = xpAppUserClient.queryOperationsUserById(appUserId);
+            return result == null ? null : result.getData();
+        } catch (Exception e) {
+            log.warn("查询乘客信息失败, appUserId={}", appUserId, e);
+            return null;
+        }
+    }
+
+    private LocalDateTime defaultIfNull(LocalDateTime value, LocalDateTime defaultValue) {
+        return value == null ? defaultValue : value;
+    }
+
+    private String defaultIfBlank(String value, String defaultValue) {
+        return StringUtils.isBlank(value) ? defaultValue : value;
+    }
+
+    private String formatTransportTime(LocalDateTime time) {
+        return time == null ? null : time.format(MinistryOfTransportOrderReporter.DATA_TIME_FORMATTER);
+    }
+
+    private String formatCoordinate(Double value) {
+        if (value == null) {
+            return "0";
+        }
+        return BigDecimal.valueOf(value)
+                .multiply(BigDecimal.valueOf(1_000_000L))
+                .setScale(0, RoundingMode.HALF_UP)
+                .toPlainString();
+    }
+
+    private String formatDecimal(Number value, int scale) {
+        if (value == null) {
+            return "0";
+        }
+        return BigDecimal.valueOf(value.doubleValue())
+                .setScale(scale, RoundingMode.HALF_UP)
+                .toPlainString();
+    }
+
+    private String formatAmount(BigDecimal value) {
+        if (value == null) {
+            return "0";
+        }
+        return value.stripTrailingZeros().toPlainString();
+    }
+
+    private String mapPassengerGender(Integer gender) {
+        if (Integer.valueOf(1).equals(gender)) {
+            return "1";
+        }
+        if (Integer.valueOf(2).equals(gender)) {
+            return "2";
+        }
+        return "0";
+    }
+
+    private String getPlateColor(String plateNumber) {
+        if (StringUtils.isBlank(plateNumber)) {
+            return "蓝色";
+        }
+        String plateWithoutProvince = plateNumber.substring(1);
+        return plateWithoutProvince.length() == 7 ? "渐变绿" : "蓝色";
     }
 
     @Override
@@ -5127,6 +5521,27 @@
         updateById(order);
     }
 
+    @Override
+    public CreditPayCallVo creditPaySuccessCall(CreditPaySuccessCallDto dto) {
+        LambdaQueryWrapper<XpOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(XpOrder::getAuthOrderId, dto.getAuthOrderId());
+        XpOrder order = this.getOne(wrapper.last("LIMIT 1"));
+        if(dto.getPayStatus()==1){
+            order.setStatus(9);
+            order.setAppUserId(null);
+            this.updateById(order);
+            CreditPayCallVo vo = new CreditPayCallVo();
+            vo.setRetCode("0");
+            vo.setRetMsg("成功");
+
+            // 对接财务
+            this.xpFrdXfipEventPush(order,dto.getPayFee(),dto.getOrderId());
+
+            return vo;
+        }
+        return null;
+    }
+
 
     /**
      * 发票列表
@@ -5162,9 +5577,6 @@
 
         ArrayList<XpInvoiceVo> xpInvoiceVoList = new ArrayList<>(list.size());
 
-        R<List<XpVehicle>> r = xpVehicleClient.listByIds(list.stream().map(XpOrder::getVehicleId).collect(Collectors.toList()));
-        List<XpVehicle> vehicleList = r.getData();
-
         // 数据组装
         for (XpOrder xpOrder : list) {
             XpInvoiceVo xpInvoiceVo = new XpInvoiceVo();
@@ -5187,7 +5599,9 @@
             goodsDetail.setItemId(xpOrder.getOrderNumber());
             goodsDetail.setCouponAmount(xpOrder.getCouponMoney());
             goodsDetail.setCompanyCode("8000");
-            xpInvoiceVo.setGoodsDetail(JSON.toJSONString(goodsDetail));
+            JSONArray goodsDetailArray = new JSONArray();
+            goodsDetailArray.add(goodsDetail);
+            xpInvoiceVo.setGoodsDetail(JSON.toJSONString(goodsDetailArray));
 
             xpInvoiceVo.setOrderTotalAmount(xpOrder.getOrderMoney()!=null?xpOrder.getOrderMoney():BigDecimal.ZERO);
             xpInvoiceVo.setOrderBusAmount(xpOrder.getOrderMoney()!=null?xpOrder.getOrderMoney():BigDecimal.ZERO);
@@ -5220,6 +5634,16 @@
             itinerary.setEndPoint(xpOrder.getEndAddress());
             itinerary.setMileage(xpOrder.getMileageKilometers()!=null ? xpOrder.getMileageKilometers().toString() :"0");
 
+            UcUserInfo user = userResourcesClient.getBaseUserByUid(xpOrder.getAppUserId().toString());
+            itinerary.setUserName(user.getNickName());
+            itinerary.setUserAccount(user.getUid().toString());
+            itinerary.setPhone(user.getMobile());
+            itinerary.setPickupTime(xpOrder.getBoardingTime()!=null?xpOrder.getBoardingTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
+            itinerary.setDropOffTime(xpOrder.getTripEnd()!=null?xpOrder.getTripEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
+            itinerary.setOldPrice(xpOrder.getOrderMoney()!=null?xpOrder.getOrderMoney().toString():"0");
+            itinerary.setCurrency("CNY");
+
+
             xpInvoiceVo.setItinerary(itinerary);
             xpInvoiceVoList.add(xpInvoiceVo);
         }
@@ -5246,9 +5670,6 @@
 
         ArrayList<XpInvoiceVo> xpInvoiceVoList = new ArrayList<>(list.size());
 
-        R<List<XpVehicle>> r = xpVehicleClient.listByIds(list.stream().map(XpOrder::getVehicleId).collect(Collectors.toList()));
-        List<XpVehicle> vehicleList = r.getData();
-
         // 数据组装
         for (XpOrder xpOrder : list) {
             XpInvoiceVo xpInvoiceVo = new XpInvoiceVo();
@@ -5271,13 +5692,18 @@
             goodsDetail.setItemId(xpOrder.getOrderNumber());
             goodsDetail.setCouponAmount(xpOrder.getCouponMoney());
             goodsDetail.setCompanyCode("8000");
-            xpInvoiceVo.setGoodsDetail(JSON.toJSONString(goodsDetail));
+            JSONArray goodsDetailArray = new JSONArray();
+            goodsDetailArray.add(goodsDetail);
+            xpInvoiceVo.setGoodsDetail(JSON.toJSONString(goodsDetailArray));
 
-            xpInvoiceVo.setOrderTotalAmount(xpOrder.getPayMoney());
-            xpInvoiceVo.setOrderBusAmount(xpOrder.getOrderMoney());
 
-            xpInvoiceVo.setOrderDiscountAmount(xpOrder.getCouponMoney());
-            xpInvoiceVo.setOrderFinishTime(xpOrder.getTripEnd()!=null?String.valueOf(xpOrder.getTripEnd()):"");
+            xpInvoiceVo.setOrderTotalAmount(xpOrder.getOrderMoney()!=null?xpOrder.getOrderMoney():BigDecimal.ZERO);
+            xpInvoiceVo.setOrderBusAmount(xpOrder.getOrderMoney()!=null?xpOrder.getOrderMoney():BigDecimal.ZERO);
+
+            xpInvoiceVo.setOrderDiscountAmount(xpOrder.getCouponMoney()!=null?xpOrder.getCouponMoney():BigDecimal.ZERO);
+
+            xpInvoiceVo.setOrderFinishTime(xpOrder.getTripEnd()!=null?xpOrder.getTripEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
+
 
 
             JSONObject extData = new JSONObject();
@@ -5302,6 +5728,16 @@
             itinerary.setStartPoint(xpOrder.getStartAddress());
             itinerary.setEndPoint(xpOrder.getEndAddress());
             itinerary.setMileage(xpOrder.getMileageKilometers()!=null ? xpOrder.getMileageKilometers().toString() :"0");
+            UcUserInfo user = userResourcesClient.getBaseUserByUid(xpOrder.getAppUserId().toString());
+            itinerary.setUserName(user.getNickName());
+            itinerary.setUserAccount(user.getUid().toString());
+            itinerary.setPhone(user.getMobile());
+            itinerary.setPickupTime(xpOrder.getBoardingTime()!=null?xpOrder.getBoardingTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
+            itinerary.setDropOffTime(xpOrder.getTripEnd()!=null?xpOrder.getTripEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):"");
+            itinerary.setOldPrice(xpOrder.getOrderMoney()!=null?xpOrder.getOrderMoney().toString():"0");
+            itinerary.setCurrency("CNY");
+
+
 
             xpInvoiceVo.setItinerary(itinerary);
             xpInvoiceVoList.add(xpInvoiceVo);

--
Gitblit v1.7.1