From b7bb5daa5f4ffe1764a363a051a5d6f868168cf9 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期一, 11 五月 2026 20:56:31 +0800
Subject: [PATCH] Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.1

---
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java |  215 +++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 172 insertions(+), 43 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 c708ebd..2d622ec 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
@@ -3,6 +3,7 @@
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.util.DesensitizedUtil;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
@@ -51,6 +52,7 @@
 import com.xiaopeng.api.query.order.XpOrderInvoiceQuery;
 import com.xiaopeng.api.vo.OrderType;
 import com.xiaopeng.api.vo.account.CalculateDiscountAmountVo;
+import com.xiaopeng.api.vo.account.LoginUser;
 import com.xiaopeng.api.vo.account.UserCouponVo;
 import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
 import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType;
@@ -61,6 +63,7 @@
 import com.xiaopeng.api.vo.order.*;
 import com.xiaopeng.api.vo.payFront.CreditOrderCreateVo;
 import com.xiaopeng.api.vo.payFront.CreditPaySignQueryVo;
+import com.xiaopeng.api.vo.order.FareBreakdownVo;
 import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo;
 import com.xiaopeng.api.vo.vehicleConvoy.BluetoothDeliverVo;
 import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo;
@@ -78,6 +81,7 @@
 import com.xiaopeng.common.core.web.domain.BaseModel;
 import com.xiaopeng.common.core.web.page.PageInfo;
 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.constant.I18nKeyConstant;
 import com.xiaopeng.order.dto.MileageDto;
@@ -85,7 +89,7 @@
 import com.xiaopeng.order.job.base.QuartzManager;
 import com.xiaopeng.order.job.base.TimeJobType;
 import com.xiaopeng.order.job.jobs.*;
-import com.xiaopeng.order.mangodb.model.OrderTrajectory;
+import com.xiaopeng.api.model.order.OrderTrajectory;
 import com.xiaopeng.order.mangodb.service.OrderTrajectoryService;
 import com.xiaopeng.order.mapper.XpCruiseOrderMapper;
 import com.xiaopeng.order.mapper.XpOrderDetailMapper;
@@ -99,10 +103,7 @@
 import com.xiaopeng.order.service.*;
 import com.xiaopeng.order.utils.*;
 import com.xiaopeng.order.utils.holiday.HolidayUtil;
-import com.xiaopeng.order.vo.OrderDetailVo;
-import com.xiaopeng.order.vo.OrderInfoVo;
-import com.xiaopeng.order.vo.UpdateOrderStatusVo;
-import com.xiaopeng.order.vo.UserOrderListVo;
+import com.xiaopeng.order.vo.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
@@ -202,6 +203,9 @@
 
     @Resource
     private OfficialPartnerUtil officialPartnerUtil;
+
+    @Resource
+    private TokenService tokenService;
 
     @Resource
     private XpPayFrontClient xpPayFrontClient;
@@ -636,6 +640,7 @@
                                           Map<Long, XpFleet> fleetMap,
                                           BigDecimal orderMoney,
                                           BigDecimal couponMoney) {
+        LoginUser loginUser = tokenService.getLoginUser();
         XpOrderPageVO vo = new XpOrderPageVO();
         vo.setId(order.getId());
         vo.setOrderNumber(order.getOrderNumber());
@@ -655,7 +660,10 @@
         if (Objects.nonNull(order.getAppUserId()) && userInfoMap != null && userInfoMap.containsKey(order.getAppUserId().toString())) {
             UcUserInfo userInfo = userInfoMap.get(order.getAppUserId().toString());
             vo.setNickName(userInfo.getNickName());
-            vo.setPhoneNumber(sysGroupMenuClient.getPhoneDesensitization(userInfo.getMobile()).getData());
+            if(!loginUser.getPhoneDesensitizationExempt()){
+                vo.setPhoneNumber(DesensitizedUtil.mobilePhone(userInfo.getMobile()));
+            }
+
         }
 
         // 车辆信息
@@ -1190,6 +1198,8 @@
             pushOrderDto.setEndTaskId(order.getXpuEndTaskId());
             pushOrderDto.setVin(newVehicle.getVehicleVin());
             pushOrderDto.setOrderId(order.getId().toString());
+            pushOrderDto.setStartWaypointId(order.getStartPointId());
+            pushOrderDto.setEndWaypointId(order.getEndPointId());
             pushOrderDto.setStartLatitude(order.getStartLat());
             pushOrderDto.setStartLongitude(order.getStartLon());
             pushOrderDto.setEndLatitude(order.getEndLat());
@@ -1325,6 +1335,8 @@
             pushOrderDto.setEndTaskId(returnOrder.getXpuTaskId());
             pushOrderDto.setVin(oldVehicle.getVehicleVin());
             pushOrderDto.setOrderId("XU" + returnOrder.getId());
+            pushOrderDto.setStartWaypointId(returnOrder.getStartPointId());
+            pushOrderDto.setEndWaypointId(returnOrder.getEndPointId());
             pushOrderDto.setStartLatitude(returnOrder.getStartLat());
             pushOrderDto.setStartLongitude(returnOrder.getStartLon());
             pushOrderDto.setEndLatitude(returnOrder.getEndLat());
@@ -1668,10 +1680,19 @@
                     }
             );
         }
-        data = data.stream().sorted(Comparator.comparingInt(XpHistoryStartPointsVo::getNum).reversed()).collect(Collectors.toList());
 
-        return data;
-
+        List<XpHistoryStartPointsVo> objects = new ArrayList<XpHistoryStartPointsVo>();
+        if(!data.isEmpty()){
+            //收藏的数据
+            List<XpHistoryStartPointsVo> collect = data.stream().filter(s -> s.getIsCollect() == 1)
+                    .sorted(Comparator.comparing(XpHistoryStartPointsVo::getDistance)).collect(Collectors.toList());
+            objects.addAll(collect);
+            //非收藏的数据
+            List<XpHistoryStartPointsVo> collect1 = data.stream().filter(s -> s.getIsCollect() == 2)
+                    .sorted(Comparator.comparing(XpHistoryStartPointsVo::getDistance)).collect(Collectors.toList());
+            objects.addAll(collect1);
+        }
+        return objects;
     }
 
     @Override
@@ -1699,9 +1720,18 @@
                     }
             );
         }
-        data = data.stream().sorted(Comparator.comparingInt(XpHistoryEndPointsVo::getNum).reversed()).collect(Collectors.toList());
-
-        return data;
+        List<XpHistoryEndPointsVo> objects = new ArrayList<XpHistoryEndPointsVo>();
+        if(!data.isEmpty()){
+            //收藏的数据
+            List<XpHistoryEndPointsVo> collect = data.stream().filter(s -> s.getIsCollect() == 1)
+                    .sorted(Comparator.comparing(XpHistoryEndPointsVo::getDistance)).collect(Collectors.toList());
+            objects.addAll(collect);
+            //非收藏的数据
+            List<XpHistoryEndPointsVo> collect1 = data.stream().filter(s -> s.getIsCollect() == 2)
+                    .sorted(Comparator.comparing(XpHistoryEndPointsVo::getDistance)).collect(Collectors.toList());
+            objects.addAll(collect1);
+        }
+        return objects;
 
     }
 
@@ -2404,7 +2434,68 @@
                 totalPrice = totalPrice.add(xpOrderDetail1.getMoney());
                 xpOrderDetailMapper.insert(xpOrderDetail1);
             }
-            order.setOrderMoney(totalPrice);
+
+            // 默认费率1
+            double priceRate = 1;
+            if (pricing.getIsDynamicPrice() == 1) {
+                // 先判断是否已经调价过了
+                Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid);
+                if (userDynamicPriceObj != null) {
+                    // 是否调价过了
+                    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();
+                            }
+
+                            // 天气预报动态调价
+                            JSONArray ws = jsonObject.getJSONArray("weather");
+                            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"))) {
+                                            double floatRate = jsonObject.getDouble("ratio");
+                                            priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+
+
+                            // 冷却时间
+                            Integer time = getOrderNum(jsonObject, 6);
+                            // 触发调价了
+                            redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
+                        }
+                    }
+                }
+            }
+
+            order.setOrderMoney(totalPrice.multiply(new BigDecimal(priceRate)));
             order.setAppUserId(null);
             baseMapper.updateById(order);
         } else {
@@ -2523,7 +2614,6 @@
                         }
                     }
                 }
-
             }
             // 封装费用明细数据
             for (Map.Entry<String, BigDecimal> stringBigDecimalEntry : bill.entrySet()) {
@@ -2832,6 +2922,8 @@
         pushOrderDto.setEndTaskId(xpCruiseOrder.getXpuTaskId());
         pushOrderDto.setVin(xpCruiseOrder.getVehicleVin());
         pushOrderDto.setOrderId("XU" + xpCruiseOrder.getId());
+        pushOrderDto.setStartWaypointId(xpCruiseOrder.getStartPointId());
+        pushOrderDto.setEndWaypointId(xpCruiseOrder.getEndPointId());
         pushOrderDto.setStartLatitude(xpCruiseOrder.getStartLat());
         pushOrderDto.setStartLongitude(xpCruiseOrder.getStartLon());
         pushOrderDto.setEndLatitude(xpCruiseOrder.getEndLat());
@@ -2839,7 +2931,7 @@
         pushOrderDto.setOrderType(OrderType.CRUISE_ORDER);
         pushOrderDto.setStage(2);
         pushOrderDto.setLastOrderId(order.getId() + "");
-        pushOrderDto.setLastOrderId(order.getXpuEndTaskId());
+        pushOrderDto.setLastXpuTaskId(order.getXpuEndTaskId());
         pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
         orderMissionClient.pushOrder(pushOrderDto);
         log.info("下发XUP巡游订单报文成功");
@@ -2952,6 +3044,8 @@
         pushOrderDto.setEndTaskId(xpCruiseOrder.getXpuTaskId());
         pushOrderDto.setVin(xpCruiseOrder.getVehicleVin());
         pushOrderDto.setOrderId("XU" + xpCruiseOrder.getId());
+        pushOrderDto.setStartWaypointId(xpCruiseOrder.getStartPointId());
+        pushOrderDto.setEndWaypointId(xpCruiseOrder.getEndPointId());
         pushOrderDto.setStartLatitude(xpCruiseOrder.getStartLat());
         pushOrderDto.setStartLongitude(xpCruiseOrder.getStartLon());
         pushOrderDto.setEndLatitude(xpCruiseOrder.getEndLat());
@@ -3613,6 +3707,7 @@
                 addTaxiPassengerVo.setUid(appUserId.toString());
                 order.setAppUserId(null);
                 this.updateById(order);
+                order.setAppUserId(appUserId);
                 bootCommonService.setCache_orderStatus(order.getId(), order, null);
 
                 //构建推送消息
@@ -3654,19 +3749,18 @@
 
                 //生成前往上车点的导航数据
                 //查询车辆位置
-                //TODO 本地环境默认写死
-                // VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(dto.getXpVehicleVin())), VehiclePosition.class);
-                // if (Objects.isNull(vehiclePosition)) {
-                //     throw new RuntimeException("车辆位置信息不存在");
-                // }
+                 VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(dto.getXpVehicleVin())), VehiclePosition.class);
+                 if (Objects.isNull(vehiclePosition)) {
+                     throw new RuntimeException("车辆位置信息不存在");
+                 }
 
                 LonLatDto destination = new LonLatDto();
                 LonLatDto origin = new LonLatDto();
                 //查询司机当前位置到起点的线路
-                // origin.setLongitude(vehiclePosition.getPoint().getX());
-                // origin.setLatitude(vehiclePosition.getPoint().getY());
-                origin.setLongitude(104.055499);
-                origin.setLatitude(30.586747);
+                 origin.setLongitude(vehiclePosition.getPoint().getX());
+                 origin.setLatitude(vehiclePosition.getPoint().getY());
+//                origin.setLongitude(104.055499);
+//                origin.setLatitude(30.586747);
                 destination.setLongitude(order.getStartLon());
                 destination.setLatitude(order.getStartLat());
 
@@ -3697,25 +3791,25 @@
                         .plusMinutes(routeVo1.getDuration()).plusMinutes(endPoint.getParkingTimeLimit()).plusMinutes(30);
                 long expirationTime = localDateTime.toEpochSecond(ZoneOffset.of("+8"));
                 //生成token
-//                String token = bluetoothUnlockTokenUtil.generateBluetoothUnlockToken(order.getAppUserId(),
-//                        order.getId(), order.getVehicleId(), expirationTime);
-//                log.info("生成蓝牙token:{} 有效期:{} 订单号: {}", token, expirationTime, order.getOrderNumber());
-//                //存储缓存
-//                JSONObject jsonObject = new JSONObject();
-//                jsonObject.put("userId", order.getAppUserId());
-//                jsonObject.put("orderId", order.getId());
-//                jsonObject.put("vehicleId", order.getVehicleId());
-//                jsonObject.put("expirationTime", expirationTime);
-//                jsonObject.put("orderNumber", order.getOrderNumber());
-//                jsonObject.put("vehicleVin", vehicle.getVehicleVin());
-//                jsonObject.put("createTime", System.currentTimeMillis());
-//                redisService.setCacheObject("rt:bluetooth:unlock:" + token, jsonObject.toJSONString(), expirationTime, TimeUnit.SECONDS);
-//                redisService.setCacheObject("rt:bluetooth:unlock:order:" + order.getId(), token, expirationTime, TimeUnit.SECONDS);
-//                //开始下发蓝牙token
-//                BluetoothDeliverVo vo = new BluetoothDeliverVo();
-//                vo.setCredential(token);
-//                vo.setVim(vehicle.getVehicleVin());
-//                vo.setPassengerUid(order.getAppUserId());
+                String token = bluetoothUnlockTokenUtil.generateBluetoothUnlockToken(order.getAppUserId(),
+                        order.getId(), order.getVehicleId(), expirationTime);
+                log.info("生成蓝牙token:{} 有效期:{} 订单号: {}", token, expirationTime, order.getOrderNumber());
+                //存储缓存
+                JSONObject jsonObject = new JSONObject();
+                jsonObject.put("userId", order.getAppUserId());
+                jsonObject.put("orderId", order.getId());
+                jsonObject.put("vehicleId", order.getVehicleId());
+                jsonObject.put("expirationTime", expirationTime);
+                jsonObject.put("orderNumber", order.getOrderNumber());
+                jsonObject.put("vehicleVin", vehicle.getVehicleVin());
+                jsonObject.put("createTime", System.currentTimeMillis());
+                redisService.setCacheObject("rt:bluetooth:unlock:" + token, jsonObject.toJSONString(), expirationTime, TimeUnit.SECONDS);
+                redisService.setCacheObject("rt:bluetooth:unlock:order:" + order.getId(), token, expirationTime, TimeUnit.SECONDS);
+                //开始下发蓝牙token
+                BluetoothDeliverVo vo = new BluetoothDeliverVo();
+                vo.setCredential(token);
+                vo.setVim(vehicle.getVehicleVin());
+                vo.setPassengerUid(order.getAppUserId());
 //                BaseVehicleUserDto deliver = bluetoothUnlockClient.deliver(vo);
 //                if(null == deliver){
 //                    throw new ServiceException("下发蓝牙token失败");
@@ -4555,6 +4649,41 @@
         return R.ok();
     }
 
+    @Override
+    public UserOrderInfoVo getOrderHistoryInfo(Long orderId) {
+        XpOrder xpOrder = this.getById(orderId);
+        UserOrderInfoVo vo = new UserOrderInfoVo();
+        vo.setOrderId(xpOrder.getId());
+        vo.setOrderCreatedAt(xpOrder.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        vo.setDispatchStartAt("");
+        vo.setDispatchSuccessAt(null == xpOrder.getAcceptanceTime() ? "" : xpOrder.getAcceptanceTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        vo.setVehicleArrivedAt(null == xpOrder.getArrivalTime() ? "" : xpOrder.getArrivalTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        vo.setFreeWaitExpiredAt("");
+        vo.setVehicleUnlockedAt("");
+        vo.setDoorOpenedAt(Arrays.asList(""));
+        vo.setDoorClosedAt(Arrays.asList(""));
+        vo.setTripConfirmedAt(null == xpOrder.getTripBegin() ? "" : xpOrder.getTripBegin().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        vo.setSafetybeltUnlockedAt(Arrays.asList(""));
+        vo.setArrivedDestinationAt("");
+        vo.setDropoffDoorOpenedAt(Arrays.asList(""));
+        vo.setDropoffTrunkOpenedAt(Arrays.asList(""));
+        vo.setDropoffDoorClosedAt(Arrays.asList(""));
+        vo.setTripEndedAt(null == xpOrder.getTripEnd() ? "" : xpOrder.getTripEnd().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        vo.setPaymentCompletedAt("");
+        XpOrderEvaluate orderEvaluate = xpOrderEvaluateService.getOne(new QueryWrapper<XpOrderEvaluate>().eq("order_id", xpOrder.getId()));
+        if(null != orderEvaluate){
+            vo.setUserRatedAt(orderEvaluate.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        }
+        XpOrderCancel xpOrderCancel = xpOrderCancelService.getOne(new QueryWrapper<XpOrderCancel>().eq("order_id", xpOrder.getId()));
+        if(null != xpOrderCancel){
+            vo.setOrderCancelledAt(xpOrderCancel.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            vo.setCancelReasonType(xpOrderCancel.getCancelSource() == 1 ? "用户取消" : xpOrderCancel.getCancelSource() == 4 ? "超时取消" : "系统取消");
+        }
+        vo.setSafetyAlertTriggeredAt("");
+        vo.setRemoteTakeoverAt("");
+        return vo;
+    }
+
 
     /**
      * 发票列表

--
Gitblit v1.7.1