liujie
2026-06-09 c96fbe6b0aeb413a17c429133ee6d81d138144b9
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpCruisePlanController.java
@@ -1,9 +1,58 @@
package com.xiaopeng.operation.controller;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
import com.xiaopeng.api.dto.operation.CruisePointDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.operation.NewCruiseOrderDto;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.model.order.XpCruiseOrder;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.log.annotation.AdminOperationLog;
import com.xiaopeng.common.log.enums.AdminBusinessType;
import com.xiaopeng.common.log.enums.AdminOperationType;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.operation.dto.XpCruisePlanAddDTO;
import com.xiaopeng.operation.dto.XpCruisePlanEditDTO;
import com.xiaopeng.operation.query.CruisePlanQuery;
import com.xiaopeng.operation.service.*;
import com.xiaopeng.operation.vo.XpCruisePlanDetailVO;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import io.swagger.annotations.ApiParam;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.xiaopeng.common.log.annotation.AdminOperationLog;
import com.xiaopeng.common.log.enums.AdminBusinessType;
import com.xiaopeng.common.log.enums.AdminOperationType;
/**
 * <p>
@@ -13,7 +62,480 @@
 * @author mitao
 * @since 2026-02-26
 */
@Validated
@RestController
@RequiredArgsConstructor(onConstructor_ = @Lazy)
public class XpCruisePlanController {
    private final IXpCruisePlanService xpCruisePlanService;
    private final IXpCruisePlanVehicleService xpCruisePlanVehicleService;
    private final IXpCruisePlanPointService xpCruisePlanPointService;
    private final XpPointService pointService;
    private final XpVehicleClient xpVehicleClient;
    @Resource
    private XpTargetedServiceVehicleService xpTargetedServiceVehicleService;
    @Resource
    private XpTargetedServiceService xpTargetedServiceService;
    @Resource
    private XpMapClient xpMapClient;
    @Resource
    private RedisService redisService;
    @Resource(name = "hutoolSnowflake")
    private Snowflake snowflake;
    @ApiOperation(value = "获取巡游计划分页列表", tags = {"管理后台-巡游计划"})
    @PostMapping(value = {"/api/v1/xp-cruise-plan/pageList"})
    public R<PageInfo<XpCruisePlan>> getPageList(@RequestBody CruisePlanQuery query) {
        return R.ok(xpCruisePlanService.getPageList(query));
    }
    @ApiOperation(value = "新增巡游计划", tags = {"管理后台-巡游计划"})
    @PostMapping(value = {"/api/v1/xp-cruise-plan/add"})
    @AdminOperationLog(
            businessType = AdminBusinessType.CRUISE_PLAN,
            operationType = AdminOperationType.ADD,
            content = "新增巡游计划",
            appendRequestData = true
    )
    public R<?> add(@Valid @RequestBody XpCruisePlanAddDTO dto) {
        xpCruisePlanService.add(dto);
        return R.ok();
    }
    @ApiOperation(value = "编辑巡游计划", tags = {"管理后台-巡游计划"})
    @PostMapping(value = {"/api/v1/xp-cruise-plan/edit"})
    @AdminOperationLog(
            businessType = AdminBusinessType.CRUISE_PLAN,
            operationType = AdminOperationType.EDIT,
            content = "编辑巡游计划",
            appendRequestData = true
    )
    public R<?> edit(@Valid @RequestBody XpCruisePlanEditDTO dto) {
        xpCruisePlanService.edit(dto);
        return R.ok();
    }
    @ApiOperation(value = "删除巡游计划", tags = {"管理后台-巡游计划"})
    @DeleteMapping(value = {"/api/v1/xp-cruise-plan/deleteById/{id}"})
    @AdminOperationLog(
            businessType = AdminBusinessType.CRUISE_PLAN,
            operationType = AdminOperationType.DELETE,
            contentExpression = "'删除巡游计划,id=' + #p0",
            appendRequestData = false
    )
    public R<?> deleteById(@ApiParam(name = "id", value = "巡游计划ID") @PathVariable Long id) {
        xpCruisePlanService.deleteById(id);
        return R.ok();
    }
    @ApiOperation(value = "巡游计划详情", tags = {"管理后台-巡游计划"})
    @GetMapping(value = {"/api/v1/xp-cruise-plan/detail"})
    public R<XpCruisePlanDetailVO> detail(@ApiParam(name = "id", value = "巡游计划ID") @RequestParam Long id) {
        return R.ok(xpCruisePlanService.detail(id));
    }
    /**
     * 获取车辆下个点位
     * @return
     */
    @PostMapping("/logan/inner/cruise/getCruisePoint")
    public R<XpCruiseOrder> getCruisePoint(@RequestBody CruisePointDto dto) {
        // 先找计划
        XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, dto.getVehicleId()));
        Long cruisePlanId = null;
        if (plan == null) {
            //没有巡游计划,判断是否在定向服务里面
            List<XpTargetedService> targetedServices = xpTargetedServiceService.list(new QueryWrapper<XpTargetedService>().eq("status", 1));
            if(targetedServices.isEmpty()){
                return R.fail("没有巡游计划");
            }
            List<Long> collect1 = targetedServices.stream().map(XpTargetedService::getId).collect(Collectors.toList());
            List<XpTargetedServiceVehicle> list = xpTargetedServiceVehicleService.list(new QueryWrapper<XpTargetedServiceVehicle>().in("targeted_service_id", collect1)
                    .eq("vehicle_id", dto.getVehicleId()));
            if(list.isEmpty()){
                return R.fail("没有巡游计划");
            }
            cruisePlanId = list.get(0).getCruisePlanId();
        }else{
            cruisePlanId = plan.getCruisePlanId();
        }
        // 找对应的多个点位
        List<XpCruisePlanPoint> planPointList = xpCruisePlanPointService.list(new LambdaQueryWrapper<XpCruisePlanPoint>().eq(XpCruisePlanPoint::getCruisePlanId, cruisePlanId).orderByAsc(XpCruisePlanPoint::getSortOrder));
        // 找到现在这个点位
        // 根据dto的pointId 是第几个
        int index = 0;
        for (int i = 0; i < planPointList.size(); i++) {
            if (planPointList.get(i).getPointId().equals(dto.getPointId())) {
                index = i;
                break;
            }
        }
        XpCruiseOrder newXpCruiseOrder = dto.getNewXpCruiseOrder();
        XpCruisePlanPoint xpCruisePlanPoint = null;
        //   判断是否是最后一个 是则往前一个  否找下一个
        if (index == planPointList.size() - 1) {
            // 最后一个 找上一个
            xpCruisePlanPoint = planPointList.get(index - 1);
            newXpCruiseOrder.setOrderReverse(2);
        } else if (index == 0) {
            // 第一个 找下一个
            xpCruisePlanPoint = planPointList.get(index + 1);
            newXpCruiseOrder.setOrderReverse(1);
        } else {
            // 中间点位
            if (dto.getOrderReverse() == 1) {
                // 正向 找下一个
                xpCruisePlanPoint = planPointList.get(index + 1);
                newXpCruiseOrder.setOrderReverse(1);
            } else {
                // 反向找上一个
                xpCruisePlanPoint = planPointList.get(index - 1);
                newXpCruiseOrder.setOrderReverse(2);
            }
        }
        Long pointId = xpCruisePlanPoint.getPointId();
        XpPoint point = pointService.getById(pointId);
        newXpCruiseOrder.setEndPointId(pointId);
        newXpCruiseOrder.setEndPointName(point.getPointName());
        newXpCruiseOrder.setEndLon(point.getPointLon());
        newXpCruiseOrder.setEndLat(point.getPointLat());
        newXpCruiseOrder.setMissionId(xpCruisePlanPoint.getCruisePlanId());
        //获取巡游导航数据,如果无法获取到有效的导航,则继续用下一个点位作为终点
        LonLatDto destination = new LonLatDto();
        LonLatDto origin = new LonLatDto();
        boolean ROUTE_FLAG = false;
        boolean start = false;
        if(newXpCruiseOrder.getOrderReverse() == 1){
            for (XpCruisePlanPoint xpCruisePlanPoint1 : planPointList) {
                if (start || xpCruisePlanPoint1.getPointId().equals(newXpCruiseOrder.getEndPointId())) {
                    start = true;
                    origin.setLongitude(newXpCruiseOrder.getStartLon());
                    origin.setLatitude(newXpCruiseOrder.getStartLat());
                    XpPoint xpPoint1 = pointService.getById(xpCruisePlanPoint1.getPointId());
                    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:" + newXpCruiseOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
                    ROUTE_FLAG = true;
                    break;
                }
            }
        }else{
            for (int i = planPointList.size() - 1; i >= 0; i--) {
                XpCruisePlanPoint xpCruisePlanPoint1 = planPointList.get(i);
                if(start || xpCruisePlanPoint1.getPointId().equals(newXpCruiseOrder.getEndPointId())){
                    start = true;
                    origin.setLongitude(newXpCruiseOrder.getStartLon());
                    origin.setLatitude(newXpCruiseOrder.getStartLat());
                    XpPoint xpPoint1 = pointService.getById(xpCruisePlanPoint1.getPointId());
                    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:" + newXpCruiseOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
                    ROUTE_FLAG = true;
                    break;
                }
            }
        }
        if(!ROUTE_FLAG){
            return R.fail("巡游计划获取导航信息失败");
        }
        return R.ok(newXpCruiseOrder);
    }
    /**
     * 获取巡游计划
     * @param vehicleId
     * @return
     */
    @PostMapping("/logan/inner/cruise/getCruisePlan")
    public R<XpCruisePlanVehicle> getCruisePlan(@RequestParam Long vehicleId) {
        XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, vehicleId));
        return R.ok(plan);
    }
    /**
     * 获取巡游计划点位列表
     * @param vehicleId
     * @return
     */
    @PostMapping("/logan/inner/cruise/getCruisePlanPointList")
    public R<List<XpCruisePlanPoint>> getCruisePlanPointList(@RequestParam Long vehicleId) {
        // 先找计划
        XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, vehicleId));
        Long cruisePlanId = null;
        if(null == plan){
            //没有巡游计划,判断是否在定向服务里面
            List<XpTargetedService> targetedServices = xpTargetedServiceService.list(new QueryWrapper<XpTargetedService>().eq("status", 1));
            if(targetedServices.isEmpty()){
                return R.fail("没有巡游计划,执行收车失败");
            }
            List<Long> collect1 = targetedServices.stream().map(XpTargetedService::getId).collect(Collectors.toList());
            List<XpTargetedServiceVehicle> list = xpTargetedServiceVehicleService.list(new QueryWrapper<XpTargetedServiceVehicle>().in("targeted_service_id", collect1)
                    .eq("vehicle_id", vehicleId));
            if(list.isEmpty()){
                return R.fail("没有巡游计划,执行收车失败");
            }
            cruisePlanId = list.get(0).getCruisePlanId();
        }else{
            cruisePlanId = plan.getCruisePlanId();
        }
        // 找对应的多个点位
        List<XpCruisePlanPoint> planPointList = xpCruisePlanPointService.list(new LambdaQueryWrapper<XpCruisePlanPoint>()
                .eq(XpCruisePlanPoint::getCruisePlanId, cruisePlanId).orderByAsc(XpCruisePlanPoint::getSortOrder));
        return R.ok(planPointList);
    }
    /**
     * 获取巡游订单数据
     * @return
     */
    @PostMapping("/logan/inner/cruise/getNewCruiseOrder")
    public R<XpCruiseOrder> getNewCruiseOrder(@RequestBody NewCruiseOrderDto dto) {
        // 先找计划
        XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, dto.getVehicleId()));
        if(null == plan){
            //没有巡游计划,判断是否在定向服务里面
            List<XpTargetedService> targetedServices = xpTargetedServiceService.list(new QueryWrapper<XpTargetedService>().eq("status", 1));
            if(targetedServices.isEmpty()){
                return R.ok(null);
            }
            List<Long> collect1 = targetedServices.stream().map(XpTargetedService::getId).collect(Collectors.toList());
            List<XpTargetedServiceVehicle> list = xpTargetedServiceVehicleService.list(new QueryWrapper<XpTargetedServiceVehicle>().in("targeted_service_id", collect1)
                    .eq("vehicle_id", dto.getVehicleId()));
            if(list.isEmpty()){
                return R.ok(null);
            }
            plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>()
                    .eq(XpCruisePlanVehicle::getCruisePlanId, list.get(0).getCruisePlanId()).eq(XpCruisePlanVehicle::getVehicleId, dto.getVehicleId()));
        }
        // 找对应的多个点位
        List<XpCruisePlanPoint> planPointList = xpCruisePlanPointService.list(new LambdaQueryWrapper<XpCruisePlanPoint>().eq(XpCruisePlanPoint::getCruisePlanId, plan.getCruisePlanId()).orderByAsc(XpCruisePlanPoint::getSortOrder));
        XpCruiseOrder newXpCruiseOrder = new XpCruiseOrder();
        newXpCruiseOrder.setFleetId(dto.getFleetId());
        newXpCruiseOrder.setVehicleId(dto.getVehicleId());
        newXpCruiseOrder.setVehicleVin(dto.getVehicleVin());
        newXpCruiseOrder.setOrderType(1);
        newXpCruiseOrder.setMissionId(plan.getCruisePlanId());
        newXpCruiseOrder.setStatus(1);
        newXpCruiseOrder.setOrderReverse(1);
        newXpCruiseOrder.setXpuTaskId(snowflake.nextId() + "");
        GeoJsonPoint point = dto.getPoint();
        // 起点
        newXpCruiseOrder.setStartLon(point.getX());
        newXpCruiseOrder.setStartLat(point.getY());
        // 终点
        XpCruisePlanPoint endCruisePlanPoint = planPointList.get(0);
        Long endPointId = endCruisePlanPoint.getPointId();
        XpPoint endPoint = pointService.getById(endPointId);
        newXpCruiseOrder.setEndPointId(endPointId);
        newXpCruiseOrder.setEndPointName(endPoint.getPointName());
        newXpCruiseOrder.setEndLon(endPoint.getPointLon());
        newXpCruiseOrder.setEndLat(endPoint.getPointLat());
        //获取巡游导航数据,如果无法获取到有效的导航,则继续用下一个点位作为终点
        LonLatDto destination = new LonLatDto();
        LonLatDto origin = new LonLatDto();
        boolean ROUTE_FLAG = false;
        boolean start = false;
        if(newXpCruiseOrder.getOrderReverse() == 1){
            for (XpCruisePlanPoint xpCruisePlanPoint1 : planPointList) {
                if (start || xpCruisePlanPoint1.getPointId().equals(newXpCruiseOrder.getEndPointId())) {
                    start = true;
                    origin.setLongitude(newXpCruiseOrder.getStartLon());
                    origin.setLatitude(newXpCruiseOrder.getStartLat());
                    XpPoint xpPoint1 = pointService.getById(xpCruisePlanPoint1.getPointId());
                    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:" + newXpCruiseOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
                    ROUTE_FLAG = true;
                    break;
                }
            }
        }else{
            for (int i = planPointList.size() - 1; i >= 0; i--) {
                XpCruisePlanPoint xpCruisePlanPoint1 = planPointList.get(i);
                if(start || xpCruisePlanPoint1.getPointId().equals(newXpCruiseOrder.getEndPointId())){
                    start = true;
                    origin.setLongitude(newXpCruiseOrder.getStartLon());
                    origin.setLatitude(newXpCruiseOrder.getStartLat());
                    XpPoint xpPoint1 = pointService.getById(xpCruisePlanPoint1.getPointId());
                    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:" + newXpCruiseOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
                    ROUTE_FLAG = true;
                    break;
                }
            }
        }
        if(!ROUTE_FLAG){
            return R.fail("巡游计划获取导航信息失败");
        }
        return R.ok(newXpCruiseOrder);
    }
    /**
     * 获取车辆返回点位
     * @param xpCruiseOrder
     * @return
     */
    @PostMapping("/logan/inner/cruise/findReturnCruisePoint")
    public R<XpCruiseOrder> findReturnCruisePoint(@RequestBody XpCruiseOrder xpCruiseOrder) {
        // 先找计划
        XpCruisePlanVehicle plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>().eq(XpCruisePlanVehicle::getVehicleId, xpCruiseOrder.getVehicleId()));
        if(null == plan){
            //没有巡游计划,判断是否在定向服务里面
            List<XpTargetedService> targetedServices = xpTargetedServiceService.list(new QueryWrapper<XpTargetedService>().eq("status", 1));
            if(targetedServices.isEmpty()){
                return R.fail("没有巡游计划,执行收车失败");
            }
            List<Long> collect1 = targetedServices.stream().map(XpTargetedService::getId).collect(Collectors.toList());
            List<XpTargetedServiceVehicle> list = xpTargetedServiceVehicleService.list(new QueryWrapper<XpTargetedServiceVehicle>().in("targeted_service_id", collect1)
                    .eq("vehicle_id", xpCruiseOrder.getVehicleId()));
            if(list.isEmpty()){
                return R.fail("没有巡游计划,执行收车失败");
            }
            plan = xpCruisePlanVehicleService.getOne(new LambdaQueryWrapper<XpCruisePlanVehicle>()
                    .eq(XpCruisePlanVehicle::getCruisePlanId, list.get(0).getCruisePlanId()).eq(XpCruisePlanVehicle::getVehicleId, xpCruiseOrder.getVehicleId()));
        }
        // 找对应的多个点位
        List<XpCruisePlanPoint> planPointList = xpCruisePlanPointService.list(new LambdaQueryWrapper<XpCruisePlanPoint>().eq(XpCruisePlanPoint::getCruisePlanId, plan.getCruisePlanId()).orderByAsc(XpCruisePlanPoint::getSortOrder));
        XpPoint xpPoint = pointService.list(new LambdaQueryWrapper<XpPoint>().eq(XpPoint::getParkingPoint, 1).in(XpPoint::getId, planPointList.stream().map(XpCruisePlanPoint::getPointId).collect(Collectors.toList()))).get(0);
        xpCruiseOrder.setEndPointId(xpPoint.getId());
        xpCruiseOrder.setEndPointName(xpPoint.getPointName());
        xpCruiseOrder.setEndLon(xpPoint.getPointLon());
        xpCruiseOrder.setEndLat(xpPoint.getPointLat());
        xpCruiseOrder.setMissionId(plan.getCruisePlanId());
        //获取巡游导航数据,如果无法获取到有效的导航,则继续用下一个点位作为终点
        LonLatDto destination = new LonLatDto();
        LonLatDto origin = new LonLatDto();
        boolean ROUTE_FLAG = false;
        boolean start = false;
        if(xpCruiseOrder.getOrderReverse() == 1){
            for (XpCruisePlanPoint xpCruisePlanPoint1 : planPointList) {
                if (start || xpCruisePlanPoint1.getPointId().equals(xpCruiseOrder.getEndPointId())) {
                    start = true;
                    origin.setLongitude(xpCruiseOrder.getStartLon());
                    origin.setLatitude(xpCruiseOrder.getStartLat());
                    XpPoint xpPoint1 = pointService.getById(xpCruisePlanPoint1.getPointId());
                    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(), JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
                    ROUTE_FLAG = true;
                    break;
                }
            }
        }else{
            for (int i = planPointList.size() - 1; i >= 0; i--) {
                XpCruisePlanPoint xpCruisePlanPoint1 = planPointList.get(i);
                if(start || xpCruisePlanPoint1.getPointId().equals(xpCruiseOrder.getEndPointId())){
                    start = true;
                    origin.setLongitude(xpCruiseOrder.getStartLon());
                    origin.setLatitude(xpCruiseOrder.getStartLat());
                    XpPoint xpPoint1 = pointService.getById(xpCruisePlanPoint1.getPointId());
                    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(), JSON.toJSONString(routeVo), 24L, TimeUnit.DAYS);
                    ROUTE_FLAG = true;
                    break;
                }
            }
        }
        if(!ROUTE_FLAG){
            return R.fail("巡游计划获取导航信息失败");
        }
        return R.ok(xpCruiseOrder);
    }
    /**
     * 判断点位ID列表是否存在关联的巡游计划点位(内部接口)
     */
    @PostMapping("/logan/inner/cruise/existsCruisePlanPointByPointIds")
    public R<Boolean> existsCruisePlanPointByPointIds(@RequestBody List<Long> pointIds) {
        List<Long> distinctPointIds = pointIds == null
                ? java.util.Collections.emptyList()
                : pointIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
        if (distinctPointIds.isEmpty()) {
            return R.ok(Boolean.FALSE);
        }
        XpCruisePlanPoint exists = xpCruisePlanPointService.getOne(
                new LambdaQueryWrapper<XpCruisePlanPoint>()
                        .in(XpCruisePlanPoint::getPointId, distinctPointIds)
                        .last("limit 1")
        );
        return R.ok(exists != null);
    }
}