sql/增量sql/xprt_operation.sql
@@ -1,7 +1,19 @@ ALTER TABLE `xp_banner` ADD COLUMN `sort` int NULL DEFAULT NULL COMMENT '排序' AFTER `banner_status`; ALTER TABLE `xp_point_0` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_cruise_plan_vehicle` ADD COLUMN `id` bigint NOT NULL COMMENT '自增id' FIRST; ALTER TABLE `xp_point_1` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_cruise_plan_vehicle` ADD PRIMARY KEY (`id`) USING BTREE; ALTER TABLE `xp_point_2` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_cruise_plan_vehicle` MODIFY COLUMN `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id'; ALTER TABLE `xp_point_3` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_point_4` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_point_5` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_point_6` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_point_7` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_point_8` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; ALTER TABLE `xp_point_9` ADD COLUMN `fp_electronic_area_id` bigint NULL DEFAULT NULL COMMENT '分片建' AFTER `electronic_area_id`; xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -793,8 +793,10 @@ break; case ORDER_RECEIVED: //收到订单 buildPushOrderStatus(orderId, OrderStatusEnum.READY_DEPART, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId.contains("XU") ? orderId.substring(2) : orderId), OrderStatusEnum.READY_DEPART.getCode()); if(!orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.READY_DEPART, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.READY_DEPART.getCode()); } break; case ORDER_STARTED: //开始执行订单 @@ -802,8 +804,10 @@ break; case ORDER_EN_ROUTE_TO_PICKUP: //前往上车点 buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId.contains("XU") ? orderId.substring(2) : orderId), OrderStatusEnum.PICK_UP.getCode()); if(!orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PICK_UP.getCode()); } break; case ORDER_ARRIVED_AT_PICKUP: //到达上车点 @@ -811,49 +815,41 @@ break; case ORDER_WAITING_FOR_PICKUP: //等待乘客上车 buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP_GUESTS, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId.contains("XU") ? orderId.substring(2) : orderId), OrderStatusEnum.PICK_UP_GUESTS.getCode()); if(!orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP_GUESTS, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PICK_UP_GUESTS.getCode()); } break; case ORDER_PASSENGER_ONBOARD: //乘客已上车 buildPushOrderStatus(orderId, OrderStatusEnum.PASSENGER_BOARDED, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId.contains("XU") ? orderId.substring(2) : orderId), OrderStatusEnum.PASSENGER_BOARDED.getCode()); if(!orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.PASSENGER_BOARDED, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PASSENGER_BOARDED.getCode()); } break; case ORDER_EN_ROUTE_TO_DESTINATION: //前往目的地 buildPushOrderStatus(orderId, OrderStatusEnum.IN_SERVICE, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId.contains("XU") ? orderId.substring(2) : orderId), OrderStatusEnum.IN_SERVICE.getCode()); if(!orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.IN_SERVICE, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.IN_SERVICE.getCode()); } break; case ORDER_ARRIVED_AT_DESTINATION: //到达目的地 log.info("到达目的地,不做任何处理:{}", orderId); break; case ORDER_WAITING_FOR_DROPOFF: //等待乘客下车 buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId.contains("XU") ? orderId.substring(2) : orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode()); //等待乘客下车,开始倒计时发下巡游单 if(!orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode()); } break; case ORDER_DROPOFF_COMPLETED: //下车完成 buildPushOrderStatus(orderId, OrderStatusEnum.APPROVAL_REJECTION, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId.contains("XU") ? orderId.substring(2) : orderId), OrderStatusEnum.APPROVAL_REJECTION.getCode()); // 下发巡游任务 R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId)); if(xpOrderR.getCode()==200){ XpOrder orderData = xpOrderR.getData(); Long vehicleId =orderData.getVehicleId(); R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(vehicleId); if(xpVehicleR.getData()!=null){ XpVehicle xpVehicle = xpVehicleR.getData(); //订单结束,在添加导航数据之前先将车辆状态修改为空闲 xpVehicleClient.updateVehicleStatus(new UpdateVehicleStateDto(xpVehicle.getVehicleVin(), 0)); xpVehicle = xpVehicleClient.queryById(vehicleId).getData(); AddCruiseMissionDto addCruiseMissionDto = new AddCruiseMissionDto(); addCruiseMissionDto.setOrder(orderData); addCruiseMissionDto.setVehicle(xpVehicle); xpCruiseOrderClient.addCruiseMission(addCruiseMissionDto); } if(!orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.APPROVAL_REJECTION, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.APPROVAL_REJECTION.getCode()); } break; case ORDER_COMPLETED: @@ -862,12 +858,16 @@ break; case ORDER_CANCELLED: //已取消 buildPushOrderStatus(orderId, OrderStatusEnum.CANCELED, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId.contains("XU") ? orderId.substring(2) : orderId), OrderStatusEnum.CANCELED.getCode()); if(!orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.CANCELED, sequence); xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.CANCELED.getCode()); } break; case ORDER_ARRIVED_AT_CRUISE_DESTINATION: //到达巡游终点 buildPushOrderStatus(orderId, OrderStatusEnum.COMPLETED, sequence); if(orderId.contains("XU")){ buildPushOrderStatus(orderId, OrderStatusEnum.COMPLETED, sequence); } break; case ORDER_PAUSED: //订单暂停 xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -217,7 +217,7 @@ } // // 算距离 // 算距离 R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (distanceAndDuration.getCode() != 200) { throw new ServiceException("获取导肮信息失败", I18nKeyConstant.PATH_NOT_FOUND); @@ -310,35 +310,7 @@ // 8. 构建响应对象 RouteAndFareVo routeAndFareVo = new RouteAndFareVo(); // MOCK数据 // RouteVo routeVo = new RouteVo(); // routeVo.setDistance(3000); // routeVo.setDuration(5); // routeVo.setRouteID("1"); // List<LonLatDto> routePolyline = Arrays.asList( // // 起点:天府新谷 // new LonLatDto(104.05363, 30.58937), // // // 途经点1:府城大道与交子北二路交叉口附近 // new LonLatDto(104.05821, 30.58745), // // // 途经点2:交子大道与成汉南路交叉口 // new LonLatDto(104.06418, 30.58492), // // // 途经点3:交子大道与万象南路交叉口 // new LonLatDto(104.06975, 30.58321), // // // 途经点4:交子大道与益州大道交叉口 // new LonLatDto(104.07366, 30.58198), // // // 终点:金融城(地铁站附近) // new LonLatDto(104.076544, 30.581039) // ); // routeVo.setPolyline(routePolyline); routeAndFareVo.setRoute(routeVo); routeAndFareVo.setXpPricingCard(xpPricingCardVo); FareVo fareVo = new FareVo(); @@ -393,8 +365,6 @@ redisService.setCacheObject(key, voJsonStr, 5l, TimeUnit.MINUTES); //缓存导航数据,用于下单后推送导航给车端和乘客端 redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + userId, JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS); return routeAndFareVo; } @@ -562,18 +532,6 @@ xpOrder.setCreateTime(LocalDateTime.now()); // 计算距离 和 时间 RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(xpPoint.getPointLon()); lonLatDto.setLatitude(xpPoint.getPointLat()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(endXpPoint.getPointLon()); lonLatDto1.setLatitude(endXpPoint.getPointLat()); routeAndFareDto.setDestination(lonLatDto1); XpOpenCity openCities = xpOpenCityMapper.selectById(dto.getOpenCityId()); if (openCities == null) { throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND); @@ -582,18 +540,15 @@ dto.setOpenCityId(xpOpenCity.getId()); xpOrder.setCityCode(xpOpenCity.getCityCode()); XpRoutePlan xpRoutePlan = xpRoutePlanMapper.selectOne(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getAuditStatus, 2).eq(XpRoutePlan::getCityCode, xpOpenCity.getCityCode())); if (xpRoutePlan != null) { routeAndFareDto.setRoutePlanRule(xpRoutePlan.getRoutePlanRule()); } R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto); Integer distance = 0; Integer duration = 0; if (distanceAndDuration.getCode() != 200) { // throw new ServiceException("订单生成失败", I18nKeyConstant.ORDER_CREATE_FAIL); Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_END_DATA:" + uid); if (cacheObject != null) { RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class); distance = routeVo.getDistance(); duration = routeVo.getDuration(); } // distance = distanceAndDuration.getData().getDistance(); // duration = distanceAndDuration.getData().getDuration(); // 产生订单 R<Long> addOrderR = xpOrderClient.addOrder(xpOrder); @@ -626,7 +581,7 @@ // 和上车点进行判断是否<maxPushDistance double v = FastDistanceCalculator.distanceFast(Double.parseDouble(lonLat.split(",")[1]), Double.parseDouble(lonLat.split(",")[0]), xpPoint.getPointLat(), xpPoint.getPointLon()); if (v < maxPushDistance) { String value = orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule(); String value = orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + xpRoutePlan.getRoutePlanRule(); if (isPriorityDispatch) { // 头部 value 订单_经纬度_状态_用户id_订单编号_距离_时间 redisService.addToHead(s, value); @@ -654,7 +609,7 @@ } String key = CacheConstants.QUEUE_POINT_ID + "-" + xpPoint.getId() + "-" + xpPoint.getPointLon() + "," + xpPoint.getPointLat(); redisService.setCacheList(key, Arrays.asList(orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule())); redisService.setCacheList(key, Arrays.asList(orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + xpRoutePlan.getRoutePlanRule())); log.info("订单推单:{} {}", key, redisService.getCacheList(key)); xpOrder.setQueueName(key); xpOrderClient.updateOrder(xpOrder); @@ -670,17 +625,6 @@ xpGeoQueryEntity.setTimestamp(System.currentTimeMillis()); geoQueryEntityService.save(xpGeoQueryEntity); return orderId.toString(); // // XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(dto.getXpElectronicFenceAreaId()); // // 获取电子围栏的车辆 // R<List<XpVehicle>> vehicles = xpVehicleClient.listByFenceId(xpElectronicFenceArea.getElectronicId()); // // 产生订单 存订单数据 // 下发指令 消息推送用户端 // return null; } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/GDMapGeocodingUtil.java
@@ -32,200 +32,8 @@ @Autowired private XpGeoFencingPolygonService xpGeoFencingPolygonService; // 自定义线程池配置 private static final int CORE_POOL_SIZE = 5; // 核心线程数 private static final int MAX_POOL_SIZE = 10; // 最大线程数 private static final long KEEP_ALIVE_TIME = 60L; // 线程空闲存活时间 private static final int QUEUE_CAPACITY = 100; // 阻塞队列容量 // 创建自定义线程池 private final ExecutorService customThreadPool = new ThreadPoolExecutor( CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<>(QUEUE_CAPACITY), new ThreadFactory() { private final AtomicInteger threadNumber = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { Thread t = new Thread(r, "route-check-thread-" + threadNumber.getAndIncrement()); t.setDaemon(true); // 设置为守护线程,避免应用关闭时线程未停止 return t; } }, new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:调用线程执行 ); // public RouteVo getDistanceAndTime(LonLatDto start, LonLatDto end, String avoidRoads, String fenceId, Integer routePlanRule) { // RouteVo routeVo = new RouteVo(); // // String url = "https://tsapi.amap.com/v1/route/price?key=" + key + "&extensions=all&start=" + start.getLongitude() + "," + start.getLatitude(); // HashMap<String, Object> params = new HashMap<>(); // params.put("extensions", "all"); // params.put("start", start.getLongitude() + "," + start.getLatitude()); // params.put("end", end.getLongitude() + "," + end.getLatitude()); // params.put("routeUserType", 2); // if (avoidRoads != null && !avoidRoads.isEmpty()) { // params.put("voidPolygons", avoidRoads); // } // if (routePlanRule != null) { // params.put("strategy", routePlanRule); // } // // String post = HttpUtils.post(url, JSON.toJSONString(params)); // System.out.println("高德地图返回结果:" + post); // // JSONObject jsonObject = JSON.parseObject(post); // String data = jsonObject.getString("data"); // JSONObject jsonObject1 = JSON.parseObject(data); // JSONArray path = jsonObject1.getJSONArray("paths"); // // if (path == null || path.isEmpty()) { // return null; // } // // // 使用自定义线程池并行处理每个路径的围栏检查 // List<Future<PathCheckResult>> futures = new ArrayList<>(); // CountDownLatch latch = new CountDownLatch(path.size()); // 用于等待所有任务完成 // // // 提交每个路径的处理任务 // for (int j = 0; j < path.size(); j++) { // final int index = j; // JSONObject pathObject = path.getJSONObject(index); // // Future<PathCheckResult> future = customThreadPool.submit(() -> { // try { // PathCheckResult result = new PathCheckResult(); // result.setIndex(index); // result.setPathObject(pathObject); // // String points = pathObject.getString("points"); // String[] split = points.split(";"); // // // 检查点位是否在围栏内 // boolean inFence = checkPointsInFence(split, fenceId); // result.setInFence(inFence); // // return result; // } finally { // latch.countDown(); // 任务完成,计数器减1 // } // }); // // futures.add(future); // } // // try { // // 等待所有任务完成,设置超时时间 // if (!latch.await(10, TimeUnit.SECONDS)) { // System.out.println("路径检查任务超时"); // // 取消所有未完成的任务 // for (Future<PathCheckResult> future : futures) { // if (!future.isDone()) { // future.cancel(true); // } // } // } // } catch (InterruptedException e) { // Thread.currentThread().interrupt(); // System.out.println("路径检查任务被中断"); // return null; // } // // // 收集处理结果,找到第一个不在围栏内的路径 // PathCheckResult validPathResult = null; // // for (Future<PathCheckResult> future : futures) { // try { // if (future.isDone() && !future.isCancelled()) { // PathCheckResult result = future.get(); // if (!result.isInFence()) { // validPathResult = result; // break; // 找到有效的就停止 // } // } // } catch (InterruptedException | ExecutionException e) { // System.out.println("获取路径检查结果失败: " + e.getMessage()); // e.printStackTrace(); // } // } // // // 如果找到了有效路径,处理该路径数据 // if (validPathResult != null) { // JSONObject validPath = validPathResult.getPathObject(); // String routeID = validPath.getString("routeID"); // String points = validPath.getString("points"); // String[] split = points.split(";"); // // Integer costTime = validPath.getInteger("costTime"); // Integer distance = validPath.getInteger("distance"); // // routeVo.setDistance(distance); // routeVo.setDuration(costTime); // // ArrayList<LonLatDto> lonLatDtos = new ArrayList<>(split.length); // for (String s : split) { // String[] split1 = s.split(","); // LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1])); // lonLatDtos.add(lonLatDto); // } // routeVo.setPolyline(lonLatDtos); // routeVo.setRouteID(routeID); // // return routeVo; // } // // return null; // } /** * 路径检查结果内部类 */ private static class PathCheckResult { private int index; private JSONObject pathObject; private boolean inFence; // true: 所有点都在围栏内, false: 有点不在围栏内 public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public JSONObject getPathObject() { return pathObject; } public void setPathObject(JSONObject pathObject) { this.pathObject = pathObject; } public boolean isInFence() { return inFence; } public void setInFence(boolean inFence) { this.inFence = inFence; } } /** * 检查路径点位是否在围栏内 */ private boolean checkPointsInFence(String[] points, String fenceId) { // 取5分之一的点位进行检查 for (int i = 0; i < points.length; i++) { if (i % 5 == 0) { String[] split1 = points[i].split(","); LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1])); if (!xpGeoFencingPolygonService.isInFence(lonLatDto.getLongitude(), lonLatDto.getLatitude(), fenceId, "operating_area")) { return false; // 有点位不在围栏内 } } } return true; // 所有检查的点都在围栏内 } /** * 根据起始点获取驾车距离 和 时间 以及避让区域 @@ -263,23 +71,22 @@ JSONObject jsonObject1 = JSON.parseObject(data); JSONArray path = jsonObject1.getJSONArray("paths"); log.info("开始判断导航路径是否在运营区域范围内 {}", fenceId); for (Object o : path) { JSONObject jsonObject2 = (JSONObject) o; String routeID = jsonObject2.getString("routeID"); String points = jsonObject2.getString("points"); String[] split = points.split(";"); int temp=0; // 取5分之一的点位 for (int i = 0; i < split.length; i++) { if (i % 10 == 0) { String[] split1 = split[i].split(","); LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1])); if (!xpGeoFencingPolygonService.isInFence(lonLatDto.getLongitude(), lonLatDto.getLatitude(), fenceId, "operating_area")) { temp++; break; } } List<LonLatDto> pointsArray = new ArrayList<>(); for (String string : split) { String[] split1 = string.split(","); LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1])); pointsArray.add(lonLatDto); } ForkJoinPool pool = new ForkJoinPool(); // 创建ForkJoinPool对象(默认使用处理器的核心数作为线程池大小) ArrayPointsTask arrayPointsTask = new ArrayPointsTask(pointsArray, fenceId); // 创建求和任务对象并传入数组作为参数(这里也可以传入数组的一部分作为参数来实现更细粒度的拆分) Long temp = pool.invoke(arrayPointsTask); // 提交任务并等待处理完成(也可以使用submit方法提交任务并获取一个Future对象来异步获取结果) pool.shutdown(); // 关闭ForkJoinPool(释放资源) if(temp==0){ Integer costTime = jsonObject2.getInteger("costTime"); Integer distance = jsonObject2.getInteger("distance"); @@ -293,15 +100,54 @@ } routeVo.setPolyline(lonLatDtos); routeVo.setRouteID(routeID); log.info("导航 {} 在 {} 运营区域内", routeVo.getRouteID(), fenceId); return routeVo; } } return null; } class ArrayPointsTask extends RecursiveTask<Long>{ //最大定位集合阈值 private final int THRESHOLD = 10; //围栏ID String fenceId; //定位点集合 List<LonLatDto> pointsArray; public ArrayPointsTask(List<LonLatDto> pointsArray, String fenceId) { this.pointsArray = pointsArray; this.fenceId = fenceId; } @Override protected Long compute() { if(this.pointsArray.size() > THRESHOLD){ int num = this.pointsArray.size() / 2; ArrayPointsTask task1 = new ArrayPointsTask(this.pointsArray.subList(0, num), fenceId); ArrayPointsTask task2 = new ArrayPointsTask(this.pointsArray.subList(num, this.pointsArray.size()), fenceId); task1.fork(); task2.fork(); return task1.join() + task2.join(); }else{ long temp = 0; for (LonLatDto lonLatDto : this.pointsArray) { if (!xpGeoFencingPolygonService.isInFence(lonLatDto.getLongitude(), lonLatDto.getLatitude(), fenceId, "operating_area")) { temp++; break; } } return temp; } } } /** * 线路还原接口 * 车端使用的数据 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java
@@ -2,6 +2,7 @@ import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.order.XpCruiseOrder; import com.xiaopeng.order.service.IXpCruiseOrderService; @@ -26,6 +27,7 @@ protected IXpCruiseOrderService xpCruiseOrderService; protected OrderMissionClient orderMissionClient; protected XpVehicleClient xpVehicleClient; protected UserVehicleClient userVehicleClient; public AbstractJob(){ this.xpOrderService = SpringContextsUtil.getBean(IXpOrderService.class); this.xpPushMessageClient = SpringContextsUtil.getBean(XpPushMessageClient.class); @@ -33,6 +35,7 @@ this.xpCruiseOrderService = SpringContextsUtil.getBean(IXpCruiseOrderService.class); this.orderMissionClient = SpringContextsUtil.getBean(OrderMissionClient.class); this.xpVehicleClient = SpringContextsUtil.getBean(XpVehicleClient.class); this.userVehicleClient = SpringContextsUtil.getBean(UserVehicleClient.class); } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/AddCruiseMissionJob.java
@@ -5,6 +5,7 @@ import com.xiaopeng.api.model.order.XpOrder; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.vo.OrderType; import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.order.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; @@ -29,26 +30,23 @@ throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long orderId = maps.getLong("id"); try { log.info("开始执行添加任务"); XpCruiseOrder xpCruiseOrder = xpCruiseOrderService.getById(orderId); R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpCruiseOrder.getVehicleId()); if(xpVehicleR.getData().getState()==0){ PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setVin(xpCruiseOrder.getVehicleVin()); pushOrderDto.setOrderId("XU" + xpCruiseOrder.getId()); pushOrderDto.setStartLatitude(xpCruiseOrder.getStartLat()); pushOrderDto.setStartLongitude(xpCruiseOrder.getStartLon()); pushOrderDto.setEndLatitude(xpCruiseOrder.getEndLat()); pushOrderDto.setEndLongitude(xpCruiseOrder.getEndLon()); pushOrderDto.setOrderType(OrderType.CRUISE_ORDER); pushOrderDto.setStage(2); // 调用推送服务 orderId + carVin orderMissionClient.pushOrder(pushOrderDto); } }catch(Exception e){ e.printStackTrace(); } String appid = maps.getString("appid"); XpOrder xpOrder = xpOrderService.getById(orderId); // 解绑用户与车辆关系 CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo(); XpVehicle vehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData(); if (vehicle != null) { cancelTaxiPassengerVo.setVin(vehicle.getVehicleVin()); cancelTaxiPassengerVo.setUid(xpOrder.getAppUserId().toString()); cancelTaxiPassengerVo.setOrderNo(xpOrder.getOrderNumber()); cancelTaxiPassengerVo.setAppId(appid); userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo); // 修改车辆接单状态 vehicle.setState(0); xpVehicleClient.updateVehicleById(vehicle); } xpOrderService.addCruiseMission(vehicle, xpOrder); } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/EndTripJob.java
@@ -3,6 +3,7 @@ import com.xiaopeng.api.model.order.XpOrder; import com.xiaopeng.api.model.order.XpOrderTimeoutLog; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.order.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; @@ -25,19 +26,18 @@ throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long orderId = maps.getLong("id"); try { try { log.info("开始执行自动结束行程任务"); XpOrder xpOrder = xpOrderService.getById(orderId); xpOrderService.endTrip(xpOrder.getId(), String.valueOf(xpOrder.getAppUserId())); if(xpOrder.getStatus() == 7){ xpOrderService.endTrip(xpOrder.getId(), String.valueOf(xpOrder.getAppUserId())); } log.info("结束执行自动结束行程任务"); // 添加超时记录 XpOrderTimeoutLog xpOrderTimeoutLog = new XpOrderTimeoutLog(); xpOrderTimeoutLog.setOrderId(xpOrder.getId()); xpOrderTimeoutLog.setUserId(xpOrder.getAppUserId()); xpOrderTimeoutLogService.save(xpOrderTimeoutLog); R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId()); xpOrderService.addCruiseMission(xpVehicleR.getData(),xpOrder); }catch(Exception e){ e.printStackTrace(); } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -1378,7 +1378,9 @@ if (xpOrder.getStatus() == 0) { return R.fail("订单已取消"); } xpOrder.setStatus(status); if(xpOrder.getStatus() >= 8){ return R.fail("订单已结束"); } switch (status) { case 4: // 查询起点点位 @@ -1409,37 +1411,51 @@ xpOrder.setTripBegin(LocalDateTime.now()); break; case 7: // 查询自动结束行程时间 if (xpOrder.getOpenTrunk() != 1) { Integer arriveTime = xpSystemSettingClient.getOrderFinishTime().getData(); // 添加自动结束行程定时任务job Map<String, ? extends Object> endTripJobMaps = new ImmutableMap.Builder<String, Long>(). put("id", xpOrder.getId()) .build(); QuartzManager.addJob( EndTripJob.class, (EndTripJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.END_TRIP, DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(arriveTime)), endTripJobMaps ); // 推送倒计时消息 Map<String, Object> params = new HashMap<>(); Map<String, Object> content = new HashMap<>(); content.put("orderId", xpOrder.getId().toString()); content.put("isOpen", 1); params.put("type", PushMessageTypeEnum.OPEN_TRUNK.getDesc()); params.put("content", JSONObject.toJSONString(content)); params.put("timestamp", new Date().getTime() + ""); String message = JSONObject.toJSONString(params); SendMessageDTO sendMessageDTO = new SendMessageDTO(); sendMessageDTO.setMessage(message); sendMessageDTO.setAppUserId(String.valueOf(xpOrder.getAppUserId())); xpPushMessageClient.sendStatus(sendMessageDTO); } Integer arriveTime = xpSystemSettingClient.getOrderFinishTime().getData(); // 添加自动结束行程定时任务job Map<String, ? extends Object> endTripJobMaps = new ImmutableMap.Builder<String, String>() .put("id", xpOrder.getId().toString()) .put("appid", appid) .build(); QuartzManager.addJob( EndTripJob.class, (EndTripJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.END_TRIP, DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(arriveTime)), endTripJobMaps ); // 添加车辆到达终点后限停时间到后驶离的定时任务 //时间到后添加巡游订单,解绑车辆关系,车辆驶离点位 XpPoint point = xpPointClient.queryById(xpOrder.getEndPointId()).getData(); Map<String, ? extends Object> jobMaps = new ImmutableMap.Builder<String, String>() .put("id", xpOrder.getId().toString()) .put("appid", appid) .build(); QuartzManager.addJob( AddCruiseMissionJob.class, (AddCruiseMissionJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ADD_CRUISE_MISSION, DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(point.getParkingTimeLimit())), jobMaps ); // 推送倒计时消息 Map<String, Object> params = new HashMap<>(); Map<String, Object> content = new HashMap<>(); content.put("orderId", xpOrder.getId().toString()); content.put("isOpen", 1); params.put("type", PushMessageTypeEnum.OPEN_TRUNK.getDesc()); params.put("content", JSONObject.toJSONString(content)); params.put("timestamp", new Date().getTime() + ""); String message = JSONObject.toJSONString(params); SendMessageDTO sendMessageDTO = new SendMessageDTO(); sendMessageDTO.setMessage(message); sendMessageDTO.setAppUserId(String.valueOf(xpOrder.getAppUserId())); xpPushMessageClient.sendStatus(sendMessageDTO); break; } xpOrder.setStatus(status); xpOrder.setAppUserId(null); this.updateById(xpOrder); return R.ok(); @@ -1474,24 +1490,7 @@ exactMinutes = new BigDecimal(exactMinutes).setScale(2, RoundingMode.HALF_UP).doubleValue(); order.setDuration(exactMinutes); // order.setMileageKilometers(80.0); baseMapper.updateById(order); // 解绑用户与车辆关系 CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo(); XpVehicle vehicle = xpVehicleClient.queryById(order.getVehicleId()).getData(); if (vehicle != null) { cancelTaxiPassengerVo.setVin(vehicle.getVehicleVin()); cancelTaxiPassengerVo.setUid(uid); cancelTaxiPassengerVo.setOrderNo(order.getOrderNumber()); // TODO 加配置文件取 cancelTaxiPassengerVo.setAppId(appid); userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo); // 修改车辆接单状态 vehicle.setState(0); xpVehicleClient.updateVehicleById(vehicle); } // 根据订单所属开通城市id 查询定价 R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId()); @@ -1511,9 +1510,6 @@ TaxiPricingDemoService.GpsPoint point = new TaxiPricingDemoService.GpsPoint(trajectory.getDistance(), trajectory.getLocatetime()); gpsPoints.add(point); } // 补充临时轨迹数据 // List<TaxiPricingDemoService.GpsPoint> gpsPoints = TaxiPricingDemoService.createMockGpsPoints(DateUtils.toDate(order.getCreateTime())); TaxiPricingDemoService.PricingConfig config = new TaxiPricingDemoService.PricingConfig(); JSONArray startingFareJsonArray = JSONArray.parseArray(pricing.getStartingFareJson()); @@ -1532,16 +1528,7 @@ Double duration1 = order.getDuration(); com.alibaba.fastjson.JSONObject basicPricingJson = com.alibaba.fastjson.JSONObject.parseObject(pricing.getBasicPricingJson()); // String num1 = "00:00"; // String num2 = "23:59"; // String num3 = basicPricingJson.getString("num1"); // String num4 = basicPricingJson.getString("num2"); // String num5 = basicPricingJson.getString("num3"); // String num6 = basicPricingJson.getString("num4"); // String num7 = basicPricingJson.getString("num5"); // config.normals.add(new TaxiPricingDemoService.PricingRule("普通时段", num1, num2, Double.parseDouble(num3), Double.parseDouble(num4), Double.parseDouble(num5), Double.parseDouble(num6), Double.parseDouble(num7))); // paramNum4 = basicPricingJson.getDouble("num2"); // paramNum5 = basicPricingJson.getDouble("num3"); XpPricingCardVo xpPricingCardVo = xpPricingUtil.calculationFixedPrice(orderAppUserId.toString(), basicPricingJson, null, mileageKilometers, duration1, 0, 0.0, pricing.getIsDynamicPrice(), order.getCityId(), pricing.getDynamicPricingJson()); XpOrderDetail xpOrderDetail = new XpOrderDetail(); xpOrderDetail.setDetailType(1); @@ -1574,11 +1561,7 @@ order.setOrderMoney(totalPrice); order.setAppUserId(null); baseMapper.updateById(order); } else { //动态计费 if (pricing.getPricingType() == 1) { @@ -1828,18 +1811,7 @@ BigDecimal add = order.getDurationMoney().add(fareBreakdownDetailVo.getMoney()); order.setDurationMoney(add); } // for (XpOrderDetail xpOrderDetail : xpOrderDetails) { // if (xpOrderDetail.getDetailType() == 1) { // order.setDurationType(xpOrderDetail.getType()); // order.setDurationMoney(xpOrderDetail.getMoney()); //// order.setDuration(Double.parseDouble(xpOrderDetail.getDuration() + "")); // } else { // order.setLongDistanceType(order.getDurationType()); // order.setLongDistance(xpOrderDetail.getMileage().doubleValue()); // order.setLongDistancemoney(xpOrderDetail.getMoney()); // } // // } BigDecimal orderMoney = startMoney.add(mileageMoney).add(order.getDurationMoney() != null ? order.getDurationMoney() : BigDecimal.ZERO) .add(order.getLongDistancemoney() != null ? order.getLongDistancemoney() : BigDecimal.ZERO) @@ -1872,87 +1844,6 @@ } order.setAppUserId(null); baseMapper.updateById(order); // 结束后的车辆操作 if (vehicle != null) { // 修改车辆状态 vehicle.setState(0); //发送巡游订单 addCruiseMission(vehicle, order); // // 获取配置 根据配置判断是否该收车 如果是则找到收车点位进行收车操作 // R<XpTaskRule> xpTaskRuleR = xpTaskRuleClient.queryDetail(); // XpTaskRule xpTaskRule = xpTaskRuleR.getData(); // // // 生成新的巡游单子 回到最新巡游的初始起点位置 // XpCruiseOrder xpCruiseOrders = xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 2).orderByDesc(BaseModel::getCreateTime).last("limit 1")); // int temp=0; // if(xpCruiseOrders==null){ // temp=1; // //特殊情况 可能没有产生终止的订单 (到站点就被正常接单了)所以找正常订单 // xpCruiseOrders=xpCruiseOrderMapper.selectOne(new LambdaQueryWrapper<XpCruiseOrder>().eq(XpCruiseOrder::getVehicleId, vehicle.getId()).eq(XpCruiseOrder::getStatus, 3).orderByDesc(BaseModel::getCreateTime).last("limit 1")); // } // XpCruiseOrder xpCruiseOrder = new XpCruiseOrder(); // xpCruiseOrder.setVehicleId(vehicle.getId()); // xpCruiseOrder.setFleetId(vehicle.getFleetId()); // xpCruiseOrder.setVehicleVin(vehicle.getVehicleVin()); // xpCruiseOrder.setOrderType(2); // // 返程起点是当前正常订单的终点 // xpCruiseOrder.setStartPointId(order.getEndPointId()); // xpCruiseOrder.setStartPointName(order.getEndPointName()); // xpCruiseOrder.setStartLon(order.getEndLon()); // xpCruiseOrder.setStartLat(order.getEndLat()); // // // 完成的直接走终点 终止的走起点 // if(temp==0){ // xpCruiseOrder.setEndPointId(xpCruiseOrders.getStartPointId()); // xpCruiseOrder.setEndPointName(xpCruiseOrders.getStartPointName()); // xpCruiseOrder.setEndLon(xpCruiseOrders.getStartLon()); // xpCruiseOrder.setEndLat(xpCruiseOrders.getStartLat()); // }else { // xpCruiseOrder.setEndPointId(xpCruiseOrders.getEndPointId()); // xpCruiseOrder.setEndPointName(xpCruiseOrders.getEndPointName()); // xpCruiseOrder.setEndLon(xpCruiseOrders.getEndLon()); // xpCruiseOrder.setEndLat(xpCruiseOrders.getEndLat()); // } // // // xpCruiseOrder.setStatus(0); // xpCruiseOrder.setLastOrderId(xpCruiseOrders.getId()); // xpCruiseOrder.setCreateTime(LocalDateTime.now()); // xpCruiseOrder.setId("XU"+ IdUtil.fastUUID()); // // // 判断当前时分秒是否大于收车时间 // LocalTime vehicleCollectionTime = xpTaskRule.getVehicleCollectionTime(); // if (vehicleCollectionTime.isBefore(LocalTime.now())) { // vehicle.setOperatingStatus(3); // //找到车辆的收车点位 更新终点点位 // R<XpCruiseOrder> returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder); // xpCruiseOrder = returnCruisePoint.getData(); // } // xpVehicleClient.updateVehicleById(vehicle); // // xpCruiseOrderMapper.insert(xpCruiseOrder); // // // R<XpPoint> xpPointR = xpPointClient.queryById(order.getEndPointId()); // XpPoint data = xpPointR.getData(); // //下发命令 // // 添加自动结束行程定时任务job // Map<String, ? extends Object> jobMaps = // new ImmutableMap.Builder<String, String>(). // put("id", xpCruiseOrder.getId()) // .build(); // QuartzManager.addJob( // AddCruiseMissionJob.class, // (AddCruiseMissionJob.name + xpCruiseOrder.getId()).toUpperCase(), // TimeJobType.ADD_CRUISE_MISSION, // DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(data.getParkingTimeLimit())), // jobMaps // ); } } @@ -1964,6 +1855,7 @@ */ public void addCruiseMission(XpVehicle vehicle, XpOrder order) { log.info("添加巡游订单 {}", vehicle.getPlateNumber()); if (vehicle.getState() != 0 || vehicle.getOperatingStatus() != 1) { log.info("添加巡游单失败,车辆状态限制 {}", vehicle.getState()); return; @@ -2048,25 +1940,20 @@ } xpVehicleClient.updateVehicleById(vehicle); } xpCruiseOrderMapper.insert(xpCruiseOrder); R<XpPoint> xpPointR = xpPointClient.queryById(order.getEndPointId()); XpPoint data = xpPointR.getData(); //下发命令 // 添加自动结束行程定时任务job Map<String, ? extends Object> jobMaps = new ImmutableMap.Builder<String, String>(). put("id", xpCruiseOrder.getId() + "") .build(); QuartzManager.addJob( AddCruiseMissionJob.class, (AddCruiseMissionJob.name + xpCruiseOrder.getId()).toUpperCase(), TimeJobType.ADD_CRUISE_MISSION, DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(data.getParkingTimeLimit())), jobMaps ); log.info("添加巡游单成功 {}", xpCruiseOrder.getId()); //下发XUP巡游订单报文 PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setVin(xpCruiseOrder.getVehicleVin()); pushOrderDto.setOrderId("XU" + xpCruiseOrder.getId()); pushOrderDto.setStartLatitude(xpCruiseOrder.getStartLat()); pushOrderDto.setStartLongitude(xpCruiseOrder.getStartLon()); pushOrderDto.setEndLatitude(xpCruiseOrder.getEndLat()); pushOrderDto.setEndLongitude(xpCruiseOrder.getEndLon()); pushOrderDto.setOrderType(OrderType.CRUISE_ORDER); pushOrderDto.setStage(2); orderMissionClient.pushOrder(pushOrderDto); log.info("下发XUP巡游订单报文成功"); }