xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserPositionDTO.java
@@ -1,5 +1,6 @@ package com.xiaopeng.api.dto.account; import com.baomidou.mybatisplus.annotation.EnumValue; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -22,19 +23,10 @@ @ApiModelProperty(value = "纬度") private double longitude; @ApiModelProperty(value = "状态:0在线,1空闲,2上班中") private Integer status; @ApiModelProperty(value = "距离,这个是mongoDB查询时填充") private double distance; @ApiModelProperty(value = "状态;在线 , 上班中 , 空闲") private Long status; enum Status { online("在线"),working("上班中"),idle("空闲"); String label; Status(String label) { this.label = label; } } } xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpTradingStrategyClientFallbackFactory.java
New file @@ -0,0 +1,14 @@ package com.xiaopeng.api.factory.operation; import com.xiaopeng.api.feignClient.operation.XpTradingStrategyClient; import com.xiaopeng.common.core.domain.R; import org.springframework.cloud.openfeign.FallbackFactory; public class XpTradingStrategyClientFallbackFactory implements FallbackFactory<XpTradingStrategyClient> { @Override public XpTradingStrategyClient create(Throwable cause) { return () -> R.fail("策略查询失败"); } } xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpTradingStrategyClient.java
New file @@ -0,0 +1,16 @@ package com.xiaopeng.api.feignClient.operation; import com.xiaopeng.api.factory.operation.XpTradingStrategyClientFallbackFactory; import com.xiaopeng.api.vo.operation.XpTradingStrategyDetailVO; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(contextId = "XpTradingStrategyClient", value = ServiceNameConstantsEnum.XP_OPERATION_SERVICE, fallbackFactory = XpTradingStrategyClientFallbackFactory.class) public interface XpTradingStrategyClient { @GetMapping("/logan/inner/xpOperationStrategy/getOne") R<XpTradingStrategyDetailVO> queryById(); } xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/XpTradingStrategyDetailVO.java
File was renamed from xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/vo/XpTradingStrategyDetailVO.java @@ -1,4 +1,4 @@ package com.xiaopeng.operation.vo; package com.xiaopeng.api.vo.operation; import com.fasterxml.jackson.annotation.JsonFormat; import com.xiaopeng.api.model.operation.XpTradingStrategyCity; xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/controller/XpPricingController.java
@@ -220,27 +220,4 @@ return R.ok(xpPricingService.getQueueStatus(orderId, uid)); } /** * 当前行程可否修改 * * @param * @return 订单数量 */ @GetMapping("/api/v1/mini-program/order/queryOrderTrajectory") public R<Integer> allowedModify(@RequestParam Long orderId){ // 1. 小于10分钟路程(后台配置)【取消行程】按钮应置灰;【取消行程】按钮应置灰;登录后获取系统和个人配置; // 2. 当前剩余里程 < 800米 (后台配置)或 剩余时间 < 5分钟(后台配置)(以先到者为准),禁止修改,按钮置灰。 // 3. 单次行程最多允许修改 2次 (后台配置)目的地,防恶意高频调用 // // 数据字典设置 // 取消行程 时间阈值 10 分钟 // 修改行程 时间阈值 5 分钟 // 修改行程 路程阈值 800 米 // 解除限制 时间阈值 3 分钟 // // 若系统检测到车辆在当前坐标时速 < 3km/h 且持续时间 > 3分钟(后台配置)(判定为极度拥堵或异常停滞),此时解除限制 // 通过 redis 轨迹得到路程 < 3s/60s * 3000m,则为堵车 return R.ok(); } } xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -16,6 +16,7 @@ import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; import com.xiaopeng.api.feignClient.map.XpMapClient; import com.xiaopeng.api.feignClient.operation.XpPointClient; import com.xiaopeng.api.feignClient.operation.XpTradingStrategyClient; import com.xiaopeng.api.feignClient.order.XpOrderClient; import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; @@ -1022,7 +1023,9 @@ payload.setDestination(routeAndFareDto.getDestination()); payload.setUserCouponId(routeAndFareDto.getUserCouponId()); payload.setRoutes(options); redisService.setCacheObject(CacheConstants.ORDER_MULTI_ROUTE_SNAPSHOT + userId + ":" + snapshotId, JSON.toJSONString(payload), 24L, TimeUnit.HOURS); XpTradingStrategyDetailVO strategyDetailVO = xpTradingStrategyClient.queryById().getData(); redisService.setCacheObject(CacheConstants.ORDER_MULTI_ROUTE_SNAPSHOT + userId + ":" + snapshotId, JSON.toJSONString(payload), Long.valueOf(strategyDetailVO.getMaxStandingTiming()), TimeUnit.SECONDS); MultiRouteAndFareVo vo = new MultiRouteAndFareVo(); vo.setSnapshotId(snapshotId); @@ -1037,7 +1040,7 @@ redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + userId, JSON.toJSONString(first.getRoute()), 24L, TimeUnit.HOURS); return vo; } XpTradingStrategyClient xpTradingStrategyClient; @Override public void selectNavigationRoute(SelectNavigationRouteDto dto, String userId) { String json = redisService.getCacheObject(CacheConstants.ORDER_MULTI_ROUTE_SNAPSHOT + userId + ":" + dto.getSnapshotId()); xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpTradingStrategyController.java
@@ -4,7 +4,7 @@ import com.xiaopeng.common.core.web.controller.BaseController; import com.xiaopeng.operation.dto.XpTradingStrategyEditDTO; import com.xiaopeng.operation.service.IXpTradingStrategyService; import com.xiaopeng.operation.vo.XpTradingStrategyDetailVO; import com.xiaopeng.api.vo.operation.XpTradingStrategyDetailVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; @@ -41,6 +41,13 @@ return R.ok(detail); } @ApiOperation(value = "获取交易策略配置", tags = {"inner-交易策略配置"}) @GetMapping("/logan/inner/xpOperationStrategy/getOne") public R<XpTradingStrategyDetailVO> getOne() { XpTradingStrategyDetailVO detail = tradingStrategyService.queryDetail(); return R.ok(detail); } /** * 修改交易策略 * xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpTradingStrategyService.java
@@ -3,7 +3,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.xiaopeng.api.model.operation.XpTradingStrategy; import com.xiaopeng.operation.dto.XpTradingStrategyEditDTO; import com.xiaopeng.operation.vo.XpTradingStrategyDetailVO; import com.xiaopeng.api.vo.operation.XpTradingStrategyDetailVO; /** * <p> xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpTradingStrategyServiceImpl.java
@@ -10,7 +10,7 @@ import com.xiaopeng.operation.mapper.XpTradingStrategyMapper; import com.xiaopeng.operation.service.IXpTradingStrategyCityService; import com.xiaopeng.operation.service.IXpTradingStrategyService; import com.xiaopeng.operation.vo.XpTradingStrategyDetailVO; import com.xiaopeng.api.vo.operation.XpTradingStrategyDetailVO; import lombok.RequiredArgsConstructor; import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType; import org.apache.shardingsphere.transaction.core.TransactionType; xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -10,6 +10,7 @@ import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; import com.xiaopeng.api.feignClient.map.XpMapClient; import com.xiaopeng.api.feignClient.operation.XpTradingStrategyClient; import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient; import com.xiaopeng.api.feignClient.order.XpOrderClient; import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; @@ -23,6 +24,7 @@ import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; import com.xiaopeng.api.vo.operation.RouteVo; import com.xiaopeng.api.vo.operation.VehiclePositionVo; import com.xiaopeng.api.vo.operation.XpTradingStrategyDetailVO; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.constant.Constants; import com.xiaopeng.common.core.domain.R; @@ -48,6 +50,7 @@ import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -79,6 +82,9 @@ @Resource private XpCruiseOrderClient xpCruiseOrderClient; @Resource private XpTradingStrategyClient tradingStrategyClient; @Resource private XpVehicleClient xpVehicleClient; @@ -1087,9 +1093,19 @@ continue; } LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split[0]), Double.parseDouble(split[1])); LonLatDto current = new LonLatDto(Double.parseDouble(split[0]), Double.parseDouble(split[1]));//当前点位 Optional<XpOrder> lucyOrderOpt = servingVehicles.getData().stream() XpTradingStrategyDetailVO strategyDetailVO = tradingStrategyClient.queryById().getData(); Integer distanceRegardAsEnding = strategyDetailVO.getDistanceRegardAsEnding(); Integer timeRegardAsEnding = strategyDetailVO.getTimeRegardAsEnding(); Integer backupPower = strategyDetailVO.getBackupPower(); Integer destToPassenger = strategyDetailVO.getDestToPassenger(); Integer endingTimeToUseTime = strategyDetailVO.getEndingTimeToUseTime(); LocalDateTime rideTime = xpOrder.getRideTime(); LocalDateTime now = LocalDateTime.now(); Optional<XpOrder> luckyOrderOpt = servingVehicles.getData().stream() //获取位置 .map(vin -> mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class)) .map(VehiclePosition::getOrderId) @@ -1097,23 +1113,48 @@ .filter(R::isSuccess) .map(R::getData) .filter(o -> { RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); routeAndFareDto.setDestination(lonLatDto); return isClose(o, routeAndFareDto); XpVehicle xpVehicle = xpVehicleClient.queryById(o.getVehicleId()).getData(); Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(o.getAppUserId().toString())); RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class); if (routeRemain.getDuration() / 60 > timeRegardAsEnding) { return false; } RouteAndFareDto remain = new RouteAndFareDto(); remain.setOrigin(current); LonLatDto ll = new LonLatDto(o.getStartLon(), o.getStartLat()); remain.setDestination(ll); RouteVo r = xpMapClient.getDistanceAndDuration(remain).getData(); if (r.getDistance() > distanceRegardAsEnding) { return false; } if (r.getDuration() / 60 > timeRegardAsEnding) { return false; } RouteAndFareDto next = new RouteAndFareDto(); next.setOrigin(new LonLatDto(o.getStartLon(),o.getStartLat())); next.setDestination(new LonLatDto(o.getEndLon(),o.getEndLat())); RouteVo route = xpMapClient.getDistanceAndDuration(next).getData(); if (route.getDistance() > backupPower + xpVehicle.getMileageRange()) return false; return r.getDistance() < destToPassenger || now.plusSeconds(routeRemain.getDuration()) .plusMinutes(endingTimeToUseTime) .isBefore(rideTime); }) .findAny(); if (lucyOrderOpt.isPresent()) { XpOrder lucyOder = lucyOrderOpt.get(); log.info("有空闲车辆 {} 订单 {}", lucyOder.getOrderNumber(), orderNo); XpVehicle xpVehicle = xpVehicleClient.queryById(lucyOder.getVehicleId()).getData(); if (luckyOrderOpt.isPresent()) { XpOrder luckyOder = luckyOrderOpt.get(); log.info("有空闲车辆 {} 订单 {}", luckyOder.getOrderNumber(), orderNo); XpVehicle xpVehicle = xpVehicleClient.queryById(luckyOder.getVehicleId()).getData(); // 设置路线信息 RouteAndFareDto routeAndFareDto = new RouteAndFareDto(); routeAndFareDto.setDestination(lonLatDto); routeAndFareDto.setOrigin(new LonLatDto(lucyOder.getEndLon(),lucyOder.getEndLat())); Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(lucyOder.getAppUserId().toString())); RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class); routeAndFareDto.setDestination(current); routeAndFareDto.setOrigin(new LonLatDto(luckyOder.getEndLon(),luckyOder.getEndLat())); RouteVo routeToOrigin = xpMapClient.getDistanceAndDuration(routeAndFareDto).getData(); Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(luckyOder.getAppUserId().toString())); RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class); routeToOrigin.getPolyline().addAll(0, routeRemain.getPolyline()); routeToOrigin.setDuration(routeToOrigin.getDuration() + routeRemain.getDuration()); routeToOrigin.setDistance(routeToOrigin.getDistance() + routeRemain.getDistance()); @@ -1121,7 +1162,7 @@ pushOrderDto.setVin(xpVehicle.getVehicleVin()); // 订单流转 orderMissionClient.pushOrder(pushOrderDto); redisService.setCacheObject(CacheConstants.nextOrder(lucyOder.getId().toString()), xpOrder.getId()); redisService.setCacheObject(CacheConstants.nextOrder(luckyOder.getId().toString()), xpOrder.getId()); redisService.setCacheObject(CacheConstants.navigationStart(xpOrder.getAppUserId().toString()), routeToOrigin); redisService.removeByPattern(quoteName,xpOrder.getOrderNumber()); log.info("将订单 {} 从队列 {} 弹出去", orderNo, quoteName);