package com.xiaopeng.operation.utils; import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; import com.xiaopeng.api.dto.map.RouteAndFareDto; import com.xiaopeng.api.dto.operation.LonLatDto; import com.xiaopeng.api.dto.operation.VehiclePositionByVinDto; import com.xiaopeng.api.dto.pushMessage.SendMessageDTO; import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto; import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; import com.xiaopeng.api.feignClient.map.XpMapClient; import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient; import com.xiaopeng.api.feignClient.order.XpOrderClient; 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.operation.XpElectronicFence; import com.xiaopeng.api.model.operation.XpTradingStrategy; 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.automaticPilot.VehiclePosition; import com.xiaopeng.api.vo.operation.RouteVo; import com.xiaopeng.api.vo.operation.VehiclePositionVo; import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.operation.mapper.XpElectronicFenceMapper; import com.xiaopeng.operation.service.IXpElectronicFenceAreaService; import com.xiaopeng.operation.service.IXpTradingStrategyService; import com.xiaopeng.operation.service.XpPointService; import com.xiaopeng.operation.utils.mango.VehiclePositionService; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Slf4j @Component public class TaskOrderUtil { @Resource private RedisService redisService; @Resource private XpPointService xpPointService; @Resource private IXpElectronicFenceAreaService xpElectronicFenceAreaService; @Resource private XpOrderClient xpOrderClient; @Resource private VehiclePositionService vehiclePositionService; @Resource private IXpTradingStrategyService xpTradingStrategyService; @Resource private XpCruiseOrderClient xpCruiseOrderClient; @Resource private XpVehicleClient xpVehicleClient; @Resource private RedissonClient redissonClient; @Resource private XpMapClient xpMapClient; // @Resource private OrderMissionClient orderMissionClient; @Resource private XpPushMessageClient xpPushMessageClient; @Resource private XpElectronicFenceMapper xpElectronicFenceMapper; // 自定义线程池 private static final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); static { threadPoolTaskExecutor.setCorePoolSize(20); threadPoolTaskExecutor.setMaxPoolSize(100); threadPoolTaskExecutor.setQueueCapacity(20); threadPoolTaskExecutor.setKeepAliveSeconds(60); threadPoolTaskExecutor.setThreadNamePrefix("taskOrder-"); threadPoolTaskExecutor.initialize(); } /** * 5秒执行一次 */ @Scheduled(cron = "0/5 * * * * ?") public void taskOrder() { System.out.println("5秒执行一次"); Set quoteMatchName = redisService.getQuoteMatchName(CacheConstants.QUEUE_POINT_ID); for (String name : quoteMatchName) { String firstElement = redisService.getFirstElement(name); if (firstElement != null) { String[] split = firstElement.toString().split("_"); // 如果未处理 创建新任务 if (split[2].equals("0")) { String value = split[0] + "_" + split[1] + "_1" + "_" + split[3] + "_" + split[4] + "_" + split[5] + "_" + split[6] + "_" + split[7]; // 状态改为处理中 redisService.updateFirst(name, value); threadPoolTaskExecutor.submit(() -> { orderProcess(name, firstElement.toString()); }); } } } } /** * 订单处理 * @param quoteName 队列名称 * @param firstElement 队列第一个元素 */ private void orderProcess(String quoteName, String firstElement) { System.out.println("进入处理环节"); XpTradingStrategy xpTradingStrategy = xpTradingStrategyService.getOne(null); String orderId = firstElement.split("_")[0]; String lonLat = firstElement.split("_")[1]; String uid = firstElement.split("_")[3]; String orderNo = firstElement.split("_")[4]; // 距离 String distance = firstElement.split("_")[5]; // 时间 String duration = firstElement.split("_")[6]; // 后台配置的规则 String planRule = firstElement.split("_")[7]; // 经纬度 String[] split = lonLat.split(","); // 5轮找车辆 //每次查找车辆推单后的等待秒数 int sleepTime = 3; Integer onePushTime = xpTradingStrategy.getOnePushTime(); Double onePushDistance = xpTradingStrategy.getOnePushDistance(); int count = onePushTime / sleepTime; // 第一轮推单 log.info("开始第一轮推单 {}", orderNo); Boolean processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, onePushDistance, distance, duration, planRule); if(processed){ log.info("订单推送成功 {}", orderNo); return; } // 第二轮推单 Integer twoPushTime = xpTradingStrategy.getTwoPushTime(); Double twoPushDistance = xpTradingStrategy.getTwoPushDistance(); count = twoPushTime / sleepTime; log.info("开始第二轮推单 {}", orderNo); processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, twoPushDistance, distance, duration, planRule); if(processed){ log.info("订单推送成功 {}", orderNo); return; } // 第三轮推单 Integer threePushTime = xpTradingStrategy.getThreePushTime(); Double threePushDistance = xpTradingStrategy.getThreePushDistance(); count = threePushTime / sleepTime; log.info("开始第三轮推单 {}", orderNo); processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, threePushDistance, distance, duration, planRule); if(processed){ log.info("订单推送成功 {}", orderNo); return; } // 第四轮推单 Integer fourPushTime = xpTradingStrategy.getFourPushTime(); Double fourPushDistance = xpTradingStrategy.getFourPushDistance(); count = fourPushTime / sleepTime; log.info("开始第四轮推单 {}", orderNo); processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fourPushDistance, distance, duration, planRule); if(processed){ log.info("订单推送成功 {}", orderNo); return; } // 第五轮推单 Integer fivePushTime = xpTradingStrategy.getFivePushTime(); Double fivePushDistance = xpTradingStrategy.getFivePushDistance(); count = fivePushTime / sleepTime; log.info("开始第五轮推单 {}", orderNo); processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fivePushDistance, distance, duration, planRule); if(processed){ log.info("订单推送成功 {}", orderNo); return; } // 取消订单 R xpOrderR = xpOrderClient.queryOrderById(Long.valueOf(orderId)); if (xpOrderR.getCode() == 200) { XpOrder xpOrder = xpOrderR.getData(); if (xpOrder.getStatus() == 1) { log.error("五轮推单结束,无车辆接单,执行取消订单 {}", orderNo); xpOrderClient.cancelOrder(orderId); //推送订单状态给乘客 SendMessageDTO dto = new SendMessageDTO(); dto.setAppUserId(xpOrder.getAppUserId().toString()); dto.setMessage("{\"type\":\"ORDER_STATUS\",\"content\":\"{\\\"orderId\\\":\\\"" + orderId + "\\\",\\\"status\\\":0}\",\"timestamp\":\"" + System.currentTimeMillis() + "\"}"); xpPushMessageClient.sendStatus(dto); //将订单从队列中移除 log.info("五轮推单结束,无车辆接单,执行队列移除订单 {}", orderNo); redisService.popFirstElement(quoteName); } } } /** * 订单处理 * @param quoteName 队列名称 * @param count 轮数 * @param uid * @param split 经纬度 * @param orderNo 订单号 * @param xpTradingStrategy 规则 */ @SneakyThrows private Boolean processPushOrder(String quoteName, int count, int sleepTime, String uid, String[] split, String orderNo, XpTradingStrategy xpTradingStrategy, Double pushDistance, String distance, String duration, String planRule) { log.info("进入推单环节 单号 {}", orderNo); if (count == 0) { count = 1; } // 订单状态 R xpOrderR = xpOrderClient.queryOrderByOrderNo(orderNo); if (xpOrderR.getCode() != 200) { return false; } if (xpOrderR.getData().getStatus() != 1) { return true; } XpOrder xpOrder = xpOrderR.getData(); // 找出围栏id Long xpElectronicFenceAreaId = xpOrder.getXpElectronicFenceAreaId(); Long electronicId = xpElectronicFenceAreaService.getById(xpElectronicFenceAreaId).getElectronicId(); XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(electronicId); for (int i = 0; i < count; i++) { //等到sleepTime秒钟 Thread.sleep(sleepTime * 1000); // 根据距离找车 // 车多则根据配置找具体车数量 根据距离最近 // 更改 暂不限制数量 List positionList = vehiclePositionService.findAvailableVehiclesNearby(Double.parseDouble(split[0]), Double.parseDouble(split[1]), pushDistance, xpTradingStrategy.getSimultaneouslyOrderCount()); log.info("根据距离找车 {} 距离 {}KM 经度 {} 维度 {} 查找结果 {} 单号 {}", orderNo, pushDistance, split[0], split[1], positionList, orderNo); // 获取车辆的区域信息 if (positionList.isEmpty()) { continue; } List vinList = positionList.stream().map(VehiclePosition::getVin).collect(Collectors.toList()); // 获取车辆的信息 筛选出可用车辆 R> vehiclePositionVos = xpVehicleClient.queryVehiclePositionByVin(new VehiclePositionByVinDto(xpElectronicFence.getId(), vinList, xpTradingStrategy.getSimultaneouslyOrderCount())); log.info("筛选可用车辆结果 {} 单号 {}", JSON.toJSONString(vehiclePositionVos), orderNo); if (vehiclePositionVos.getCode() != 200) { continue; } List availableVehiclesNearby = BeanUtil.copyToList(positionList, VehiclePositionVo.class); List data = vehiclePositionVos.getData(); // 找出符合条件的 availableVehiclesNearby = availableVehiclesNearby.stream().filter(e -> data.contains(e.getVin())).collect(Collectors.toList()); // List availableVehiclesNearby =vehiclePositionVos.getData(); if (!availableVehiclesNearby.isEmpty()) { if (availableVehiclesNearby.size() > 1) { log.info("附近有 {} 辆车,进入权重判断流程 单号 {}", availableVehiclesNearby.size(), orderNo); // 走权重 // 订单价值 Integer tendencyOrderValue = xpTradingStrategy.getTendencyOrderValue(); // 距离价值 Integer tendencyDistance = xpTradingStrategy.getTendencyDistance(); // 时间价值 Integer tendencyTime = xpTradingStrategy.getTendencyTime(); // 电量价值 Integer tendencyElectricity = xpTradingStrategy.getTendencyElectricity(); // 找出最大的值是那个 Integer max = Math.max(tendencyOrderValue, Math.max(tendencyDistance, Math.max(tendencyTime, tendencyElectricity))); if (max.equals(tendencyOrderValue)) { // 订单价值 // 时间差权重 Integer weightTimeDifference = xpTradingStrategy.getWeightTimeDifference(); // 距离差权重 Integer weightDistanceDifference = xpTradingStrategy.getWeightDistanceDifference(); // 距离权重 Integer weightDistance = xpTradingStrategy.getWeightDistance(); // 时间权重 Integer weightTime = xpTradingStrategy.getWeightTime(); // 电量权重 Integer weightElectricity = xpTradingStrategy.getWeightElectricity(); // 找出最大的值是那个 Integer max1 = Math.max(weightTimeDifference, Math.max(weightDistanceDifference, Math.max(weightDistance, Math.max(weightTime, weightElectricity)))); // 时间差 if (max1.equals(weightTimeDifference)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.valueOf(split[0])); lonLatDto1.setLatitude(Double.valueOf(split[1])); routeAndFareDto.setDestination(lonLatDto1); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); R distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (distanceAndDuration.getCode() == 200) { // 送驾- 接驾 Integer durationDifference = Integer.parseInt(duration) - distanceAndDuration.getData().getDuration(); vehiclePosition.setTimeDifference(durationDifference); } } } if (max1.equals(weightDistanceDifference)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.valueOf(split[0])); lonLatDto1.setLatitude(Double.valueOf(split[1])); routeAndFareDto.setDestination(lonLatDto1); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); R distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (distanceAndDuration.getCode() == 200) { // 送驾- 接驾 Integer distanceDifference = Integer.parseInt(distance) - distanceAndDuration.getData().getDistance(); vehiclePosition.setDistanceDifference(distanceDifference); } } } if (max1.equals(weightDistance)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.parseDouble(split[0])); lonLatDto1.setLatitude(Double.parseDouble(split[1])); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); routeAndFareDto.setDestination(lonLatDto1); // 调用地图 获取时间 R r = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (r.getCode() == 200) { vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance())); } else { vehiclePosition.setDistance(0.0); } } } if (max1.equals(weightTime)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.parseDouble(split[0])); lonLatDto1.setLatitude(Double.parseDouble(split[1])); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); routeAndFareDto.setDestination(lonLatDto1); // 调用地图 获取时间 R r = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (r.getCode() == 200) { vehiclePosition.setSecond(r.getData().getDuration()); } else { vehiclePosition.setSecond(0); } } } if (max1.equals(weightElectricity)) { // 计算车的分数 分数最大是车的size availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getCurrentElectricity).reversed()).collect(Collectors.toList()); int size = tendencyElectricity; // 做比对的分数 int temp = availableVehiclesNearby.get(0).getCurrentElectricity(); for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setCurrentElectricityScore(vehiclePosition.getCurrentElectricityScore() + size); if (temp != vehiclePosition.getCurrentElectricity()) { size--; } } } // 算出总分 再来排序计算 for (VehiclePositionVo vehiclePositionVo : availableVehiclesNearby) { vehiclePositionVo.setOrderValueTotal(vehiclePositionVo.getCurrentElectricityScore() + vehiclePositionVo.getDistanceScore() + vehiclePositionVo.getTimeScore() + vehiclePositionVo.getDistanceDifference() + vehiclePositionVo.getTimeDifference()); } availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getOrderValueTotal).reversed()).collect(Collectors.toList()); int size = tendencyOrderValue; // 做比对的分数 double temp = availableVehiclesNearby.get(0).getOrderValueTotal(); for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setValueScore(vehiclePosition.getValueScore() + size); if (temp != vehiclePosition.getOrderValueTotal()) { size--; } } } // 距离分数 if (max.equals(tendencyDistance)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.parseDouble(split[0])); lonLatDto1.setLatitude(Double.parseDouble(split[1])); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); routeAndFareDto.setDestination(lonLatDto1); // 调用地图 获取时间 R r = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (r.getCode() == 200) { vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance())); } else { vehiclePosition.setDistance(0.0); } } availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList()); int size = tendencyDistance; // 做比对的分数 double temp = availableVehiclesNearby.get(0).getDistance(); for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setDistanceScore(vehiclePosition.getDistanceScore() + size); if (temp != vehiclePosition.getDistance()) { size--; } } } // 时间分数 if (max.equals(tendencyTime)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.parseDouble(split[0])); lonLatDto1.setLatitude(Double.parseDouble(split[1])); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); routeAndFareDto.setDestination(lonLatDto1); // 调用地图 获取时间 R r = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (r.getCode() == 200) { vehiclePosition.setSecond(r.getData().getDuration()); } else { vehiclePosition.setSecond(0); } } availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getSecond)).collect(Collectors.toList()); int size = tendencyTime; // 做比对的分数 double temp = availableVehiclesNearby.get(0).getSecond(); for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setTimeScore(vehiclePosition.getTimeScore() + size); if (temp != vehiclePosition.getSecond()) { size--; } } } // 电量分数 if (max.equals(tendencyElectricity)) { // 计算车的分数 分数最大是车的size availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getCurrentElectricity).reversed()).collect(Collectors.toList()); int size = tendencyElectricity; // 做比对的分数 int temp = availableVehiclesNearby.get(0).getCurrentElectricity(); int maxTemp = 0; for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setCurrentElectricityScore(vehiclePosition.getCurrentElectricityScore() + size); if (temp != vehiclePosition.getCurrentElectricity()) { size--; } else { maxTemp++; } } if (maxTemp > 1) { // 证明有最高相同电量的 找下一个 // 找出最第二大的值是那个 // 将四个值放入列表 List values = Arrays.asList(tendencyOrderValue, tendencyDistance, tendencyTime); // 降序排序 values.sort(Collections.reverseOrder()); // 获取第二大值 Integer secondMax = values.get(1); // 判断第二大的是哪个 if (Objects.equals(secondMax, tendencyDistance)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.parseDouble(split[0])); lonLatDto1.setLatitude(Double.parseDouble(split[1])); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); routeAndFareDto.setDestination(lonLatDto1); // 调用地图 获取时间 R r = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (r.getCode() == 200) { vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance())); } else { vehiclePosition.setDistance(0.0); } } availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList()); int size1 = tendencyDistance; // 做比对的分数 double temp1 = availableVehiclesNearby.get(0).getDistance(); for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setDistanceScore(vehiclePosition.getDistanceScore() + size1); if (temp1 != vehiclePosition.getDistance()) { size1--; } } } if (Objects.equals(secondMax, tendencyTime)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.parseDouble(split[0])); lonLatDto1.setLatitude(Double.parseDouble(split[1])); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); routeAndFareDto.setDestination(lonLatDto1); // 调用地图 获取时间 R r = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (r.getCode() == 200) { vehiclePosition.setSecond(r.getData().getDuration()); } else { vehiclePosition.setSecond(0); } } availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getSecond)).collect(Collectors.toList()); int size1 = tendencyTime; // 做比对的分数 double temp1 = availableVehiclesNearby.get(0).getSecond(); for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setTimeScore(vehiclePosition.getTimeScore() + size1); if (temp1 != vehiclePosition.getSecond()) { size1--; } } } // 订单价值 if (Objects.equals(secondMax, tendencyOrderValue)) { // 订单价值 // 时间差权重 Integer weightTimeDifference = xpTradingStrategy.getWeightTimeDifference(); // 距离差权重 Integer weightDistanceDifference = xpTradingStrategy.getWeightDistanceDifference(); // 距离权重 Integer weightDistance = xpTradingStrategy.getWeightDistance(); // 时间权重 Integer weightTime = xpTradingStrategy.getWeightTime(); // 电量权重 Integer weightElectricity = xpTradingStrategy.getWeightElectricity(); // 找出最大的值是那个 Integer max1 = Math.max(weightTimeDifference, Math.max(weightDistanceDifference, Math.max(weightDistance, Math.max(weightTime, weightElectricity)))); // 时间差 if (max1.equals(weightTimeDifference)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.valueOf(split[0])); lonLatDto1.setLatitude(Double.valueOf(split[1])); routeAndFareDto.setDestination(lonLatDto1); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); R distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (distanceAndDuration.getCode() == 200) { // 送驾- 接驾 Integer durationDifference = Integer.parseInt(duration) - distanceAndDuration.getData().getDuration(); vehiclePosition.setTimeDifference(durationDifference); } } } if (max1.equals(weightDistanceDifference)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.valueOf(split[0])); lonLatDto1.setLatitude(Double.valueOf(split[1])); routeAndFareDto.setDestination(lonLatDto1); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); R distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (distanceAndDuration.getCode() == 200) { // 送驾- 接驾 Integer distanceDifference = Integer.parseInt(distance) - distanceAndDuration.getData().getDistance(); vehiclePosition.setDistanceDifference(distanceDifference); } } } if (max1.equals(weightDistance)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.parseDouble(split[0])); lonLatDto1.setLatitude(Double.parseDouble(split[1])); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); routeAndFareDto.setDestination(lonLatDto1); // 调用地图 获取时间 R r = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (r.getCode() == 200) { vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance())); } else { vehiclePosition.setDistance(0.0); } } } if (max1.equals(weightTime)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); LonLatDto lonLatDto = new LonLatDto(); lonLatDto.setLongitude(vehiclePosition.getPoint().getX()); lonLatDto.setLatitude(vehiclePosition.getPoint().getY()); routeAndFareDto.setOrigin(lonLatDto); LonLatDto lonLatDto1 = new LonLatDto(); lonLatDto1.setLongitude(Double.parseDouble(split[0])); lonLatDto1.setLatitude(Double.parseDouble(split[1])); routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule)); routeAndFareDto.setDestination(lonLatDto1); // 调用地图 获取时间 R r = xpMapClient.getDistanceAndDuration(routeAndFareDto); if (r.getCode() == 200) { vehiclePosition.setSecond(r.getData().getDuration()); } else { vehiclePosition.setSecond(0); } } } if (max1.equals(weightElectricity)) { // 计算车的分数 分数最大是车的size availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getCurrentElectricity).reversed()).collect(Collectors.toList()); int size1 = tendencyElectricity; // 做比对的分数 int temp1 = availableVehiclesNearby.get(0).getCurrentElectricity(); for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setCurrentElectricityScore(vehiclePosition.getCurrentElectricityScore() + size1); if (temp1 != vehiclePosition.getCurrentElectricity()) { size1--; } } } // 算出总分 再来排序计算 for (VehiclePositionVo vehiclePositionVo : availableVehiclesNearby) { vehiclePositionVo.setOrderValueTotal(vehiclePositionVo.getCurrentElectricityScore() + vehiclePositionVo.getDistanceScore() + vehiclePositionVo.getTimeScore() + vehiclePositionVo.getDistanceDifference() + vehiclePositionVo.getTimeDifference()); } availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getOrderValueTotal).reversed()).collect(Collectors.toList()); int size2 = tendencyOrderValue; // 做比对的分数 double temp2 = availableVehiclesNearby.get(0).getOrderValueTotal(); for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { vehiclePosition.setValueScore(vehiclePosition.getValueScore() + size2); if (temp2 != vehiclePosition.getOrderValueTotal()) { size2--; } } } } } // 判断总分来计算 for (VehiclePositionVo vehiclePositionVo : availableVehiclesNearby) { vehiclePositionVo.setTotal(vehiclePositionVo.getCurrentElectricityScore() + vehiclePositionVo.getDistanceScore() + vehiclePositionVo.getTimeScore() + vehiclePositionVo.getValueScore()); } VehiclePositionVo vehiclePositionVo = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getTotal).reversed()).collect(Collectors.toList()).get(0); // // VehiclePositionVo vehiclePositionVo1 = vehiclePositionVo; RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePositionVo.getVin()); lock.lock(10, TimeUnit.SECONDS); log.info("队列 {} 车辆 {} 单号 {}", quoteName, vehiclePositionVo.getVin(), orderNo); try { // VehiclePosition vehiclePosition = vehiclePositionService.findByVehicleId(vehiclePositionVo.getVehicle_id()); R vehiclePositionR = xpVehicleClient.findByVehicleVin(vehiclePositionVo.getVin()); if (vehiclePositionR.getCode() != 200) { continue; } XpVehicle vehiclePosition = vehiclePositionR.getData(); log.info("符合条件的车辆 {} ,直接推单XPU。单号 {}", vehiclePosition.getPlateNumber(), orderNo); log.info("当前车辆状态 {} 单号 {}", vehiclePosition.getStatus(), orderNo); if (vehiclePosition.getStatus() != 1 || vehiclePosition.getState() != 0 || vehiclePosition.getVehicleType()==1) { continue; } // 关闭巡游单子 R stringR = xpCruiseOrderClient.updateCruiseOrder(vehiclePosition.getVehicleVin()); if(stringR ==null || stringR.getCode() != 200){ log.info("关闭巡游单子失败 车牌号 {}", vehiclePosition.getPlateNumber()); continue; } // 下发命令 PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setVin(vehiclePosition.getVehicleVin()); pushOrderDto.setOrderId(xpOrder.getId().toString()); pushOrderDto.setStartLatitude(xpOrder.getStartLat()); pushOrderDto.setStartLongitude(xpOrder.getStartLon()); pushOrderDto.setEndLatitude(xpOrder.getEndLat()); pushOrderDto.setEndLongitude(xpOrder.getEndLon()); pushOrderDto.setOrderType(OrderType.USER_ORDER); pushOrderDto.setStage(1); // 调用推送服务 orderId + carVin orderMissionClient.pushOrder(pushOrderDto); log.info("开始推送 {} 订单到XPU。单号 {}", xpOrder.getOrderNumber(), orderNo); redisService.popFirstElement(quoteName); log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName); return true; } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } else { // 直接派单 定义一个锁来锁定车辆 VehiclePosition vehiclePosition = positionList.get(0); String vehicleVin = vehiclePosition.getVin(); RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePosition.getVin()); lock.lock(10, TimeUnit.SECONDS); try { // 查询车辆状态 R vehicleR = xpVehicleClient.findByVehicleVin(vehicleVin); if (vehicleR.getCode() != 200) { continue; } XpVehicle vehicleId1 = vehicleR.getData(); log.info("附近只有一个车辆 {} ,直接推单XPU。单号 {}", vehicleId1.getPlateNumber(), orderNo); log.info("当前车辆状态 {} 运营状态 {} 单号 {}", vehicleId1.getOperatingStatus(), vehicleId1.getState(), orderNo); if (vehicleId1.getOperatingStatus() != 1 || vehicleId1.getState() != 0 || vehicleId1.getVehicleType()==1) { continue; } // 关闭巡游单子 R stringR = xpCruiseOrderClient.updateCruiseOrder(vehicleId1.getVehicleVin()); if(stringR ==null || stringR.getCode() != 200){ log.info("关闭巡游单子失败 车牌号 {}", vehicleId1.getPlateNumber()); continue; } PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setVin(vehiclePosition.getVin()); pushOrderDto.setOrderId(xpOrder.getId().toString()); pushOrderDto.setStartLatitude(xpOrder.getStartLat()); pushOrderDto.setStartLongitude(xpOrder.getStartLon()); pushOrderDto.setEndLatitude(xpOrder.getEndLat()); pushOrderDto.setEndLongitude(xpOrder.getEndLon()); pushOrderDto.setOrderType(OrderType.USER_ORDER); pushOrderDto.setStage(1); // 调用推送服务 orderId + carVin orderMissionClient.pushOrder(pushOrderDto); log.info("开始推送 {} 订单到XPU", xpOrder.getOrderNumber()); redisService.popFirstElement(quoteName); log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName); return true; } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } } } return false; } /** * 订单处理 * @param count 轮数 * @param uid * @param longitude 经度 * @param latitude 纬度 * @param orderNo 订单号 */ @SneakyThrows public void reassignPushOrder(int count, String uid, Double longitude, Double latitude, String orderNo) { System.out.println("进入推单环环节"); if (count == 0) { count = 1; } // 订单状态 R xpOrderR = xpOrderClient.queryOrderByOrderNo(orderNo); if (xpOrderR.getCode() != 200) { return; } if (xpOrderR.getData().getStatus() != 1) { return; } XpOrder data = xpOrderR.getData(); XpTradingStrategy xpTradingStrategy = xpTradingStrategyService.getOne(null); for (int i = 0; i < count; i++) { log.info("进入找车环节"); List positionList = vehiclePositionService.findAvailableVehiclesNearby(longitude, latitude, xpTradingStrategy.getOnePushDistance(), xpTradingStrategy.getSimultaneouslyOrderCount()); // 获取车辆的区域信息 if (positionList.isEmpty()) { continue; } // 直接派单 定义一个锁来锁定车辆 VehiclePosition vehiclePosition = positionList.get(0); String vehicleVin = vehiclePosition.getVin(); RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePosition.getVin()); lock.lock(10, TimeUnit.SECONDS); try { // 查询车辆状态 R vehicleR = xpVehicleClient.findByVehicleVin(vehicleVin); if (vehicleR.getCode() != 200) { continue; } XpVehicle vehicleId1 = vehicleR.getData(); if (vehicleId1.getStatus() != 1 || vehicleId1.getState() != 0) { lock.unlock(); continue; } // 关闭巡游单子 R stringR = xpCruiseOrderClient.updateCruiseOrder(vehicleId1.getVehicleVin()); if(stringR ==null || stringR.getData()==null){ log.info("关闭巡游单子失败"); continue; } PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setVin(vehiclePosition.getVin()); pushOrderDto.setOrderId(data.getId().toString()); pushOrderDto.setStartLatitude(data.getStartLat()); pushOrderDto.setStartLongitude(data.getStartLon()); pushOrderDto.setEndLatitude(data.getEndLat()); pushOrderDto.setEndLongitude(data.getEndLon()); pushOrderDto.setOrderType(OrderType.USER_ORDER); pushOrderDto.setStage(1); // 调用推送服务 orderId + carVin orderMissionClient.pushOrder(pushOrderDto); } catch (Exception e) { } finally { lock.unlock(); } } } }