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<String> 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<VehiclePosition> 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<VehiclePosition> positionList = vehiclePositionService.findAvailableVehiclesNearby(Double.parseDouble(split[0]), Double.parseDouble(split[1]), xpTradingStrategy.getOnePushDistance(), xpTradingStrategy.getSimultaneouslyOrderCount());
|
List<VehiclePositionVo> 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<VehiclePositionVo> 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<VehiclePositionVo> 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<VehiclePositionVo> 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;
|
}
|
}
|
}
|
}
|
}
|
|
|
}
|