package com.xiaopeng.operation.utils; import cn.hutool.core.bean.BeanUtil; import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto; import com.xiaopeng.api.feignClient.order.XpOrderClient; import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; import com.xiaopeng.api.model.operation.XpTradingStrategy; import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.redis.service.RedisService; 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 com.xiaopeng.operation.utils.map.FastDistanceCalculator; import com.xiaopeng.operation.vo.VehiclePositionVo; import org.redisson.Redisson; 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.Comparator; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Component public class TaskOrderUtil { @Resource private RedisService redisService; @Autowired private XpPointService xpPointService; @Autowired private IXpElectronicFenceAreaService xpElectronicFenceAreaService; @Autowired private XpOrderClient xpOrderClient; @Autowired private VehiclePositionService vehiclePositionService; @Autowired private IXpTradingStrategyService xpTradingStrategyService; @Autowired private UserVehicleClient userVehicleClient; @Autowired private RedissonClient redissonClient; // 自定义线程池 private static final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); static { threadPoolTaskExecutor.setCorePoolSize(5); threadPoolTaskExecutor.setMaxPoolSize(10); 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) { Object firstElement = redisService.getFirstElement(name); if (firstElement != null) { String[] split = firstElement.toString().split("_"); // 如果市未处理 创建新任务 if (split[2].equals("0")) { // 状态改为处理中 redisService.updateFirst(name, split[0] + "_" + split[1] + "_1"); threadPoolTaskExecutor.submit(() -> { orderProcess(name, firstElement.toString()); }); } } } } /** * 订单处理 * @param quoteName 队列名称 * @param firstElement 队列第一个元素 */ private void orderProcess(String quoteName, String firstElement) { 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[] split = lonLat.split(","); // 5轮找车辆 Integer onePushTime = xpTradingStrategy.getOnePushTime(); int count = onePushTime / 3; // 第一轮推单 processOrder(quoteName,count,uid,split,orderNo,xpTradingStrategy); // // for (int i = 0; i < count; i++) { // // 根据距离找车 // // 车多则根据配置找具体车数量 根据距离最近 // List availableVehiclesNearby = vehiclePositionService.findAvailableVehiclesNearby(Double.parseDouble(split[0]), Double.parseDouble(split[1]), one.getOnePushDistance(), one.getSimultaneouslyOrderCount()); // if (!availableVehiclesNearby.isEmpty()) { // if (availableVehiclesNearby.size() > 1) { // // 走权重 // } else { // // 直接派单 定义一个锁来锁定车辆 // VehiclePosition vehiclePosition = availableVehiclesNearby.get(0); // Long vehicleId = vehiclePosition.getVehicle_id(); // // 查询车辆状态 // VehiclePosition vehicleId1 = vehiclePositionService.findByVehicleId(vehicleId); // if (vehicleId1.getStatus() != 1 || vehicleId1.getState() != 0) { // continue; // } // if (vehiclePosition.getHasOrder() == 1) { // // 关闭巡游单子 TODO // } // // AddTaxiPassengerVo addTaxiPassengerVo = new AddTaxiPassengerVo(); // addTaxiPassengerVo.setVin(vehiclePosition.getVin()); // addTaxiPassengerVo.setUid(uid); // addTaxiPassengerVo.setOrderNo(orderNo); // // TODO // addTaxiPassengerVo.setAppId(""); // BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.addTaxiPassenger(addTaxiPassengerVo); // if (baseVehicleUserDto.getCode() == 200) { // redisService.popFirstElement(quoteName); // // } // } // // } // } // 第二轮推单 Integer twoPushTime = xpTradingStrategy.getTwoPushTime(); count = twoPushTime / 3; processOrder(quoteName,count,uid,split,orderNo,xpTradingStrategy); // 第三轮推单 Integer threePushTime = xpTradingStrategy.getThreePushTime(); count = threePushTime / 3; processOrder(quoteName,count,uid,split,orderNo,xpTradingStrategy); // 第四轮推单 Integer fourPushTime = xpTradingStrategy.getFourPushTime(); count = fourPushTime / 3; processOrder(quoteName,count,uid,split,orderNo,xpTradingStrategy); // 第五轮推单 Integer fivePushTime = xpTradingStrategy.getFivePushTime(); count = fivePushTime / 3; processOrder(quoteName,count,uid,split,orderNo,xpTradingStrategy); // 最终没找到车 redisService.popFirstElement(quoteName); // 取消订单 xpOrderClient.cancelOrder(orderId); } /** * 订单处理 * @param quoteName 队列名称 * @param count 轮数 * @param uid * @param split 经纬度 * @param orderNo 订单号 * @param xpTradingStrategy 规则 */ private void processOrder(String quoteName, int count, String uid, String[] split, String orderNo, XpTradingStrategy xpTradingStrategy) { for (int i = 0; i < count; i++) { // 根据距离找车 // 车多则根据配置找具体车数量 根据距离最近 List positionList = vehiclePositionService.findAvailableVehiclesNearby(Double.parseDouble(split[0]), Double.parseDouble(split[1]), xpTradingStrategy.getOnePushDistance(), xpTradingStrategy.getSimultaneouslyOrderCount()); List availableVehiclesNearby = BeanUtil.copyToList(positionList, VehiclePositionVo.class); if (!availableVehiclesNearby.isEmpty()) { if (availableVehiclesNearby.size() > 1) { // 走权重 // 订单价值 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)) { } if (max.equals(tendencyDistance)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { double v = FastDistanceCalculator.distanceFast(Double.parseDouble(split[1]), Double.parseDouble(split[0]), vehiclePosition.getPoint().getY(), vehiclePosition.getPoint().getX()); vehiclePosition.setDistance(v); } List positionVoList = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList()); int size = tendencyDistance; // 做比对的分数 double temp=positionVoList.get(0).getDistance(); for (VehiclePositionVo vehiclePosition : positionVoList) { vehiclePosition.setDistanceScore(vehiclePosition.getDistanceScore() + size); if(temp!=vehiclePosition.getDistance()){ size--; } } } if (max.equals(tendencyTime)) { for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) { // TODO 调用地图 获取时间 vehiclePosition.setSecond(1); } List positionVoList = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getSecond)).collect(Collectors.toList()); int size = tendencyTime; // 做比对的分数 double temp=positionVoList.get(0).getSecond(); for (VehiclePositionVo vehiclePosition : positionVoList) { vehiclePosition.setTimeScore(vehiclePosition.getTimeScore() + size); if(temp!=vehiclePosition.getSecond()){ size--; } } } if (max.equals(tendencyElectricity)) { // 计算车的分数 分数最大是车的size List list = availableVehiclesNearby.stream().peek(e -> e.setCurrentElectricity(0)).sorted(Comparator.comparing(VehiclePositionVo::getCurrentElectricity).reversed()).collect(Collectors.toList()); int size = tendencyElectricity; // 做比对的分数 int temp=list.get(0).getCurrentElectricity(); for (VehiclePositionVo vehiclePosition : list) { vehiclePosition.setCurrentElectricityScore(vehiclePosition.getCurrentElectricityScore() + size); if(temp!=vehiclePosition.getCurrentElectricity()){ size--; } } } // 判断总分来计算 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); // TODO 找到这个车锁车 VehiclePositionVo vehiclePositionVo1 =vehiclePositionVo; RLock lock = redissonClient.getLock("FIND_CAR_"+vehiclePositionVo1.getVin()); lock.lock(10, TimeUnit.SECONDS); try { VehiclePosition vehiclePosition= vehiclePositionService.findByVehicleId(vehiclePositionVo.getVehicle_id()); if (vehiclePosition.getStatus() != 1 || vehiclePosition.getState() != 0) { lock.unlock(); continue; } if (vehiclePosition.getHasOrder() == 1) { // 关闭巡游单子 TODO } AddTaxiPassengerVo addTaxiPassengerVo = new AddTaxiPassengerVo(); addTaxiPassengerVo.setVin(vehiclePosition.getVin()); addTaxiPassengerVo.setUid(uid); addTaxiPassengerVo.setOrderNo(orderNo); // TODO appid addTaxiPassengerVo.setAppId(""); BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.addTaxiPassenger(addTaxiPassengerVo); if (baseVehicleUserDto.getCode() == 200) { redisService.popFirstElement(quoteName); return; } }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } else { // 直接派单 定义一个锁来锁定车辆 VehiclePosition vehiclePosition = positionList.get(0); Long vehicleId = vehiclePosition.getVehicle_id(); // 查询车辆状态 VehiclePosition vehicleId1 = vehiclePositionService.findByVehicleId(vehicleId); if (vehicleId1.getStatus() != 1 || vehicleId1.getState() != 0) { continue; } if (vehiclePosition.getHasOrder() == 1) { // 关闭巡游单子 TODO } AddTaxiPassengerVo addTaxiPassengerVo = new AddTaxiPassengerVo(); addTaxiPassengerVo.setVin(vehiclePosition.getVin()); addTaxiPassengerVo.setUid(uid); addTaxiPassengerVo.setOrderNo(orderNo); // TODO appid addTaxiPassengerVo.setAppId(""); BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.addTaxiPassenger(addTaxiPassengerVo); if (baseVehicleUserDto.getCode() == 200) { redisService.popFirstElement(quoteName); return; } } } } } }