liujie
2026-05-12 560be817c1342d4da523760ba38433c4c0f52983
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.payFront.CreditPrecreateVo;
import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo;
import com.xiaopeng.api.vo.vehicleConvoy.BluetoothDeliverVo;
@@ -79,6 +82,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;
@@ -86,7 +90,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;
@@ -100,10 +104,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;
@@ -203,6 +204,9 @@
    @Resource
    private OfficialPartnerUtil officialPartnerUtil;
    @Resource
    private TokenService tokenService;
    @Resource
    private XpPayFrontClient xpPayFrontClient;
@@ -637,6 +641,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());
@@ -656,7 +661,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()));
            }
        }
        // 车辆信息
@@ -1191,6 +1199,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());
@@ -1326,6 +1336,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());
@@ -1669,10 +1681,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
@@ -1700,9 +1721,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;
    }
@@ -2405,7 +2435,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 {
@@ -2524,7 +2615,6 @@
                        }
                    }
                }
            }
            // 封装费用明细数据
            for (Map.Entry<String, BigDecimal> stringBigDecimalEntry : bill.entrySet()) {
@@ -2833,6 +2923,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());
@@ -2840,7 +2932,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巡游订单报文成功");
@@ -2953,6 +3045,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());
@@ -3229,16 +3323,13 @@
    @Override
    public R payment(XpOrderPayDto dto, String uid) {
        HashMap<String, Object> resultMap = new HashMap<>();
        // 1.0 免密  //查询是否开通免密
        // 1先查用户是否申请  申请了拿到通过的businessOrderId
        boolean signed = false;
        CreditPaySignQueryDto creditPaySignQueryDto = new CreditPaySignQueryDto();
        creditPaySignQueryDto.setUid(Long.valueOf(uid));
        creditPaySignQueryDto.setBusinessId("xp-robotaxi");
        creditPaySignQueryDto.setCategory("009001");
        creditPaySignQueryDto.setBusinessId(appid);
        creditPaySignQueryDto.setCategory("xp_robotaxi_api");
        creditPaySignQueryDto.setBusinessOrderId("");
        R<CreditPaySignQueryVo> creditPaySignQueryVoR = xpPayFrontClient.queryCreditPaySign(creditPaySignQueryDto);
        if (creditPaySignQueryVoR.getCode()==200) {
@@ -3255,10 +3346,10 @@
            // y已签约 1.信用下单
            CreditOrderCreateDto creditOrderCreateDto = new CreditOrderCreateDto();
            creditOrderCreateDto.setUid(Long.valueOf(uid));
            creditOrderCreateDto.setBusinessId("xp-robotaxi");
            creditOrderCreateDto.setBusinessId(appid);
            creditOrderCreateDto.setCategory("xp_robotaxi_api");
            creditOrderCreateDto.setBusinessOrderId("");
            creditOrderCreateDto.setSubject("009001");
            creditOrderCreateDto.setSubject("信用下单");
            creditOrderCreateDto.setPayType("13");
@@ -3272,9 +3363,7 @@
            R<CreditOrderCreateVo> creditOrderCreateVoR = xpPayFrontClient.createCreditOrder(creditOrderCreateDto);
            if(creditOrderCreateVoR.getCode()==200){
                CreditOrderCreateVo data = creditOrderCreateVoR.getData();
                resultMap.put("status", 1);
                resultMap.put("value", data);
                return R.ok(resultMap);
                return R.ok(data.getPackageValue());
            }
        }else {
@@ -3284,26 +3373,14 @@
            XpOrder order = this.getById(dto.getOrderId());
            CreditPrecreateDto creditPrecreateDto = new CreditPrecreateDto();
            creditPrecreateDto.setUid(uid);
            creditPrecreateDto.setBizId("xp-robotaxi");
            creditPrecreateDto.setBizId(appid);
            creditPrecreateDto.setBizOrderId("");
            creditPrecreateDto.setPayScene(99);
            creditPrecreateDto.setAmount(order.getOrderMoney().multiply(new BigDecimal(100)).intValue());
            creditPrecreateDto.setCategory("009001");
            creditPrecreateDto.setCategory("信用下单");
            creditPrecreateDto.setTitle("信用下单");
            creditPrecreateDto.setDetail("信用下单");
            HashMap<String, String> businessExtend = new HashMap<>();
            businessExtend.put("returnUrl", "");
            businessExtend.put("notifyUrl", "");
            creditPrecreateDto.setBusinessExtend(businessExtend);
            R<CreditPrecreateVo> creditPrecreateVoR = xpPayFrontClient.precreate(creditPrecreateDto);
            if (creditPrecreateVoR.getCode()==200) {
                CreditPrecreateVo data = creditPrecreateVoR.getData();
                resultMap.put("status", 2);
                resultMap.put("value", data);
                return R.ok(resultMap);
            }
        }
@@ -3631,6 +3708,7 @@
                addTaxiPassengerVo.setUid(appUserId.toString());
                order.setAppUserId(null);
                this.updateById(order);
                order.setAppUserId(appUserId);
                bootCommonService.setCache_orderStatus(order.getId(), order, null);
                //构建推送消息
@@ -3672,19 +3750,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());
@@ -3715,25 +3792,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失败");
@@ -4573,6 +4650,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;
    }
    /**
     * 发票列表