xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/map/OrderRouteAndFareDto.java
New file @@ -0,0 +1,31 @@ package com.xiaopeng.api.dto.map; import com.xiaopeng.api.dto.operation.LonLatDto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotNull; @Data @ApiModel(description = "订单得线路和运费Dto") public class OrderRouteAndFareDto { @ApiModelProperty(value = "出发地") @NotNull(message = "出发地不能为空") private LonLatDto origin; @ApiModelProperty(value = "目的地") @NotNull(message = "目的地不能为空") private LonLatDto destination; @ApiModelProperty(value = "订单id") @NotNull(message = "订单id不能为空") private Long orderId; @ApiModelProperty(value = "轨迹类型 1=接单轨迹 2=服务轨迹 3=巡游轨迹") @NotNull(message = "轨迹类型不能为空") private Integer routeType; @ApiModelProperty(value = "前端不处理") private Integer routePlanRule; } xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/map/XpMapClientFallbackFactory.java
@@ -1,5 +1,6 @@ package com.xiaopeng.api.factory.map; import com.xiaopeng.api.dto.map.OrderRouteAndFareDto; import com.xiaopeng.api.dto.map.RouteAndFareDto; import com.xiaopeng.api.feignClient.map.XpMapClient; import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient; @@ -23,6 +24,12 @@ } @Override public R<RouteVo> getOrderDistanceAndDuration(OrderRouteAndFareDto dto) { log.error("获取订单距离和时长失败:{}", cause.getMessage()); return R.fail("获取订单距离和时长失败,"+cause.getMessage()); } @Override public R<Boolean> diagnosisArea(RouteAndFareDto dto) { log.error("判断是否同一经营区域失败:{}", cause.getMessage()); return R.fail("判断是否同一经营区域失败"); xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/map/XpMapClient.java
@@ -1,5 +1,6 @@ package com.xiaopeng.api.feignClient.map; import com.xiaopeng.api.dto.map.OrderRouteAndFareDto; import com.xiaopeng.api.dto.map.RouteAndFareDto; import com.xiaopeng.api.factory.map.XpMapClientFallbackFactory; import com.xiaopeng.api.factory.operation.XpSystemSettingClientFallbackFactory; @@ -23,6 +24,13 @@ @PostMapping("/base/v1/mini-program/map/getDistanceAndDuration") R<RouteVo> getDistanceAndDuration(@RequestBody RouteAndFareDto dto); /** * 获取距离和时长 * @param dto * @return */ @PostMapping("/base/v1/mini-program/map/getOrderDistanceAndDuration") R<RouteVo> getOrderDistanceAndDuration(@RequestBody OrderRouteAndFareDto dto); /** * 判断是否同一经营区域 xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/constant/CacheConstants.java
@@ -115,4 +115,12 @@ * 附近点位距离 */ public static final String NEAR_POINT_DISTANCE = "NEAR_POINT_DISTANCE"; /** * 订单车辆位置 */ public static final String ORDER_OLD_LOCATION = "order_old_location:"; /** * 订单车辆位置 */ public static final String ORDER_ROUTE = "order_route:"; } xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpMapController.java
@@ -1,11 +1,14 @@ package com.xiaopeng.map.controller; import com.xiaopeng.api.dto.map.OrderRouteAndFareDto; import com.xiaopeng.api.dto.map.RouteAndFareDto; import com.xiaopeng.api.dto.operation.LonLatDto; import com.xiaopeng.api.vo.map.XpDistanceAndDurationVo; import com.xiaopeng.api.vo.operation.RouteVo; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.map.mangodb.model.GeoPoint; import com.xiaopeng.map.mangodb.service.XpGeoFencingPolygonService; import com.xiaopeng.map.utils.GDMapGeocodingUtil; @@ -13,6 +16,7 @@ import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.bson.Document; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -31,10 +35,12 @@ private final GDMapGeocodingUtil gdMapGeocodingUtil; private final XpGeoFencingPolygonService xpGeoFencingPolygonService; private final RedisService redisService; public XpMapController(GDMapGeocodingUtil gdMapGeocodingUtil, XpGeoFencingPolygonService xpGeoFencingPolygonService) { public XpMapController(GDMapGeocodingUtil gdMapGeocodingUtil, XpGeoFencingPolygonService xpGeoFencingPolygonService, RedisService redisService) { this.gdMapGeocodingUtil = gdMapGeocodingUtil; this.xpGeoFencingPolygonService = xpGeoFencingPolygonService; this.redisService = redisService; } @@ -72,5 +78,42 @@ } /** * 获取订单距离和时长 * @param dto * @return */ @PostMapping("/map/getOrderDistanceAndDuration") public R<RouteVo> getOrderDistanceAndDuration(@Validated @RequestBody OrderRouteAndFareDto dto){ // 获取电子围栏的禁行区域点位 GeoPoint startPoint = new GeoPoint(dto.getOrigin().getLongitude(),dto.getOrigin().getLatitude()); List<String> operatingArea = xpGeoFencingPolygonService.findFencesContainingPoint(startPoint, "operating_area", "points"); String fenceId = operatingArea.get(0); List<Document> pointsInFence = xpGeoFencingPolygonService.findPointsByParentId(fenceId, "parentId", "prohibited_area"); // 避让区域 ArrayList<String> pointStrParam = new ArrayList<>(); for (Document document : pointsInFence) { List<GeoPoint> points = document.getList("points", GeoPoint.class); // 一个区域的点位 ArrayList<String> pointStr = new ArrayList<>(); for (GeoPoint point : points) { pointStr.add( point.getLongitude()+","+point.getLatitude()); } if(!pointStr.isEmpty()){ pointStrParam.add(String.join(";", pointStr)); } } RouteVo routeVo = gdMapGeocodingUtil.getDistanceAndTime(dto.getOrigin(), dto.getDestination(), String.join("|", pointStrParam), fenceId,dto.getRoutePlanRule()); if(routeVo==null){ return R.fail("没有找到路线"); } // 存储redis redisService.setCacheObject(CacheConstants.ORDER_ROUTE + "_" + dto.getOrderId() + "_" +dto.getRouteType(), routeVo); return R.ok(routeVo); } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -16,6 +16,7 @@ import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.utils.WebUtils; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.order.mangodb.model.OrderTrajectory; import com.xiaopeng.order.model.dto.XpOrderCommentDto; import com.xiaopeng.order.model.dto.XpOrderPayDto; import com.xiaopeng.order.model.exportExcel.XpOrderExportExcel; @@ -383,8 +384,8 @@ /** * 订单状态修改-车控消息推送我方调用(内部接口) */ @PostMapping("/inner/v1/order/updateOrderStatus") @ApiOperation(value = "订单状态推送修改") @PostMapping("/inner/v1/order/updateOrderStatus") public R<String> updateOrderStatus(@RequestParam Long orderId, @RequestParam Integer status) { return xpOrderService.updateOrderStatus(orderId,status); @@ -394,10 +395,21 @@ * 业务流程-通过订单id查询车辆信息 */ @ApiOperation(value = "通过订单id查询车辆信息", tags = {"小程序-业务流程"}) @XpClientCheck(checkToken = false, checkOtpToken = true) @GetMapping("/api/v1/order/queryVehicleByOrderId") public R<XpVehicle> queryVehicleByOrderId(@RequestParam Long orderId, HttpServletRequest request) { String uid = request.getHeader("XP-Uid"); return R.ok(xpOrderService.queryVehicleByOrderId(orderId,uid)); } /** * 订单车辆定位实时存储-订单车辆定位实时存储(内部接口) */ @ApiOperation(value = "订单车辆定位实时存储") @PostMapping("/inner/v1/order/saveVehicleLocation") public R<String> saveVehicleLocation(@RequestBody OrderTrajectory orderTrajectory) { xpOrderService.saveVehicleLocation(orderTrajectory); return R.ok(); } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/mangodb/model/OrderTrajectory.java
@@ -23,7 +23,7 @@ private Long orderId; /** * 经纬度 坐标 * 经纬度 坐标 (104.45645456,34.41564654) */ private String location; /** @@ -38,5 +38,10 @@ * 时间戳 毫秒 */ private Long locatetime; /** * 距离 米 */ private Double distance; } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
@@ -13,6 +13,7 @@ import com.xiaopeng.api.vo.order.XpPointInfoVo; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.web.page.PageInfo; import com.xiaopeng.order.mangodb.model.OrderTrajectory; import com.xiaopeng.order.model.dto.XpOrderCommentDto; import com.xiaopeng.order.model.dto.XpOrderPayDto; import com.xiaopeng.order.model.query.XpHistoryOrderListQuery; @@ -180,4 +181,9 @@ */ Integer getOrderNum(GetOrderNumDto dto); /** * 保存车辆位置信息 * @param orderTrajectory */ void saveVehicleLocation(OrderTrajectory orderTrajectory); } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -36,6 +36,7 @@ import com.xiaopeng.api.vo.account.UserCouponVo; import com.xiaopeng.api.vo.order.*; import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.DateUtils; @@ -47,6 +48,8 @@ import com.xiaopeng.common.security.utils.SecurityUtils; import com.xiaopeng.order.constant.I18nKeyConstant; import com.xiaopeng.order.job.jobs.EndTripJob; import com.xiaopeng.order.mangodb.model.OrderTrajectory; import com.xiaopeng.order.mangodb.service.OrderTrajectoryService; import com.xiaopeng.order.mangodb.model.OrderTrajectory; import com.xiaopeng.order.mapper.XpOrderMapper; import com.xiaopeng.order.model.dto.XpOrderCommentDto; @@ -112,6 +115,7 @@ private final RedisService redisService; private final XpPricingClient xpPricingClient; private final XpSystemSettingClient xpSystemSettingClient; private final OrderTrajectoryService orderTrajectoryService; @Autowired private MongoTemplate mongoTemplate; @@ -1035,6 +1039,41 @@ return num.intValue(); } @Override public void saveVehicleLocation(OrderTrajectory orderTrajectory) { // 查询订单信息 XpOrder xpOrder = this.getById(orderTrajectory.getOrderId()); // 计算距离 // 获取上一次定位 String oldLocation = redisService.getCacheObject(CacheConstants.ORDER_OLD_LOCATION + orderTrajectory.getOrderId()); if(StringUtils.isEmpty(oldLocation)){ // 首次定位 xpOrder.setMileageKilometers(0D); this.updateById(xpOrder); orderTrajectory.setDistance(0D); // 存储mongo数据 orderTrajectoryService.create(orderTrajectory); // 存储首次定位 redisService.setCacheObject(CacheConstants.ORDER_OLD_LOCATION + orderTrajectory.getOrderId(), orderTrajectory.getLocation()); }else { Map<String, Double> distance = GeodesyUtil.getDistance(orderTrajectory.getLocation(), oldLocation); if(null != distance){ Double distance1 = distance.get("WGS84"); if(distance1 > 50 && xpOrder.getStatus() == 6){//大于50米表示在移动,且在服务中的时候记录里程 xpOrder.setMileageKilometers(BigDecimal.valueOf(xpOrder.getMileageKilometers()).add(new BigDecimal(distance1)).setScale(2, RoundingMode.HALF_EVEN).doubleValue()); this.updateById(xpOrder); // 存储本次距离 orderTrajectory.setDistance(distance1); // 存储mongo数据 orderTrajectoryService.create(orderTrajectory); } }else{ log.error("调用高德计算距离出错"); } } } /** * 获取当前用户正在执行的订单