From c96fbe6b0aeb413a17c429133ee6d81d138144b9 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期二, 09 六月 2026 10:58:52 +0800
Subject: [PATCH] Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.0
---
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java | 1301 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 1,241 insertions(+), 60 deletions(-)
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
index b192bcc..27c5b4f 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -1,7 +1,10 @@
package com.xiaopeng.operation.utils;
import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
import com.xiaopeng.api.dto.map.RouteAndFareDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
@@ -16,30 +19,36 @@
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.operation.XpElectronicFence;
+import com.xiaopeng.api.model.operation.XpTargetedServiceVehicle;
import com.xiaopeng.api.model.operation.XpTradingStrategy;
+import com.xiaopeng.api.model.operation.XpTradingStrategyPush;
+import com.xiaopeng.api.model.order.XpCruiseOrder;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.order.XpOrderReassign;
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.automaticPilot.protobuf.TaskActionType;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.api.vo.operation.VehiclePositionVo;
+import com.xiaopeng.api.vo.operation.XpTargetedServiceVehicleVo;
import com.xiaopeng.api.vo.operation.XpTradingStrategyDetailVO;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.constant.Constants;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
+import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
+import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.operation.config.UidVinBindingConfig;
import com.xiaopeng.operation.dto.PriorityMatchResult;
import com.xiaopeng.operation.mapper.XpElectronicFenceMapper;
-import com.xiaopeng.operation.service.IXpElectronicFenceAreaService;
-import com.xiaopeng.operation.service.IXpTradingStrategyService;
-import com.xiaopeng.operation.service.UidVinPriorityMatcher;
-import com.xiaopeng.operation.service.XpPointService;
+import com.xiaopeng.operation.service.*;
import com.xiaopeng.operation.utils.mango.VehiclePositionService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.mongodb.core.MongoTemplate;
@@ -51,6 +60,8 @@
import javax.annotation.Resource;
import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
@@ -60,7 +71,11 @@
@Slf4j
@Component
public class TaskOrderUtil {
+ @Resource
+ private XpTargetedServiceService xpTargetedServiceService;
+ @Resource
+ private XpTargetedServiceVehicleService xpTargetedServiceVehicleService;
@Resource
private RedisService redisService;
@@ -79,6 +94,9 @@
@Resource
private IXpTradingStrategyService xpTradingStrategyService;
+
+ @Resource
+ private IXpTradingStrategyPushService xpTradingStrategyPushService;
@Resource
private XpCruiseOrderClient xpCruiseOrderClient;
@@ -112,6 +130,9 @@
@Resource
private XpAppUserCouponClient xpAppUserCouponClient;
+ @Resource
+ private OfficialPartnerUtil officialPartnerUtil;
+
// 自定义线程池
private static final ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
@@ -129,6 +150,7 @@
/**
* 5秒执行一次
+ * 播单 在下单的时候会存一个 redis 队列
*/
@Scheduled(cron = "0/5 * * * * ?")
public void taskOrder() {
@@ -144,8 +166,54 @@
// 状态改为处理中
redisService.updateFirst(name, value);
threadPoolTaskExecutor.submit(() -> {
- orderProcess(name, firstElement.toString());
+ log.info("订单处理:{}", firstElement);
+ orderProcess(name, firstElement.toString(), false);
});
+ }else{
+ //判断订单状态,如果不是待接单,则将数据清除
+ String orderId = split[0];
+ XpOrder xpOrder = xpOrderClient.queryOrderById(Long.valueOf(orderId)).getData();
+ if(xpOrder.getStatus() != OrderStatusEnum.PENDING_ORDER.getCode()){
+ if(StringUtils.isNotEmpty((xpOrder.getQueueName()))){
+ redisService.removeByPattern(xpOrder.getQueueName(), xpOrder.getOrderNumber());
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ /**
+ * 定向订单
+ */
+ @Scheduled(cron = "0/5 * * * * ?")
+ public void taskOrder_targeted() {
+ System.out.println("5秒执行一次");
+ Set<String> quoteMatchName = redisService.getQuoteMatchName(CacheConstants.SP_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] + "_" + split[8];
+ // 状态改为处理中
+ redisService.updateFirst(name, value);
+ threadPoolTaskExecutor.submit(() -> {
+ log.info("定向订单处理:{}", firstElement);
+ orderProcess(name, firstElement.toString(), true);
+ });
+ }else{
+ //判断订单状态,如果不是待接单,则将数据清除
+ String orderId = split[0];
+ XpOrder xpOrder = xpOrderClient.queryOrderById(Long.valueOf(orderId)).getData();
+ if(xpOrder.getStatus() != OrderStatusEnum.PENDING_ORDER.getCode()){
+ if(StringUtils.isNotEmpty(xpOrder.getQueueName())){
+ redisService.removeByPattern(xpOrder.getQueueName(), xpOrder.getOrderNumber());
+ }
+ }
+
}
}
}
@@ -157,7 +225,7 @@
* @param quoteName 队列名称
* @param firstElement 队列第一个元素
*/
- private void orderProcess(String quoteName, String firstElement) {
+ private void orderProcess(String quoteName, String firstElement, Boolean isTargetedService) {
XpTradingStrategy xpTradingStrategy = xpTradingStrategyService.getOne(null);
String orderId = firstElement.split("_")[0];
String lonLat = firstElement.split("_")[1];
@@ -173,58 +241,68 @@
// 经纬度
String[] split = lonLat.split(",");
+ //查询当前时段是不是特殊推单时段
+ List<XpTradingStrategyPush> tradingStrategyId = xpTradingStrategyPushService.list(new QueryWrapper<XpTradingStrategyPush>().eq("trading_strategy_id", xpTradingStrategy));
+ long now = Long.parseLong(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmm")));
+ XpTradingStrategyPush xpTradingStrategyPush = tradingStrategyId.stream().filter(item -> {
+ long start = Long.parseLong(item.getStartTime().replace(":", ""));
+ long end = Long.parseLong(item.getEndTime().replace(":", ""));
+ return now >= start && now < end;
+ }).findFirst().orElse(null);
+
+
// 5轮找车辆
//每次查找车辆推单后的等待秒数
int sleepTime = 3;
- Integer onePushTime = xpTradingStrategy.getOnePushTime();
- Double onePushDistance = xpTradingStrategy.getOnePushDistance();
+ Integer onePushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getOnePushTime() : xpTradingStrategy.getOnePushTime();
+ Double onePushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getOnePushDistance() : xpTradingStrategy.getOnePushDistance();
int count = onePushTime / sleepTime;
// 第一轮推单
log.info("开始第一轮推单 {}", orderNo);
- Boolean processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, onePushDistance, distance, duration, planRule);
+ Boolean processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, onePushDistance, distance, duration, planRule, isTargetedService);
if(processed){
log.info("订单推送成功 {}", orderNo);
return;
}
// 第二轮推单
- Integer twoPushTime = xpTradingStrategy.getTwoPushTime();
- Double twoPushDistance = xpTradingStrategy.getTwoPushDistance();
+ Integer twoPushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getTwoPushTime() : xpTradingStrategy.getTwoPushTime();
+ Double twoPushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getTwoPushDistance() : xpTradingStrategy.getTwoPushDistance();
count = twoPushTime / sleepTime;
log.info("开始第二轮推单 {}", orderNo);
- processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, twoPushDistance, distance, duration, planRule);
+ processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, twoPushDistance, distance, duration, planRule, isTargetedService);
if(processed){
log.info("订单推送成功 {}", orderNo);
return;
}
// 第三轮推单
- Integer threePushTime = xpTradingStrategy.getThreePushTime();
- Double threePushDistance = xpTradingStrategy.getThreePushDistance();
+ Integer threePushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getThreePushTime() : xpTradingStrategy.getThreePushTime();
+ Double threePushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getThreePushDistance() : xpTradingStrategy.getThreePushDistance();
count = threePushTime / sleepTime;
log.info("开始第三轮推单 {}", orderNo);
- processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, threePushDistance, distance, duration, planRule);
+ processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, threePushDistance, distance, duration, planRule, isTargetedService);
if(processed){
log.info("订单推送成功 {}", orderNo);
return;
}
// 第四轮推单
- Integer fourPushTime = xpTradingStrategy.getFourPushTime();
- Double fourPushDistance = xpTradingStrategy.getFourPushDistance();
+ Integer fourPushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getFourPushTime() : xpTradingStrategy.getFourPushTime();
+ Double fourPushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getFourPushDistance() : xpTradingStrategy.getFourPushDistance();
count = fourPushTime / sleepTime;
log.info("开始第四轮推单 {}", orderNo);
- processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fourPushDistance, distance, duration, planRule);
+ processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fourPushDistance, distance, duration, planRule, isTargetedService);
if(processed){
log.info("订单推送成功 {}", orderNo);
return;
}
// 第五轮推单
- Integer fivePushTime = xpTradingStrategy.getFivePushTime();
- Double fivePushDistance = xpTradingStrategy.getFivePushDistance();
+ Integer fivePushTime = null != xpTradingStrategyPush ? xpTradingStrategyPush.getFivePushTime() : xpTradingStrategy.getFivePushTime();
+ Double fivePushDistance = null != xpTradingStrategyPush ? xpTradingStrategyPush.getFivePushDistance() : xpTradingStrategy.getFivePushDistance();
count = fivePushTime / sleepTime;
log.info("开始第五轮推单 {}", orderNo);
- processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fivePushDistance, distance, duration, planRule);
+ processed = processPushOrder(quoteName, count, sleepTime, uid, split, orderNo, xpTradingStrategy, fivePushDistance, distance, duration, planRule, isTargetedService);
if(processed){
log.info("订单推送成功 {}", orderNo);
return;
@@ -235,8 +313,8 @@
if (xpOrderR.getCode() == 200) {
XpOrder xpOrder = xpOrderR.getData();
if (xpOrder.getStatus() == 1) {
- log.info("五轮推单结束,无车辆接单,执行取消订单 {}", orderNo);
xpOrderClient.cancelOrder(orderId);
+ log.info("五轮推单结束,无车辆接单,执行取消订单 {}", orderNo);
//推送订单状态给乘客
SendMessageDTO dto = new SendMessageDTO();
dto.setAppUserId(xpOrder.getAppUserId().toString());
@@ -260,9 +338,6 @@
}
});
}
- //将订单从队列中移除
- log.info("五轮推单结束,无车辆接单,执行队列移除订单 {}", orderNo);
- redisService.popFirstElement(quoteName);
}
}
@@ -279,7 +354,7 @@
* @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) {
+ 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, Boolean isTargetedService) {
log.info("进入推单环节 单号 {}", orderNo);
if (count == 0) {
count = 1;
@@ -294,7 +369,1018 @@
}
XpOrder xpOrder = xpOrderR.getData();
if (xpOrder.getStatus() == 0) {
- redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+ log.info("订单已取消,退出退单逻辑 {}", orderNo);
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+ }
+ return true;
+ }
+
+ // 找出围栏id
+ Long xpElectronicFenceAreaId = xpOrder.getXpElectronicFenceAreaId();
+ Long electronicId = xpElectronicFenceAreaService.getById(xpElectronicFenceAreaId).getElectronicId();
+ XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(electronicId);
+
+ // ===== 新增:UID-VIN 优先匹配(仅 enabled=true 时生效)=====
+ log.info("[人车订单绑定测试] >>>>>> 进入优先匹配判断, uid={}, orderNo={}, 围栏区域ID={}", uid, orderNo, xpElectronicFenceAreaId);
+ if (uidVinBindingConfig.isEnabled()) {
+ log.info("[人车订单绑定测试] 总开关已开启, 开始执行优先匹配逻辑, uid={}, orderNo={}", uid, orderNo);
+ try {
+ PriorityMatchResult priorityResult = uidVinPriorityMatcher.tryPriorityMatch(uid, orderNo, String.valueOf(xpElectronicFenceAreaId));
+ log.info("[人车订单绑定测试] 优先匹配结果: matched={}, vin={}, failReason={}, uid={}, orderNo={}",
+ priorityResult != null ? priorityResult.isMatched() : "null",
+ priorityResult != null ? priorityResult.getVin() : "null",
+ priorityResult != null ? priorityResult.getFailReason() : "null",
+ uid, orderNo);
+ if (priorityResult != null && priorityResult.isMatched()) {
+ String priorityVin = priorityResult.getVin();
+ log.info("[人车订单绑定测试] 匹配成功, 准备获取分布式锁, lockKey=FIND_CAR_{}, orderNo={}", priorityVin, orderNo);
+ RLock priorityLock = redissonClient.getLock("FIND_CAR_" + priorityVin);
+ priorityLock.lock(10, TimeUnit.SECONDS);
+ log.info("[人车订单绑定测试] 分布式锁获取成功, vin={}, orderNo={}", priorityVin, orderNo);
+ try {
+ // 二次校验车辆状态
+ log.info("[人车订单绑定测试] 开始二次校验车辆状态, vin={}, orderNo={}", priorityVin, orderNo);
+ R<XpVehicle> vehicleR = xpVehicleClient.findByVehicleVin(priorityVin);
+ log.info("[人车订单绑定测试] 二次校验-车辆查询结果: code={}, hasData={}, vin={}", vehicleR.getCode(), vehicleR.getData() != null, priorityVin);
+ if (vehicleR.getCode() == 200 && vehicleR.getData() != null) {
+ XpVehicle vehicle = vehicleR.getData();
+ //判断当前车辆是否在禁派单车辆内
+ String cacheList = redisService.getCacheObject("CAN_NOT_RECEIVE_ORDER_VEHICLE:" + xpOrder.getId());
+ List<String> strings = new ArrayList<>();
+ if(null != cacheList){
+ strings = JSON.parseArray(cacheList, String.class);
+ }
+ log.info("[人车订单绑定测试] 二次校验-车辆状态: operatingStatus={}, state={}, vehicleType={}, vin={}",
+ vehicle.getOperatingStatus(), vehicle.getState(), vehicle.getVehicleType(), priorityVin);
+ if (vehicle.getOperatingStatus() == 1 && vehicle.getState() == 0 && vehicle.getVehicleType() != 1 && !strings.contains(vehicle.getVehicleVin())) {
+ log.info("[人车订单绑定测试] 二次校验-车辆状态通过(空闲), 开始校验订单状态, orderNo={}", orderNo);
+ // 二次校验订单状态
+ R<XpOrder> orderCheck = xpOrderClient.queryOrderByOrderNo(orderNo);
+ log.info("[人车订单绑定测试] 二次校验-订单查询结果: code={}, status={}, orderNo={}",
+ orderCheck.getCode(),
+ orderCheck.getData() != null ? orderCheck.getData().getStatus() : "null",
+ orderNo);
+ if (orderCheck.getCode() == 200 && orderCheck.getData() != null && orderCheck.getData().getStatus() == 1) {
+ log.info("[人车订单绑定测试] 二次校验全部通过, 开始关闭巡游单, vin={}, orderNo={}", priorityVin, orderNo);
+ // 关闭巡游单
+ R stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(priorityVin);
+ log.info("[人车订单绑定测试] 关闭巡游单结果: code={}, vin={}, orderNo={}",
+ stringR != null ? stringR.getCode() : "null", priorityVin, orderNo);
+ if (stringR != null && stringR.getCode() == 200) {
+ log.info("[人车订单绑定测试] 关闭巡游单成功, 开始下发XPU命令, vin={}, orderNo={}", priorityVin, orderNo);
+ // 下发XPU命令
+ PushOrderDto pushOrderDto = new PushOrderDto();
+ pushOrderDto.setVin(priorityVin);
+ pushOrderDto.setOrderId(orderCheck.getData().getId().toString());
+ pushOrderDto.setStartTaskId(orderCheck.getData().getXpuStartTaskId());
+ pushOrderDto.setEndTaskId(orderCheck.getData().getXpuEndTaskId());
+ pushOrderDto.setStartWaypointId(orderCheck.getData().getStartPointId());
+ pushOrderDto.setEndWaypointId(orderCheck.getData().getEndPointId());
+ pushOrderDto.setStartLatitude(orderCheck.getData().getStartLat());
+ pushOrderDto.setStartLongitude(orderCheck.getData().getStartLon());
+ pushOrderDto.setEndLatitude(orderCheck.getData().getEndLat());
+ pushOrderDto.setEndLongitude(orderCheck.getData().getEndLon());
+ pushOrderDto.setEndPoiName(orderCheck.getData().getEndPointName());
+ pushOrderDto.setOrderType(OrderType.USER_ORDER);
+ pushOrderDto.setStage(1);
+ log.info("[人车订单绑定测试] XPU推单参数: vin={}, orderId={}, startLat={}, startLon={}, endLat={}, endLon={}, orderNo={}",
+ priorityVin, orderCheck.getData().getId(), orderCheck.getData().getStartLat(), orderCheck.getData().getStartLon(),
+ orderCheck.getData().getEndLat(), orderCheck.getData().getEndLon(), orderNo);
+ orderMissionClient.pushOrder(pushOrderDto);
+ log.info("[人车订单绑定测试] ====== 派单成功! uid={}, vin={}, orderNo={}, 从队列移除订单 ======", uid, priorityVin, orderNo);
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName, orderNo);
+ }
+
+ return true;
+ } else {
+ log.info("[人车订单绑定测试] 关闭巡游单失败, 回退常规流程, vin={}, orderNo={}", priorityVin, orderNo);
+ }
+ } else {
+ log.info("[人车订单绑定测试] 二次校验-订单状态不满足(非待派单), 回退常规流程, orderNo={}", orderNo);
+ }
+ } else {
+ if (vehicle.getState() != 0) {
+ log.info("[人车订单绑定测试] 二次校验-车辆已接单(state={}), 当前有未完成订单, 无法指派, vin={}, plateNumber={}, orderNo={}",
+ vehicle.getState(), priorityVin, vehicle.getPlateNumber(), orderNo);
+ } else {
+ log.info("[人车订单绑定测试] 二次校验-车辆状态不满足, 回退常规流程, vin={}, operatingStatus={}, state={}, vehicleType={}",
+ priorityVin, vehicle.getOperatingStatus(), vehicle.getState(), vehicle.getVehicleType());
+ }
+ }
+ } else {
+ log.info("[人车订单绑定测试] 二次校验-车辆查询失败, 回退常规流程, vin={}, code={}", priorityVin, vehicleR.getCode());
+ }
+ } catch (Exception e) {
+ log.error("[人车订单绑定测试] 锁内执行异常,回退常规流程, uid={}, vin={}, orderNo={}", uid, priorityVin, orderNo, e);
+ } finally {
+ priorityLock.unlock();
+ log.info("[人车订单绑定测试] 分布式锁已释放, vin={}, orderNo={}", priorityVin, orderNo);
+ }
+ } else {
+ log.info("[人车订单绑定测试] 优先匹配未命中, 进入常规流程, uid={}, orderNo={}", uid, orderNo);
+ }
+ } catch (Exception e) {
+ log.error("[人车订单绑定测试] 优先匹配过程异常,回退常规流程, uid={}, orderNo={}", uid, orderNo, e);
+ }
+ } else {
+ log.info("[人车订单绑定测试] 总开关未开启(enabled=false), 跳过优先匹配, uid={}, orderNo={}", uid, orderNo);
+ }
+ // ===== 新增结束 =====
+
+ for (int i = 0; i < count; i++) {
+ //等到sleepTime秒钟
+ Thread.sleep(sleepTime * 1000);
+ // 根据距离找车
+ // 车多则根据配置找具体车数量 根据距离最近
+ // 更改 暂不限制数量
+ List<VehiclePosition> positionList = vehiclePositionService.findAvailableVehiclesNearby(Double.parseDouble(split[0]), Double.parseDouble(split[1]), pushDistance, xpTradingStrategy.getSimultaneouslyOrderCount());
+ log.info("根据距离找车 {} 距离 {}KM 经度 {} 维度 {} 查找结果 {} 单号 {}", orderNo, pushDistance, split[0], split[1], JSON.toJSONString(positionList), orderNo);
+ // 获取车辆的区域信息
+ if (positionList.isEmpty()) {
+ continue;
+ }
+ Set<String> vinList = positionList.stream().map(VehiclePosition::getVin).collect(Collectors.toSet());
+
+ //判断当前车辆是否在禁派单车辆内
+ String cacheList = redisService.getCacheObject("CAN_NOT_RECEIVE_ORDER_VEHICLE:" + xpOrder.getId());
+ if(Objects.nonNull(cacheList)){
+ List<String> strings = JSON.parseArray(cacheList, String.class);
+ Set<String> vins = new HashSet<>();
+ for (String s : vinList) {
+ if (!strings.contains(s)) {
+ vins.add(s);
+ }
+ }
+ vinList = vins;
+ }
+
+ // 获取车辆的信息 筛选出可用车辆,定向服务的车辆排除
+ R<List<String>> vehiclePositionVos = xpVehicleClient.queryVehiclePositionByVin(new VehiclePositionByVinDto(xpElectronicFence.getId(), vinList, xpTradingStrategy.getSimultaneouslyOrderCount()));
+ log.info("筛选可用车辆结果 {} 单号 {}", JSON.toJSONString(vehiclePositionVos), orderNo);
+ List<String> vehicleVinByTargetedService = xpTargetedServiceVehicleService.getVehicleVinByTargetedService(xpOrderR.getData().getCityCode());
+ if(!isTargetedService){
+ vehiclePositionVos.getData().removeAll(vehicleVinByTargetedService);
+ log.info("剔除定向服务车辆后的结果 {} 单号 {}", JSON.toJSONString(vehiclePositionVos), orderNo);
+ }else{
+ vehiclePositionVos.setData(vehicleVinByTargetedService);
+ log.info("查找定向服务车辆后的结果 {} 单号 {}", JSON.toJSONString(vehiclePositionVos), orderNo);
+ }
+ if (vehiclePositionVos.getCode() != 200) {
+ continue;
+ }
+ List<VehiclePositionVo> availableVehiclesNearby = BeanUtil.copyToList(positionList, VehiclePositionVo.class);
+ List<String> data = vehiclePositionVos.getData();
+
+ // 找出符合条件的
+ availableVehiclesNearby = availableVehiclesNearby.stream().filter(e -> data.contains(e.getVin())).collect(Collectors.toList());
+
+ if (!availableVehiclesNearby.isEmpty()) {
+ if (availableVehiclesNearby.size() > 1) {
+ log.info("附近有 {} 辆车,进入权重判断流程 单号 {}", availableVehiclesNearby.size(), orderNo);
+ // 走权重
+
+ // 订单价值
+ Integer tendencyOrderValue = xpTradingStrategy.getTendencyOrderValue();
+
+ // 距离价值
+ Integer tendencyDistance = xpTradingStrategy.getTendencyDistance();
+
+ // 时间价值
+ Integer tendencyTime = xpTradingStrategy.getTendencyTime();
+
+ try {
+
+ // 电量价值
+ 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);
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ R<RouteVo> 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);
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+ if (distanceAndDuration.getCode() == 200) {
+ // 送驾- 接驾
+ Integer distanceDifference = Integer.parseInt(distance) - distanceAndDuration.getData().getDistance();
+ vehiclePosition.setDistanceDifference(distanceDifference);
+ }
+ }
+
+ }
+
+ if (max1.equals(weightDistance)) {
+ log.info("车子距离~~");
+ 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]));
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ routeAndFareDto.setDestination(lonLatDto1);
+ // 调用地图 获取时间
+ R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+ if (r.getCode() == 200) {
+ log.info("车子距离~~{},{},{}",vehiclePosition.getVin(),r.getData().getDistance(),orderNo);
+ vehiclePosition.setDistance(Double.valueOf(r.getData().getDistance()));
+ } else {
+ vehiclePosition.setDistance(0.0);
+ }
+
+ }
+
+ // 分数计算 把时间短的分数调高
+ availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList());
+ double score = 10;
+ for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+ vehiclePosition.setDistance(score);
+ score--;
+ }
+
+ }
+
+ 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]));
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ routeAndFareDto.setDestination(lonLatDto1);
+ // 调用地图 获取时间
+ R<RouteVo> 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 score = 10;
+ for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+ vehiclePosition.setSecond(score);
+ score--;
+ }
+
+ }
+
+ 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()+vehiclePositionVo.getSecond()+vehiclePositionVo.getDistance().intValue());
+ }
+ 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)) {
+ log.info("车子距离~~");
+ 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]));
+
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ routeAndFareDto.setDestination(lonLatDto1);
+ // 调用地图 获取时间
+ R<RouteVo> r = xpMapClient.getDistanceAndDuration(routeAndFareDto);
+ if (r.getCode() == 200) {
+ log.info("车子距离~~{},{},{}",vehiclePosition.getVin(),r.getData().getDistance(),orderNo);
+ 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--;
+// }
+// }
+
+ // 分数计算 把时间短的分数调高
+ availableVehiclesNearby = availableVehiclesNearby.stream().sorted(Comparator.comparing(VehiclePositionVo::getDistance)).collect(Collectors.toList());
+ int score = 10;
+ for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+ vehiclePosition.setDistanceScore(score);
+ score--;
+ }
+ }
+
+
+ // 时间分数
+ 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]));
+
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ routeAndFareDto.setDestination(lonLatDto1);
+ // 调用地图 获取时间
+ R<RouteVo> 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 score = 10;
+ for (VehiclePositionVo vehiclePosition : availableVehiclesNearby) {
+ vehiclePosition.setTimeScore(score);
+ score--;
+ }
+// 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<Integer> 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]));
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ routeAndFareDto.setDestination(lonLatDto1);
+ // 调用地图 获取时间
+ R<RouteVo> 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]));
+
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ routeAndFareDto.setDestination(lonLatDto1);
+ // 调用地图 获取时间
+ R<RouteVo> 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);
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ R<RouteVo> 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);
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ R<RouteVo> 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]));
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ routeAndFareDto.setDestination(lonLatDto1);
+ // 调用地图 获取时间
+ R<RouteVo> 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]));
+ if(planRule!=null&& !"null".equals(planRule)){
+ routeAndFareDto.setRoutePlanRule(Integer.valueOf(planRule));
+ }
+ routeAndFareDto.setDestination(lonLatDto1);
+ // 调用地图 获取时间
+ R<RouteVo> 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()+vehiclePositionVo.getSecond()+vehiclePositionVo.getDistance().intValue());
+ }
+ 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--;
+ }
+ }
+
+ }
+ }
+
+
+ } catch (Exception e) {
+ log.error("异常", e);
+ }
+
+ // 判断总分来计算
+ 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);
+
+ RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePositionVo.getVin());
+ lock.lock(10, TimeUnit.SECONDS);
+ log.info("队列 {} 车辆 {} 单号 {}", quoteName, vehiclePositionVo.getVin(), orderNo);
+ try {
+ R<XpVehicle> vehiclePositionR = xpVehicleClient.findByVehicleVin(vehiclePositionVo.getVin());
+ if (vehiclePositionR.getCode() == 200) {
+ XpVehicle vehiclePosition = vehiclePositionR.getData();
+ log.info("符合条件的车辆 {} ,直接推单XPU。单号 {}", vehiclePosition.getPlateNumber(), orderNo);
+ log.info("当前车辆状态 {} 单号 {}", vehiclePosition.getState(), orderNo);
+
+ String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehiclePosition.getVehicleVin());
+ // 再次查询一下订单 看是否取消
+ xpOrder = xpOrderClient.queryOrderByOrderNo(orderNo).getData();
+ if (xpOrder.getStatus() == 1) {
+ //所有条件满足,走正常派单,不满足走后面的连环派单
+ if (vehiclePosition.getOperatingStatus() == 1 && vehiclePosition.getState() == 0 && vehiclePosition.getVehicleType() == 2) {
+ //非合作商的车辆需要处理巡游单
+ if(null == vehiclePosition.getOfficialPartnerId()){
+ // 关闭巡游单子
+ R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vin);
+ if (stringR != null && stringR.getCode() == 200) {
+ log.info("关闭巡游单成功 {} {}", vehiclePosition.getPlateNumber(), orderNo);
+ XpCruiseOrder cruiseOrder = stringR.getData();
+ // 下发命令
+ PushOrderDto pushOrderDto = new PushOrderDto();
+ pushOrderDto.setVin(vin);
+ pushOrderDto.setOrderId(xpOrder.getId().toString());
+ pushOrderDto.setStartTaskId(xpOrder.getXpuStartTaskId());
+ pushOrderDto.setEndTaskId(xpOrder.getXpuEndTaskId());
+ pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+ pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
+ pushOrderDto.setStartLatitude(xpOrder.getStartLat());
+ pushOrderDto.setStartLongitude(xpOrder.getStartLon());
+ pushOrderDto.setEndLatitude(xpOrder.getEndLat());
+ pushOrderDto.setEndLongitude(xpOrder.getEndLon());
+ pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
+ pushOrderDto.setOrderType(OrderType.USER_ORDER);
+ pushOrderDto.setStage(1);
+ if(null != cruiseOrder){
+ pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+ pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+ }
+ pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
+ // 调用推送服务 orderId + carVin
+ orderMissionClient.pushOrder(pushOrderDto);
+ log.info("开始推送 {} 订单到XPU。单号 {}", xpOrder.getOrderNumber(), orderNo);
+ }
+ }else {
+ //流量接入-接单推送 合作商的车辆需要调用合作商的订单通知接口
+ officialPartnerUtil.pushNewOrder(vehiclePosition.getOfficialPartnerId(), xpOrder);
+ }
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+ }
+
+ log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
+ return true;
+ }
+ }
+
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ lock.unlock();
+ }
+
+ } else {
+ // 直接派单 定义一个锁来锁定车辆
+ VehiclePositionVo vehiclePosition = availableVehiclesNearby.get(0);
+ String vehicleVin = vehiclePosition.getVin();
+
+ RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePosition.getVin());
+ lock.lock(10, TimeUnit.SECONDS);
+ try {
+ // 查询车辆状态
+ R<XpVehicle> vehicleR = xpVehicleClient.findByVehicleVin(vehicleVin);
+ if (vehicleR.getCode() == 200) {
+ XpVehicle vehicleId1 = vehicleR.getData();
+ log.info("附近只有一个车辆 {} ,直接推单XPU。单号 {}", vehicleId1.getPlateNumber(), orderNo);
+ log.info("当前车辆状态 运营状态 {} 单号 {}", vehicleId1.getState(), orderNo);
+
+ // 再次查询一下订单 看是否取消
+ xpOrder = xpOrderClient.queryOrderByOrderNo(orderNo).getData();
+ if (xpOrder.getStatus() == 1) {
+ // 所有条件满足走正常派单,不满足走循环派单
+ if (vehicleId1.getOperatingStatus() == 1 && vehicleId1.getState() == 0 && vehicleId1.getVehicleType() == 2) {
+ if(null == vehicleId1.getOfficialPartnerId()){
+ // 关闭巡游单子
+ String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehicleId1.getVehicleVin());
+ R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vin);
+ if (stringR != null && stringR.getCode() == 200) {
+ log.info("关闭巡游单成功 {} {}", vehicleId1.getPlateNumber(), orderNo);
+ XpCruiseOrder cruiseOrder = stringR.getData();
+ PushOrderDto pushOrderDto = new PushOrderDto();
+ pushOrderDto.setVin(vehiclePosition.getVin());
+ pushOrderDto.setOrderId(xpOrder.getId().toString());
+ pushOrderDto.setStartTaskId(xpOrder.getXpuStartTaskId());
+ pushOrderDto.setEndTaskId(xpOrder.getXpuEndTaskId());
+ pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+ pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
+ pushOrderDto.setStartLatitude(xpOrder.getStartLat());
+ pushOrderDto.setStartLongitude(xpOrder.getStartLon());
+ pushOrderDto.setEndLatitude(xpOrder.getEndLat());
+ pushOrderDto.setEndLongitude(xpOrder.getEndLon());
+ pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
+ pushOrderDto.setOrderType(OrderType.USER_ORDER);
+ pushOrderDto.setStage(1);
+ if(null != cruiseOrder){
+ pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+ pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+ }
+ pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
+ // 调用推送服务 orderId + carVin
+ orderMissionClient.pushOrder(pushOrderDto);
+ }
+ }else {
+ //流量接入-接单推送 合作商的车辆需要调用合作商的订单通知接口
+ officialPartnerUtil.pushNewOrder(vehicleId1.getOfficialPartnerId(), xpOrder);
+ }
+ log.info("开始推送 {} 订单到XPU", xpOrder.getOrderNumber());
+
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+ }
+
+ log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
+ return true;
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+
+ log.info("没有找到空闲车辆 {},尝试连环派单给即将服务结束的车辆", orderNo);
+ // 查询状态为1的车辆vin
+ R<List<String>> servingVehicles = xpVehicleClient.queryVehiclePositionByVin(new VehiclePositionByVinDto(xpElectronicFence.getId(), vinList, xpTradingStrategy.getSimultaneouslyOrderCount(),1));
+ if (servingVehicles.getCode() != 200) {
+ continue;
+ }
+ log.info("连环派单查询车辆结果 {} {}", orderNo, JSON.toJSONString(servingVehicles.getData()));
+ if(!isTargetedService){
+ servingVehicles.getData().removeAll(vehicleVinByTargetedService);
+ log.info("连环派单剔除定向服务车辆后的结果 {} 单号 {}", JSON.toJSONString(servingVehicles), orderNo);
+ }else{
+ servingVehicles.setData(vehicleVinByTargetedService);
+ log.info("连环派单查找定向服务车辆后的结果 {} 单号 {}", JSON.toJSONString(servingVehicles), orderNo);
+ }
+
+ XpTradingStrategyDetailVO strategyDetailVO = tradingStrategyClient.queryById().getData();
+ log.info("连环排查推单逻辑 {} {}", orderNo, JSON.toJSONString(strategyDetailVO));
+ Integer distanceRegardAsEnding = strategyDetailVO.getDistanceRegardAsEnding();
+ Integer timeRegardAsEnding = strategyDetailVO.getTimeRegardAsEnding();
+
+ Integer backupPower = strategyDetailVO.getBackupPower();
+ Integer destToPassenger = strategyDetailVO.getDestToPassenger();
+ Integer endingTimeToUseTime = strategyDetailVO.getEndingTimeToUseTime();
+
+ for (String vin : servingVehicles.getData()) {
+ VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class);
+ if(null == vehiclePosition){
+ log.info("连环派单 {} 车辆查询定位数据失败 {}", vin, orderNo);
+ continue;
+ }
+ XpOrder xpOrder1 = xpOrderClient.queryOrderById(vehiclePosition.getOrderId()).getData();
+ String json = redisService.getCacheObject(CacheConstants.nextOrder(xpOrder1.getId().toString()));
+ if (StringUtils.isNotEmpty(json)){
+ log.info("车辆已经有连环订单 {} 单号 {}", vin, orderNo);
+ continue;
+ }
+ Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(xpOrder1.getAppUserId().toString()));
+ RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class);
+ //距离和时间只要有一个满足条件就达到候选对象
+ if (routeRemain.getDuration() > timeRegardAsEnding * 60 && routeRemain.getDistance() > distanceRegardAsEnding * 1000) {
+ log.info("连环派单 {} 车辆订单结束时间不满足条件 {} 秒 {} 米 {}", vin, routeRemain.getDuration(), routeRemain.getDistance(), orderNo);
+ continue;
+ }
+
+ //剩余里程》=下一单预估里程+50
+ //预估接驾行程+送驾行程
+ RouteAndFareDto next = new RouteAndFareDto();
+ next.setOrigin(new LonLatDto(xpOrder1.getEndLon(),xpOrder1.getEndLat()));
+ next.setDestination(new LonLatDto(xpOrder.getStartLon(),xpOrder.getStartLat()));
+ RouteVo route = xpMapClient.getDistanceAndDuration(next).getData();
+ Object new_cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(xpOrder.getAppUserId().toString()));
+ RouteVo new_routeRemain = JSON.parseObject(new_cacheObject.toString(), RouteVo.class);
+ //总续航里程 米
+ long xh = new_routeRemain.getDistance() + route.getDistance() + backupPower * 1000;
+ if(vehiclePosition.getMileageRange() * 1000 < xh){
+ log.info("连环派单 {} 车辆剩余续航不满足派车条件 {} 米 {}", vin, xh, orderNo);
+ continue;
+ }
+
+ //下一单的起点距离本单终点小于X公里,或者下一单的用车时间与本单的预计结束时间偏差小于X分钟
+ //上一单的预估结束时间
+ LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(routeRemain.getDuration());
+ //上一单预估结束时间与本单用车时间差 秒
+ long time = localDateTime.toEpochSecond(ZoneOffset.of("+8")) - xpOrder1.getCreateTime().toEpochSecond(ZoneOffset.of("+8"));
+ if(route.getDistance() <= destToPassenger * 1000 || time <= endingTimeToUseTime * 60){
+ log.info("连环派单 {} 找到满足条件的车辆 {} 距离 {} 时间 {}", orderNo, vin, route.getDistance(), time);
+ log.info("上一单终点与当前订单起点距离 {} 米 {}", route.getDistance(), orderNo);
+ log.info("当前订单用车时间与上一单预估结束时间偏差 {} 秒 {}", time, orderNo);
+ // 设置接驾导航数据
+ //将上一单的剩余导航添加到接驾导航中
+ route.getPolyline().addAll(0, routeRemain.getPolyline());
+ route.setDuration(route.getDuration() + routeRemain.getDuration());
+ route.setDistance(route.getDistance() + routeRemain.getDistance());
+
+ //此处找到车后先不忙给车推送接单消息,先修改订单上的车辆信息
+ xpOrder.setVehicleId(xpOrder1.getVehicleId());
+ xpOrder.setAcceptanceTime(LocalDateTime.now());
+ xpOrder.setStatus(2);
+ xpOrderClient.updateOrder(xpOrder);
+ log.info("连环派单 {} 修改订单状态为接单成功 {}", orderNo, xpOrder.getId());
+
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("orderId", xpOrder.getId());
+ jsonObject.put("endLongitude", xpOrder.getEndLon());
+ jsonObject.put("endLatitude", xpOrder.getEndLat());
+ redisService.setCacheObject(CacheConstants.nextOrder(xpOrder1.getId().toString()), jsonObject.toJSONString());
+ redisService.setCacheObject(CacheConstants.navigationStart(xpOrder.getAppUserId().toString()), JSON.toJSONString(route));
+
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName,xpOrder.getOrderNumber());
+ }
+ log.info("连环派单 {} 设置下一单接驾导航数据 {}", orderNo, JSON.toJSONString(route));
+
+ //构建推送消息
+ Map<String, Object> params = new HashMap<>();
+ Map<String, Object> content = new HashMap<>();
+ content.put("orderId", xpOrder.getId().toString());
+ content.put("status", 2);
+ params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
+ params.put("content", JSONObject.toJSONString(content));
+ params.put("timestamp", System.currentTimeMillis() + "");
+ String message = JSONObject.toJSONString(params);
+ SendMessageDTO dto1 = new SendMessageDTO();
+ dto1.setAppUserId(xpOrder.getAppUserId() + "");
+ dto1.setMessage(message);
+ R<String> stringR = xpPushMessageClient.sendStatus(dto1);
+
+ //推送失败,重试3次
+ if (stringR.getCode() != Constants.SUCCESS) {
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
+ XpOrder finalXpOrder = xpOrder;
+ executor.execute(() -> {
+ for (int j = 0; j < 3; j++) {
+ R<String> stringR1 = xpPushMessageClient.sendStatus(dto1);
+ if (stringR1.getCode() == Constants.SUCCESS) {
+ break;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ log.info("推送订单状态消息失败:{} {} {}", stringR1.getMsg(), JSON.toJSONString(dto1), finalXpOrder.getOrderNumber());
+ }
+ });
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * 定向服务订单处理
+ * @param quoteName 队列名称
+ * @param count 轮数
+ * @param uid
+ * @param split 经纬度
+ * @param orderNo 订单号
+ * @param xpTradingStrategy 规则
+ */
+ @SneakyThrows
+ private Boolean processPushSpOrder(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<XpOrder> xpOrderR = xpOrderClient.queryOrderByOrderNo(orderNo);
+ if (xpOrderR.getCode() != 200) {
+ return false;
+ }
+ if (xpOrderR.getData().getStatus() != 1) {
+ return true;
+ }
+ XpOrder xpOrder = xpOrderR.getData();
+ if (xpOrder.getStatus() == 0) {
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+ }
+
}
// 找出围栏id
@@ -339,16 +1425,20 @@
if (orderCheck.getCode() == 200 && orderCheck.getData() != null && orderCheck.getData().getStatus() == 1) {
log.info("[人车订单绑定测试] 二次校验全部通过, 开始关闭巡游单, vin={}, orderNo={}", priorityVin, orderNo);
// 关闭巡游单
- R stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(priorityVin);
+ R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(priorityVin);
log.info("[人车订单绑定测试] 关闭巡游单结果: code={}, vin={}, orderNo={}",
stringR != null ? stringR.getCode() : "null", priorityVin, orderNo);
if (stringR != null && stringR.getCode() == 200) {
log.info("[人车订单绑定测试] 关闭巡游单成功, 开始下发XPU命令, vin={}, orderNo={}", priorityVin, orderNo);
+ XpCruiseOrder cruiseOrder = stringR.getData();
// 下发XPU命令
PushOrderDto pushOrderDto = new PushOrderDto();
pushOrderDto.setVin(priorityVin);
- pushOrderDto.setTaskId(orderCheck.getData().getXpuTaskId());
+ pushOrderDto.setStartTaskId(orderCheck.getData().getXpuStartTaskId());
+ pushOrderDto.setEndTaskId(orderCheck.getData().getXpuEndTaskId());
pushOrderDto.setOrderId(orderCheck.getData().getId().toString());
+ pushOrderDto.setStartWaypointId(orderCheck.getData().getStartPointId());
+ pushOrderDto.setEndWaypointId(orderCheck.getData().getEndPointId());
pushOrderDto.setStartLatitude(orderCheck.getData().getStartLat());
pushOrderDto.setStartLongitude(orderCheck.getData().getStartLon());
pushOrderDto.setEndLatitude(orderCheck.getData().getEndLat());
@@ -356,12 +1446,21 @@
pushOrderDto.setEndPoiName(orderCheck.getData().getEndPointName());
pushOrderDto.setOrderType(OrderType.USER_ORDER);
pushOrderDto.setStage(1);
+ if(null != cruiseOrder){
+ pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+ pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+ }
+ pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
log.info("[人车订单绑定测试] XPU推单参数: vin={}, orderId={}, startLat={}, startLon={}, endLat={}, endLon={}, orderNo={}",
priorityVin, orderCheck.getData().getId(), orderCheck.getData().getStartLat(), orderCheck.getData().getStartLon(),
orderCheck.getData().getEndLat(), orderCheck.getData().getEndLon(), orderNo);
orderMissionClient.pushOrder(pushOrderDto);
log.info("[人车订单绑定测试] ====== 派单成功! uid={}, vin={}, orderNo={}, 从队列移除订单 ======", uid, priorityVin, orderNo);
- redisService.removeByPattern(quoteName, orderNo);
+
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName, orderNo);
+ }
+
return true;
} else {
log.info("[人车订单绑定测试] 关闭巡游单失败, 回退常规流程, vin={}, orderNo={}", priorityVin, orderNo);
@@ -397,7 +1496,8 @@
log.info("[人车订单绑定测试] 总开关未开启(enabled=false), 跳过优先匹配, uid={}, orderNo={}", uid, orderNo);
}
// ===== 新增结束 =====
-
+ //根据 用户id 和 城市编码 查询 定向服务的 车辆信息
+ List<String> targetedServiceVehicleVinList = xpTargetedServiceService.findSetVehicleVinByUserIdAndCityCode(xpOrder.getAppUserId(), xpOrder.getCityCode());
for (int i = 0; i < count; i++) {
//等到sleepTime秒钟
Thread.sleep(sleepTime * 1000);
@@ -418,11 +1518,19 @@
if (vehiclePositionVos.getCode() != 200) {
continue;
}
- List<VehiclePositionVo> availableVehiclesNearby = BeanUtil.copyToList(positionList, VehiclePositionVo.class);
- List<String> data = vehiclePositionVos.getData();
+ List<String> data = vehiclePositionVos.getData(); //指定区域的车
+ // 计算交集:指定区域的车辆 与 定向服务车辆列表的交集
+ if (targetedServiceVehicleVinList != null && !targetedServiceVehicleVinList.isEmpty() && data != null) {
+ Collection<String> newVehicleVinList = CollUtil.intersection(data,targetedServiceVehicleVinList);
+ if(CollUtil.isNotEmpty(newVehicleVinList)){
+ data = (List<String>) newVehicleVinList;
+ }
+ }
+ List<VehiclePositionVo> availableVehiclesNearby = BeanUtil.copyToList(positionList, VehiclePositionVo.class);
// 找出符合条件的
- availableVehiclesNearby = availableVehiclesNearby.stream().filter(e -> data.contains(e.getVin())).collect(Collectors.toList());
+ List<String> finalData = data;
+ availableVehiclesNearby = availableVehiclesNearby.stream().filter(e -> finalData.contains(e.getVin())).collect(Collectors.toList());
// List<VehiclePositionVo> availableVehiclesNearby =vehiclePositionVos.getData();
if (!availableVehiclesNearby.isEmpty()) {
@@ -1000,19 +2108,23 @@
continue;
}
-
+ String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehiclePosition.getVehicleVin());
// 关闭巡游单子
- R stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vehiclePosition.getVehicleVin());
+ R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vin);
if (stringR == null || stringR.getCode() != 200) {
log.info("关闭巡游单子失败 车牌号 {}", vehiclePosition.getPlateNumber());
continue;
}
log.info("关闭巡游单成功 {} {}", vehiclePosition.getPlateNumber(), orderNo);
+ XpCruiseOrder cruiseOrder = stringR.getData();
// 下发命令
PushOrderDto pushOrderDto = new PushOrderDto();
- pushOrderDto.setTaskId(xpOrder.getXpuTaskId());
- pushOrderDto.setVin(vehiclePosition.getVehicleVin());
+ pushOrderDto.setStartTaskId(xpOrder.getXpuStartTaskId());
+ pushOrderDto.setEndTaskId(xpOrder.getXpuEndTaskId());
+ pushOrderDto.setVin(vin);
pushOrderDto.setOrderId(xpOrder.getId().toString());
+ pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+ pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
pushOrderDto.setStartLatitude(xpOrder.getStartLat());
pushOrderDto.setStartLongitude(xpOrder.getStartLon());
pushOrderDto.setEndLatitude(xpOrder.getEndLat());
@@ -1020,11 +2132,17 @@
pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
pushOrderDto.setOrderType(OrderType.USER_ORDER);
pushOrderDto.setStage(1);
+ if(null != cruiseOrder){
+ pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+ pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+ }
+ pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
// 调用推送服务 orderId + carVin
orderMissionClient.pushOrder(pushOrderDto);
log.info("开始推送 {} 订单到XPU。单号 {}", xpOrder.getOrderNumber(), orderNo);
-
- redisService.removeByPattern(quoteName,xpOrder.getOrderNumber());
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+ }
log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
return true;
} catch (Exception e) {
@@ -1047,6 +2165,7 @@
continue;
}
XpVehicle vehicleId1 = vehicleR.getData();
+ String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehicleId1.getVehicleVin());
log.info("附近只有一个车辆 {} ,直接推单XPU。单号 {}", vehicleId1.getPlateNumber(), orderNo);
log.info("当前车辆状态 运营状态 {} 单号 {}", vehicleId1.getState(), orderNo);
if (vehicleId1.getOperatingStatus() != 1 || vehicleId1.getState() != 0 || vehicleId1.getVehicleType() == 1) {
@@ -1065,19 +2184,40 @@
}
// 关闭巡游单子
- R<?> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vehicleId1.getVehicleVin());
+ R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vin);
if (stringR == null || stringR.getCode() != 200) {
log.info("关闭巡游单子失败 车牌号 {}", vehicleId1.getPlateNumber());
continue;
}
log.info("关闭巡游单成功 {} {}", vehicleId1.getPlateNumber(), orderNo);
- PushOrderDto pushOrderDto = buildPushOrderDto(xpOrder);
+ XpCruiseOrder cruiseOrder = stringR.getData();
+ // 下发命令
+ PushOrderDto pushOrderDto = new PushOrderDto();
+ pushOrderDto.setStartTaskId(xpOrder.getXpuStartTaskId());
+ pushOrderDto.setEndTaskId(xpOrder.getXpuEndTaskId());
pushOrderDto.setVin(vehiclePosition.getVin());
- pushOrderDto.setTaskId(xpOrder.getXpuTaskId());
+ pushOrderDto.setOrderId(xpOrder.getId().toString());
+ pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+ pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
+ pushOrderDto.setStartLatitude(xpOrder.getStartLat());
+ pushOrderDto.setStartLongitude(xpOrder.getStartLon());
+ pushOrderDto.setEndLatitude(xpOrder.getEndLat());
+ pushOrderDto.setEndLongitude(xpOrder.getEndLon());
+ pushOrderDto.setEndPoiName(xpOrder.getEndPointName());
+ pushOrderDto.setOrderType(OrderType.USER_ORDER);
+ pushOrderDto.setStage(1);
+ if(null != cruiseOrder){
+ pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+ pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+ }
+ pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
// 调用推送服务 orderId + carVin
orderMissionClient.pushOrder(pushOrderDto);
log.info("开始推送 {} 订单到XPU", xpOrder.getOrderNumber());
- redisService.popFirstElement(quoteName);
+
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName, xpOrder.getOrderNumber());
+ }
log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
return true;
} catch (Exception e) {
@@ -1155,14 +2295,29 @@
routeToOrigin.getPolyline().addAll(0, routeRemain.getPolyline());
routeToOrigin.setDuration(routeToOrigin.getDuration() + routeRemain.getDuration());
routeToOrigin.setDistance(routeToOrigin.getDistance() + routeRemain.getDistance());
- PushOrderDto pushOrderDto = buildPushOrderDto(xpOrder);
- pushOrderDto.setVin(xpVehicle.getVehicleVin());
- pushOrderDto.setTaskId(xpOrder.getXpuTaskId());
- // 订单流转
- orderMissionClient.pushOrder(pushOrderDto);
- redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), xpOrder.getId());
+
+ //此处找到车后先不忙给车推送接单消息,先修改订单上的车辆信息
+ xpOrder.setVehicleId(xpVehicle.getId());
+ xpOrder.setAcceptanceTime(LocalDateTime.now());
+ xpOrder.setStatus(2);
+ xpOrderClient.updateOrder(xpOrder);
+
+// PushOrderDto pushOrderDto = buildPushOrderDto(xpOrder);
+// pushOrderDto.setVin(xpVehicle.getVehicleVin());
+// pushOrderDto.setTaskId(xpOrder.getXpuTaskId());
+// pushOrderDto.setChainSingle(true);
+// // 订单流转
+// orderMissionClient.pushOrder(pushOrderDto);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("orderId", xpOrder.getId());
+ jsonObject.put("endLongitude", xpOrder.getEndLon());
+ jsonObject.put("endLatitude", xpOrder.getEndLat());
+ redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), jsonObject.toJSONString());
redisService.setCacheObject(CacheConstants.navigationStart(xpOrder.getAppUserId().toString()), routeToOrigin);
- redisService.removeByPattern(quoteName,xpOrder.getOrderNumber());
+ if(StringUtils.isNotEmpty(quoteName)){
+ redisService.removeByPattern(quoteName,xpOrder.getOrderNumber());
+ }
+
log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);
break;
}
@@ -1170,9 +2325,13 @@
return false;
}
+
+
private static PushOrderDto buildPushOrderDto(XpOrder xpOrder) {
PushOrderDto pushOrderDto = new PushOrderDto();
pushOrderDto.setOrderId(xpOrder.getId().toString());
+ pushOrderDto.setStartWaypointId(xpOrder.getStartPointId());
+ pushOrderDto.setEndWaypointId(xpOrder.getEndPointId());
pushOrderDto.setStartLatitude(xpOrder.getStartLat());
pushOrderDto.setStartLongitude(xpOrder.getStartLon());
pushOrderDto.setEndLatitude(xpOrder.getEndLat());
@@ -1228,6 +2387,10 @@
XpOrderReassign entity = new XpOrderReassign(data.getId(),data.getVehicleId(),data.getFleetId(),longitude,latitude,"接驾故障");
entity.setIsComplete(false);
entity.setAppUserId(Long.valueOf(uid));
+
+ // 根据城市编码获取 定向服务设置的车辆
+ List<String> targetedServiceVehicleVinList = xpTargetedServiceService.findSetVehicleVinByUserIdAndCityCode(data.getAppUserId(), data.getCityCode());
+
//循环找车
for (int i = 0; i < count; i++) {
log.info("进入找车环节");
@@ -1302,19 +2465,29 @@
routeToOrigin.getPolyline().addAll(0, routeRemain.getPolyline());
routeToOrigin.setDuration(routeToOrigin.getDuration() + routeRemain.getDuration());
routeToOrigin.setDistance(routeToOrigin.getDistance() + routeRemain.getDistance());
- PushOrderDto pushOrderDto = buildPushOrderDto(data);
- pushOrderDto.setVin(xpVehicle.getVehicleVin());
- // 订单流转
- orderMissionClient.pushOrder(pushOrderDto);
- redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), data.getId());
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("orderId", data.getId());
+ jsonObject.put("endLongitude", data.getEndLon());
+ jsonObject.put("endLatitude", data.getEndLat());
+ redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), jsonObject.toJSONString());
redisService.setCacheObject(CacheConstants.navigationStart(data.getAppUserId().toString()), routeToOrigin);
break;
}
}
+
// 直接派单 定义一个锁来锁定车辆
VehiclePosition vehiclePosition = positionList.get(0);
+ if(CollUtil.isNotEmpty(targetedServiceVehicleVinList)){//定向服务获取的车
+ for (VehiclePosition position : positionList) {
+ if(targetedServiceVehicleVinList.contains(position.getVin())){
+ vehiclePosition = position;
+ break;
+ }
+ }
+ }
String vehicleVin = vehiclePosition.getVin();
+
RLock lock = redissonClient.getLock("FIND_CAR_" + vehiclePosition.getVin());
lock.lock(10, TimeUnit.SECONDS);
@@ -1330,16 +2503,20 @@
continue;
}
// 关闭巡游单子
- R<?> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vehicleId1.getVehicleVin());
+ R<XpCruiseOrder> stringR = xpCruiseOrderClient.cancelCruiseOrderByVin(vehicleId1.getVehicleVin());
if (stringR == null || stringR.getData() == null) {
log.info("关闭巡游单子失败");
continue;
}
+ XpCruiseOrder cruiseOrder = stringR.getData();
PushOrderDto pushOrderDto = new PushOrderDto();
- pushOrderDto.setTaskId(data.getXpuTaskId());
+ pushOrderDto.setStartTaskId(data.getXpuStartTaskId());
+ pushOrderDto.setEndTaskId(data.getXpuEndTaskId());
pushOrderDto.setVin(vehiclePosition.getVin());
pushOrderDto.setOrderId(data.getId().toString());
+ pushOrderDto.setStartWaypointId(data.getStartPointId());
+ pushOrderDto.setEndWaypointId(data.getEndPointId());
pushOrderDto.setStartLatitude(data.getStartLat());
pushOrderDto.setStartLongitude(data.getStartLon());
pushOrderDto.setEndLatitude(data.getEndLat());
@@ -1347,15 +2524,19 @@
pushOrderDto.setEndPoiName(data.getEndPointName());
pushOrderDto.setOrderType(OrderType.USER_ORDER);
pushOrderDto.setStage(1);
+ if(null != cruiseOrder){
+ pushOrderDto.setLastOrderId("XU" + cruiseOrder.getId());
+ pushOrderDto.setLastXpuTaskId(cruiseOrder.getXpuTaskId());
+ }
+ pushOrderDto.setTaskActionType(TaskActionType.kTerminateForNewTask);
// 调用推送服务 orderId + carVin
orderMissionClient.pushOrder(pushOrderDto);
-
entity.setNewVehicleId(vehicleId1.getId());
entity.setNewFleetId(vehicleId1.getFleetId());
entity.setIsComplete(true);
// //接单成功 将 修改 订单的状态=1 ( 状态 0=已取消,1=待接单,2=待出发,3=接驾中,4=待客上车,5=乘客已上车,6=服务中,7=待客下车,8=待付款,9=待评价,10=已完成)
// orderCarStatus = true;
- xpOrderClient.updateOrderStatus(data.getId(), OrderStatusEnum.PENDING_ORDER.getCode(), false);
+ xpOrderClient.updateOrderStatus(data.getId(), OrderStatusEnum.PENDING_ORDER.getCode());
redisService.setCacheObject("ORDER_STATUS:" + data.getId(), OrderStatusEnum.PENDING_ORDER.getCode(), 24L, TimeUnit.HOURS);
break;
--
Gitblit v1.7.1