| | |
| | | import cn.hutool.core.lang.Snowflake; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.google.common.collect.ImmutableMap; |
| | | import com.google.protobuf.InvalidProtocolBufferException; |
| | | import com.google.protobuf.util.JsonFormat; |
| | | import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto; |
| | | import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; |
| | | import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO; |
| | | import com.xiaopeng.api.dto.map.HistoryPointDto; |
| | | import com.xiaopeng.api.dto.map.OrderRouteAndFareDto; |
| | | import com.xiaopeng.api.dto.operation.CruisePointDto; |
| | | import com.xiaopeng.api.dto.operation.LonLatDto; |
| | | import com.xiaopeng.api.dto.operation.ReassignOrderDTO; |
| | | import com.xiaopeng.api.dto.order.AddCruiseMissionDto; |
| | | import com.xiaopeng.api.dto.order.PopOrderDto; |
| | | import com.xiaopeng.api.dto.pushMessage.PushOrderRouteDTO; |
| | | import com.xiaopeng.api.dto.pushMessage.SendMessageDTO; |
| | | import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto; |
| | | import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; |
| | | import com.xiaopeng.api.feignClient.automaticPilot.VehicleBuriedPointClient; |
| | | import com.xiaopeng.api.feignClient.maintenance.XpTaskClient; |
| | | import com.xiaopeng.api.feignClient.map.XpMapClient; |
| | | import com.xiaopeng.api.feignClient.operation.ReassignOrderClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpCruisePlanClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient; |
| | | import com.xiaopeng.api.feignClient.order.XpCruiseOrderClient; |
| | | import com.xiaopeng.api.feignClient.order.XpOrderClient; |
| | | import com.xiaopeng.api.feignClient.order.XpTestOrderClient; |
| | | import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.UserVehicleClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; |
| | | import com.xiaopeng.api.model.operation.XpSystemSetting; |
| | | import com.xiaopeng.api.model.order.XpCruiseOrder; |
| | | import com.xiaopeng.api.model.order.XpOrder; |
| | | import com.xiaopeng.api.model.order.XpTestOrder; |
| | |
| | | import com.xiaopeng.api.vo.operation.RouteVo; |
| | | import com.xiaopeng.api.vo.order.OrderTrajectoryVo; |
| | | import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; |
| | | import com.xiaopeng.automaticPilot.job.base.QuartzManager; |
| | | import com.xiaopeng.automaticPilot.job.base.TimeJobType; |
| | | import com.xiaopeng.automaticPilot.job.jobs.OrderExceptionJob; |
| | | import com.xiaopeng.automaticPilot.util.XPUUtil; |
| | | import com.xiaopeng.common.core.constant.CacheConstants; |
| | | import com.xiaopeng.common.core.constant.Constants; |
| | |
| | | import com.xiaopeng.common.core.enums.CancelOrderSceneEnum; |
| | | import com.xiaopeng.common.core.enums.OrderStatusEnum; |
| | | import com.xiaopeng.common.core.enums.PushMessageTypeEnum; |
| | | import com.xiaopeng.common.core.utils.DateUtils; |
| | | import com.xiaopeng.common.core.utils.StringUtils; |
| | | import com.xiaopeng.common.core.utils.uuid.UUID; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.redisson.api.RLock; |
| | | import org.redisson.api.RedissonClient; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.geo.Point; |
| | | import org.springframework.data.mongodb.core.MongoTemplate; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | import java.util.concurrent.*; |
| | | import java.util.concurrent.LinkedBlockingQueue; |
| | | import java.util.concurrent.ThreadPoolExecutor; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | |
| | | /** |
| | |
| | | @Service |
| | | public class KafkaConsumerService { |
| | | private static final String REASSIGN_CANCEL_CONTEXT_PREFIX = "REASSIGN_CANCEL_CONTEXT:"; |
| | | private static final String CANCEL_ORDER_CONTEXT_PREFIX = "CANCEL_ORDER_CONTEXT:"; |
| | | |
| | | |
| | | @Resource |
| | |
| | | |
| | | @Resource |
| | | private XpTestOrderClient testOrderClient; |
| | | |
| | | @Resource |
| | | private RedissonClient redissonClient; |
| | | |
| | | @Resource |
| | | private XpSystemSettingClient systemSettingClient; |
| | | |
| | | private static final JsonFormat.Printer jsonPrinter = JsonFormat.printer() |
| | | .printingEnumsAsInts() |
| | |
| | | break; |
| | | case PULLOVER_STATUS_EVENT: |
| | | log.info("靠边停车状态(XPU→云端)(XPU→座舱):{}", message); |
| | | pulloverStatusEvent(msgContent); |
| | | break; |
| | | case DRIVING_MODE_UPDATE_EVENT: |
| | | log.info("驾驶模式变化(XPU→云端)(XPU→座舱):{}", message); |
| | |
| | | if (xpuResPingEnable) { |
| | | responseMessage(cmd, sequence, vin); |
| | | } |
| | | //保存车辆实时位置到redis |
| | | if(0 != longitude && 0 != latitude){ |
| | | redisTemplate.opsForGeo().add("vehiclePosition:" + vin, new Point(longitude, latitude), vin); |
| | | } |
| | | |
| | | VehicleStatus vehicleStatus = systemRuntimeStatus.getVehicleStatus(); |
| | | OrderStatusInfo runningOrderStatusInfo = systemRuntimeStatus.getRunningOrderStatusInfo(); |
| | | String order_id = runningOrderStatusInfo.getOrderId(); |
| | | //车辆动态信息 |
| | | VehicleDynamicStatus dynamicStatus = vehicleStatus.getDynamicStatus(); |
| | | Long orderId = null; |
| | | Integer hasOrder = 0; |
| | | if (StringUtils.isNotEmpty(order_id)) { |
| | | if (order_id.contains("XU")) { |
| | | hasOrder = 1; |
| | | orderId = Long.parseLong(order_id.substring(2)); |
| | | } else if(order_id.contains("TEST")) { |
| | | orderId = Long.parseLong(order_id.substring(4)); |
| | | }else{ |
| | | orderId = Long.parseLong(order_id); |
| | | RLock lock = redissonClient.getLock("PUSH_ORDER_ROUTE_LOCK:" + order_id); |
| | | try { |
| | | boolean tryLock = lock.tryLock(10, 10, TimeUnit.SECONDS); |
| | | if (!tryLock) { |
| | | log.info("获取锁失败,订单ID:{} 无法完成车辆实时位置的逻辑处理。", order_id); |
| | | return; |
| | | } |
| | | } |
| | | //保存车辆实时信息到mongodb |
| | | if(0 != longitude && 0 != latitude){ |
| | | //缓存车辆历史定位,用户辅助获取导航抓路用 |
| | | List<HistoryPointDto> history = redisService.getCacheList("VEHICLE_HISTORY_POINT_LIST:" + xpVehicle.getId()); |
| | | if(history.size() >= 10){ |
| | | history = new ArrayList<>(history.subList(history.size() - 9, history.size())); |
| | | } |
| | | HistoryPointDto historyPointDto = new HistoryPointDto(); |
| | | historyPointDto.setLocation(longitude + "," + latitude); |
| | | historyPointDto.setLocateTime(System.currentTimeMillis() + ""); |
| | | historyPointDto.setAccuracy(naviPose.getPosAcc()); |
| | | historyPointDto.setDirection(course); |
| | | historyPointDto.setSpeed(dynamicStatus.getSpeed()); |
| | | historyPointDto.setHeight(naviPose.getAlt()); |
| | | history.add(historyPointDto); |
| | | redisService.setCacheList("VEHICLE_HISTORY_POINT_LIST:" + xpVehicle.getId(), history); |
| | | |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); |
| | | if (null == vehiclePosition) { |
| | | vehiclePosition = new VehiclePosition(); |
| | | vehiclePosition.setVin(vin); |
| | | vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude)); |
| | | vehiclePosition.setCourse(course); |
| | | vehiclePosition.setAlt(alt); |
| | | vehiclePosition.setSpeed(dynamicStatus.getSpeed()); |
| | | vehiclePosition.setCurrentElectricity(dynamicStatus.getBmsSocDisp()); |
| | | vehiclePosition.setMileageRange(dynamicStatus.getDstBatDisp()); |
| | | vehiclePosition.setOrderId(orderId); |
| | | vehiclePosition.setTotalOdometer(dynamicStatus.getTotalOdometer()); |
| | | vehiclePosition.setAddTime(System.currentTimeMillis()); |
| | | mongoTemplate.save(vehiclePosition); |
| | | }else{ |
| | | vehiclePosition.setOrderId(orderId); |
| | | Update update = new Update() |
| | | .set("point", new GeoJsonPoint(longitude, latitude)) |
| | | .set("course", course) |
| | | .set("alt", alt) |
| | | .set("speed", dynamicStatus.getSpeed()) |
| | | .set("currentElectricity", dynamicStatus.getBmsSocDisp()) |
| | | .set("mileageRange", dynamicStatus.getDstBatDisp()) |
| | | .set("hasOrder", hasOrder) |
| | | .set("orderId", orderId) |
| | | .set("totalOdometer", dynamicStatus.getTotalOdometer()) |
| | | .set("addTime", System.currentTimeMillis()); |
| | | mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class); |
| | | } |
| | | //调用推送服务接口,给乘客推送剩余轨迹和里程时长 |
| | | if (null != orderId && !order_id.contains("XU")) { |
| | | RtTripInfo rtTripInfo = systemRuntimeStatus.getRunningOrderStatusInfo().getRtTripInfo(); |
| | | PushOrderRouteDTO dto = new PushOrderRouteDTO(); |
| | | dto.setOrderId(orderId); |
| | | dto.setRouteType(1); |
| | | dto.setLongitude(longitude); |
| | | dto.setLatitude(latitude); |
| | | if (rtTripInfo.hasCurrentTask() && rtTripInfo.getCurrentTask().hasNaviProgressInfo()) { |
| | | dto.setDuration(rtTripInfo.getCurrentTask().getNaviProgressInfo().getRouteRemainTime()); |
| | | dto.setDistance(rtTripInfo.getCurrentTask().getNaviProgressInfo().getRouteRemainDist()); |
| | | dto.setDirection(course.intValue()); |
| | | } |
| | | |
| | | OrderTrajectoryVo orderTrajectory = new OrderTrajectoryVo(); |
| | | orderTrajectory.setOrderId(orderId); |
| | | orderTrajectory.setLocation(longitude + "," + latitude); |
| | | orderTrajectory.setDirection(dto.getDirection()); |
| | | orderTrajectory.setSpeed((double) dynamicStatus.getSpeed()); |
| | | orderTrajectory.setLocatetime(System.currentTimeMillis()); |
| | | orderTrajectory.setCreateTime(new Date()); |
| | | //只有乘客订单需要推送剩余导航数据 |
| | | if(!order_id.contains("TEST")){ |
| | | xpPushMessageClient.pushOrderRoute(dto);//存储历史轨迹 |
| | | xpOrderClient.saveVehicleLocation(orderTrajectory); |
| | | //车辆动态信息 |
| | | VehicleDynamicStatus dynamicStatus = vehicleStatus.getDynamicStatus(); |
| | | Long orderId = null; |
| | | Integer hasOrder = 0; |
| | | if (StringUtils.isNotEmpty(order_id)) { |
| | | if (order_id.contains("XU")) { |
| | | hasOrder = 1; |
| | | orderId = Long.parseLong(order_id.substring(2)); |
| | | } else if(order_id.contains("TEST")) { |
| | | orderId = Long.parseLong(order_id.substring(4)); |
| | | }else{ |
| | | testOrderClient.saveVehicleLocation(orderTrajectory); |
| | | orderId = Long.parseLong(order_id); |
| | | } |
| | | } |
| | | //保存车辆实时信息到mongodb |
| | | if(0 != longitude && 0 != latitude){ |
| | | //缓存车辆历史定位,用户辅助获取导航抓路用 |
| | | // List<HistoryPointDto> history = redisService.getCacheList("VEHICLE_HISTORY_POINT_LIST:" + xpVehicle.getId()); |
| | | // if(history.size() >= 10){ |
| | | // history = new ArrayList<>(history.subList(history.size() - 9, history.size())); |
| | | // } |
| | | // HistoryPointDto historyPointDto = new HistoryPointDto(); |
| | | // historyPointDto.setLocation(longitude + "," + latitude); |
| | | // historyPointDto.setLocateTime(System.currentTimeMillis() + ""); |
| | | // historyPointDto.setAccuracy(naviPose.getPosAcc()); |
| | | // historyPointDto.setDirection(new BigDecimal(course).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()); |
| | | // historyPointDto.setSpeed(dynamicStatus.getSpeed()); |
| | | // historyPointDto.setHeight(naviPose.getAlt()); |
| | | // history.add(historyPointDto); |
| | | // redisService.setCacheList("VEHICLE_HISTORY_POINT_LIST:" + xpVehicle.getId(), history); |
| | | |
| | | redisTemplate.opsForGeo().add("vehiclePosition:" + vin, new Point(longitude, latitude), vin); |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vin)), VehiclePosition.class); |
| | | if (null == vehiclePosition) { |
| | | vehiclePosition = new VehiclePosition(); |
| | | vehiclePosition.setVin(vin); |
| | | vehiclePosition.setPoint(new GeoJsonPoint(longitude, latitude)); |
| | | vehiclePosition.setCourse(course); |
| | | vehiclePosition.setAlt(alt); |
| | | vehiclePosition.setSpeed(dynamicStatus.getSpeed()); |
| | | vehiclePosition.setCurrentElectricity(dynamicStatus.getBmsSocDisp()); |
| | | vehiclePosition.setMileageRange(dynamicStatus.getDstBatDisp()); |
| | | vehiclePosition.setOrderId(orderId); |
| | | vehiclePosition.setTotalOdometer(dynamicStatus.getTotalOdometer()); |
| | | vehiclePosition.setAddTime(System.currentTimeMillis()); |
| | | mongoTemplate.save(vehiclePosition); |
| | | }else{ |
| | | vehiclePosition.setOrderId(orderId); |
| | | Update update = new Update() |
| | | .set("point", new GeoJsonPoint(longitude, latitude)) |
| | | .set("course", course) |
| | | .set("alt", alt) |
| | | .set("speed", dynamicStatus.getSpeed()) |
| | | .set("currentElectricity", dynamicStatus.getBmsSocDisp()) |
| | | .set("mileageRange", dynamicStatus.getDstBatDisp()) |
| | | .set("hasOrder", hasOrder) |
| | | .set("orderId", orderId) |
| | | .set("totalOdometer", dynamicStatus.getTotalOdometer()) |
| | | .set("addTime", System.currentTimeMillis()); |
| | | mongoTemplate.updateFirst(new Query(Criteria.where("vin").is(vin)), update, VehiclePosition.class); |
| | | } |
| | | //调用推送服务接口,给乘客推送剩余轨迹和里程时长 |
| | | RtTripInfo rtTripInfo = systemRuntimeStatus.getRunningOrderStatusInfo().getRtTripInfo(); |
| | | if (null != orderId && !order_id.contains("XU")) { |
| | | PushOrderRouteDTO dto = new PushOrderRouteDTO(); |
| | | dto.setMessageType(PushMessageTypeEnum.ORDER_ROUTE.getDesc()); |
| | | dto.setOrderId(orderId); |
| | | dto.setRouteType(1); |
| | | dto.setLongitude(longitude); |
| | | dto.setLatitude(latitude); |
| | | dto.setSpeed(dynamicStatus.getSpeed()); |
| | | if (rtTripInfo.hasCurrentTask() && rtTripInfo.getCurrentTask().hasNaviProgressInfo()) { |
| | | dto.setDuration(rtTripInfo.getCurrentTask().getNaviProgressInfo().getRouteRemainTime()); |
| | | dto.setDistance(rtTripInfo.getCurrentTask().getNaviProgressInfo().getRouteRemainDist()); |
| | | dto.setDirection(course.intValue()); |
| | | } |
| | | |
| | | OrderTrajectoryVo orderTrajectory = new OrderTrajectoryVo(); |
| | | orderTrajectory.setOrderId(orderId); |
| | | orderTrajectory.setLocation(longitude + "," + latitude); |
| | | orderTrajectory.setDirection(dto.getDirection()); |
| | | orderTrajectory.setSpeed((double) dynamicStatus.getSpeed()); |
| | | orderTrajectory.setLocatetime(System.currentTimeMillis()); |
| | | orderTrajectory.setCreateTime(new Date()); |
| | | //只有乘客订单需要推送剩余导航数据 |
| | | if(!order_id.contains("TEST")){ |
| | | xpPushMessageClient.pushOrderRoute(dto);//存储历史轨迹 |
| | | // 给连环派单的用户推送 |
| | | String json = redisService.getCacheObject(CacheConstants.nextOrder(order_id)); |
| | | if (StringUtils.isNotEmpty(json)){ |
| | | JSONObject jsonObject = JSON.parseObject(json); |
| | | dto.setOrderId(jsonObject.getLong("orderId")); |
| | | dto.setEndLongitude(jsonObject.getDouble("endLongitude")); |
| | | dto.setEndLatitude(jsonObject.getDouble("endLatitude")); |
| | | xpPushMessageClient.pushOrderRoute(dto); |
| | | } |
| | | xpOrderClient.saveVehicleLocation(orderTrajectory); |
| | | }else{ |
| | | testOrderClient.saveVehicleLocation(orderTrajectory); |
| | | } |
| | | } |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | }finally { |
| | | lock.unlock(); |
| | | } |
| | | } |
| | | |
| | |
| | | if (vehicle != null) { |
| | | // 修改车辆状态 |
| | | XpVehicle vehicle1 = new XpVehicle(); |
| | | vehicle1.setState(0); |
| | | vehicle1.setOperatingStatus(4); |
| | | vehicle1.setState(0);//车辆接单状态 1接单中 0空闲 |
| | | vehicle1.setOperatingStatus(4);//运营状态 1运营中 2维修中 3已收车 4车辆异常 |
| | | vehicle1.setId(vehicle.getId()); |
| | | xpVehicleClient.updateVehicleById(vehicle1); |
| | | log.info("车辆故障,车辆状态修改0 {}", vehicle.getPlateNumber()); |
| | |
| | | userVehicleClient.cancelTaxiPassenger(cancelTaxiPassengerVo); |
| | | } |
| | | //status 状态 0=已取消,1=待接单,2=待出发,3=接驾中,4=待客上车,5=乘客已上车,6=服务中,7=待客下车,8=待付款,9=待评价,10=已完成 |
| | | List<Integer> notDrive = new ArrayList<Integer>(){{ //未行驶的情况下订单故障状态点 |
| | | List<Integer> notDrive = new ArrayList<Integer>(){{ //未行驶的情况下订单故障状态点 status=2、3、4、5 |
| | | add(OrderStatusEnum.READY_DEPART.getCode());add(OrderStatusEnum.PICK_UP.getCode()); |
| | | add(OrderStatusEnum.PICK_UP_GUESTS.getCode());add(OrderStatusEnum.PASSENGER_BOARDED.getCode()); |
| | | }}; |
| | | |
| | | if(xpOrder.getStatus().equals(OrderStatusEnum.IN_SERVICE.getCode()) |
| | | || xpOrder.getStatus().equals(OrderStatusEnum.SEE_OFF_GUESTS.getCode()) ){ //6=服务中 7=待客下车 在行驶中 修改订单-已完成 需要处理订单金额 |
| | | //单独写个修改订单的方法。 |
| | | // ff |
| | | if(xpOrder.getStatus().equals(OrderStatusEnum.IN_SERVICE.getCode()) ){ //6=服务中 在行驶中 修改订单-已完成 需要处理订单金额 |
| | | //行驶中车辆异常,订单状态修改- 修改状态=7 再修改 金额 再将状态修改成8 |
| | | xpOrderClient.carAbnormalUpdateOrderStatus(Long.parseLong(orderId)); |
| | | |
| | | }else if(notDrive.contains(xpOrder.getStatus())){//在接驾中 车辆出现故障 重新派单 |
| | | |
| | | // TODO 重新派单 |
| | | }else if(notDrive.contains(xpOrder.getStatus())){//在接驾中 车辆出现故障 重新派单 改派 |
| | | ReassignOrderDTO reassignOrderDTO = new ReassignOrderDTO(); |
| | | reassignOrderDTO.setUid(xpOrder.getAppUserId().toString()); |
| | | reassignOrderDTO.setOrderNo(xpOrder.getOrderNumber()); |
| | | reassignOrderDTO.setCount(10); |
| | | RealtimePose pose = systemRuntimeStatus.getPose(); |
| | | Wgs naviPose = pose.getNaviPose(); |
| | | Double latitude = naviPose.getLatitude(); |
| | | Double longitude = naviPose.getLongitude(); |
| | | reassignOrderDTO.setLongitude(longitude); |
| | | reassignOrderDTO.setLatitude(latitude); |
| | | // RealtimePose pose = systemRuntimeStatus.getPose(); |
| | | // Wgs naviPose = pose.getNaviPose(); |
| | | // Double latitude = naviPose.getLatitude(); |
| | | // Double longitude = naviPose.getLongitude(); |
| | | reassignOrderDTO.setLongitude(xpOrder.getStartLon()); |
| | | reassignOrderDTO.setLatitude(xpOrder.getStartLat()); |
| | | reassignOrderClient.reassignOrder(reassignOrderDTO); |
| | | } |
| | | } |
| | |
| | | LonLatDto destination = new LonLatDto(); |
| | | LonLatDto origin = new LonLatDto(); |
| | | RouteVo routeVo = null; |
| | | if (orderId.contains("XU")) { |
| | | orderType = OrderType.CRUISE_ORDER; |
| | | String key = ""; |
| | | Float speed = 0f; |
| | | |
| | | R<XpCruiseOrder> cruiseOrder = xpCruiseOrderClient.getCruiseOrder(Long.parseLong(orderId.substring(2))); |
| | | XpCruiseOrder xpCruiseOrder = cruiseOrder.getData(); |
| | | |
| | | //构建导航数据给到车端 |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(xpCruiseOrder.getEndLon()); |
| | | destination.setLatitude(xpCruiseOrder.getEndLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId.substring(2))); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(3); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | //添加redis锁,用于在发生偏航后重新规划线路与正常推送剩余导航数据之间的冲突 |
| | | RLock lock = redissonClient.getLock("PUSH_ORDER_ROUTE_LOCK:" + orderId); |
| | | try { |
| | | boolean tryLock = lock.tryLock(10, 10, TimeUnit.SECONDS); |
| | | if(!tryLock){ |
| | | log.info("获取锁失败,订单ID:{} 无法完成偏航后的逻辑处理。", orderId); |
| | | return; |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | if (orderId.contains("XU")) { |
| | | orderType = OrderType.CRUISE_ORDER; |
| | | |
| | | |
| | | vehicleId = xpCruiseOrder.getVehicleId(); |
| | | } else if(orderId.contains("TEST")){ |
| | | R<XpTestOrder> cruiseOrder = testOrderClient.queryOrderById(Long.parseLong(orderId.substring(4))); |
| | | XpTestOrder testOrder = cruiseOrder.getData(); |
| | | //区分测试单和测试巡游单 |
| | | if(1 == testOrder.getOrderType()){ |
| | | orderType = OrderType.TEST_ORDER; |
| | | //驶往上车点的行程 |
| | | if (3 == testOrder.getStatus()) { |
| | | //查询司机当前位置到起点的线路 |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(testOrder.getStartLon()); |
| | | destination.setLatitude(testOrder.getStartLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId.substring(4))); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(1); |
| | | dto.setVehicleId(testOrder.getVehicleId()); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | //缓存数据,用于后续推给乘客导航线路 |
| | | redisService.setCacheObject("TEST_ORDER_NAVIGATION_START_DATA:" + testOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS); |
| | | } |
| | | //驶往下车点的行程 |
| | | if (6 == testOrder.getStatus()) { |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(testOrder.getEndLon()); |
| | | destination.setLatitude(testOrder.getEndLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId.substring(4))); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(2); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据 |
| | | redisService.setCacheObject("TEST_ORDER_NAVIGATION_END_DATA:" + testOrder.getVehicleId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS); |
| | | } |
| | | |
| | | }else{ |
| | | orderType = OrderType.TEST_CRUISE_ORDER; |
| | | R<XpCruiseOrder> cruiseOrder = xpCruiseOrderClient.getCruiseOrder(Long.parseLong(orderId.substring(2))); |
| | | XpCruiseOrder xpCruiseOrder = cruiseOrder.getData(); |
| | | |
| | | //构建导航数据给到车端 |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(testOrder.getEndLon()); |
| | | destination.setLatitude(testOrder.getEndLat()); |
| | | destination.setLongitude(xpCruiseOrder.getEndLon()); |
| | | destination.setLatitude(xpCruiseOrder.getEndLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId.substring(4))); |
| | | dto.setOrderId(Long.parseLong(orderId.substring(2))); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(3); |
| | |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | |
| | | vehicleId = testOrder.getVehicleId(); |
| | | } |
| | | } else { |
| | | orderType = OrderType.USER_ORDER; |
| | | //正常单 |
| | | R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId)); |
| | | if (200 != xpOrderR.getCode()) { |
| | | throw new RuntimeException("订单不存在"); |
| | | } |
| | | XpOrder xpOrder = xpOrderR.getData(); |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData(); |
| | | //驶往上车点的行程 |
| | | if (3 == xpOrder.getStatus()) { |
| | | //查询司机当前位置到起点的线路 |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(xpOrder.getStartLon()); |
| | | destination.setLatitude(xpOrder.getStartLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId)); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(1); |
| | | dto.setVehicleId(xpOrder.getVehicleId()); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | //缓存数据,用于后续推给乘客导航线路 |
| | | redisService.setCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS); |
| | | } |
| | | //驶往下车点的行程 |
| | | if (6 == xpOrder.getStatus()) { |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(xpOrder.getEndLon()); |
| | | destination.setLatitude(xpOrder.getEndLat()); |
| | | vehicleId = xpCruiseOrder.getVehicleId(); |
| | | } else if(orderId.contains("TEST")){ |
| | | R<XpTestOrder> cruiseOrder = testOrderClient.queryOrderById(Long.parseLong(orderId.substring(4))); |
| | | XpTestOrder testOrder = cruiseOrder.getData(); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId)); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(2); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(testOrder.getVehicleId()).getData(); |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(Query.query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class); |
| | | if(null != vehiclePosition){ |
| | | speed = vehiclePosition.getSpeed(); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据 |
| | | redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + xpOrder.getAppUserId(), JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS); |
| | | } |
| | | vehicleId = xpOrder.getVehicleId(); |
| | | } |
| | | //直接响应回最新导航数据 |
| | | if(StringUtils.isNotEmpty(routeID)){ |
| | | //推送小程序新的导航数据 |
| | | if(orderType.equals(OrderType.USER_ORDER)){ |
| | | PushOrderRouteDTO dto = new PushOrderRouteDTO(); |
| | | dto.setOrderId(Long.parseLong(orderId)); |
| | | dto.setRouteType(1); |
| | | dto.setLongitude(longitude); |
| | | dto.setLatitude(latitude); |
| | | if (null != routeVo) { |
| | | dto.setDuration(null == routeVo.getDuration() ? 0 : routeVo.getDuration().doubleValue()); |
| | | dto.setDistance(null == routeVo.getDistance() ? 0 : routeVo.getDistance().doubleValue()); |
| | | dto.setDirection(null == routeVo.getDirection() ? 0 : routeVo.getDirection().intValue()); |
| | | } |
| | | xpPushMessageClient.pushOrderRoute(dto); |
| | | log.info("完成小程序下发导航偏离后的新轨迹:" + orderId); |
| | | } |
| | | |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData(); |
| | | R<String> stringR = xpMapClient.queryRouted(routeID); |
| | | if (200 != stringR.getCode()) { |
| | | throw new RuntimeException("根据导航ID获取车端需要的导航数据失败"); |
| | | //区分测试单和测试巡游单 |
| | | if(1 == testOrder.getOrderType()){ |
| | | orderType = OrderType.TEST_ORDER; |
| | | //驶往上车点的行程 |
| | | if (3 == testOrder.getStatus()) { |
| | | //查询司机当前位置到起点的线路 |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(testOrder.getStartLon()); |
| | | destination.setLatitude(testOrder.getStartLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId.substring(4))); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(1); |
| | | dto.setVehicleId(testOrder.getVehicleId()); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | key = "TEST_ORDER_NAVIGATION_START_DATA:" + testOrder.getVehicleId(); |
| | | } |
| | | //驶往下车点的行程 |
| | | if (6 == testOrder.getStatus()) { |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(testOrder.getEndLon()); |
| | | destination.setLatitude(testOrder.getEndLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId.substring(4))); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(2); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | key = "TEST_ORDER_NAVIGATION_END_DATA:" + testOrder.getVehicleId(); |
| | | } |
| | | |
| | | }else{ |
| | | orderType = OrderType.TEST_CRUISE_ORDER; |
| | | |
| | | //构建导航数据给到车端 |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(testOrder.getEndLon()); |
| | | destination.setLatitude(testOrder.getEndLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId.substring(4))); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(3); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | |
| | | vehicleId = testOrder.getVehicleId(); |
| | | } |
| | | } else { |
| | | orderType = OrderType.USER_ORDER; |
| | | //正常单 |
| | | R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId)); |
| | | if (200 != xpOrderR.getCode()) { |
| | | throw new RuntimeException("订单不存在"); |
| | | } |
| | | XpOrder xpOrder = xpOrderR.getData(); |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData(); |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(Query.query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class); |
| | | if(null != vehiclePosition){ |
| | | speed = vehiclePosition.getSpeed(); |
| | | } |
| | | //驶往上车点的行程 |
| | | if (3 == xpOrder.getStatus()) { |
| | | //查询司机当前位置到起点的线路 |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(xpOrder.getStartLon()); |
| | | destination.setLatitude(xpOrder.getStartLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId)); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(1); |
| | | dto.setVehicleId(xpOrder.getVehicleId()); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | key = "ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId(); |
| | | } |
| | | //驶往下车点的行程 |
| | | if (6 == xpOrder.getStatus()) { |
| | | origin.setLongitude(longitude); |
| | | origin.setLatitude(latitude); |
| | | destination.setLongitude(xpOrder.getEndLon()); |
| | | destination.setLatitude(xpOrder.getEndLat()); |
| | | |
| | | OrderRouteAndFareDto dto = new OrderRouteAndFareDto(); |
| | | dto.setOrderId(Long.parseLong(orderId)); |
| | | dto.setOrigin(origin); |
| | | dto.setDestination(destination); |
| | | dto.setRouteType(2); |
| | | R<RouteVo> routeVoR = xpMapClient.getOrderDistanceAndDuration(dto); |
| | | if (200 != routeVoR.getCode()) { |
| | | throw new RuntimeException("获取订单线路和运费失败"); |
| | | } |
| | | routeVo = routeVoR.getData(); |
| | | routeID = routeVo.getRouteID(); |
| | | key = "ORDER_NAVIGATION_END_DATA:" + xpOrder.getAppUserId(); |
| | | } |
| | | vehicleId = xpOrder.getVehicleId(); |
| | | } |
| | | log.info("开始下发XPU导航偏离后新的导航数据:" + orderId); |
| | | //构建响应导航数据给车端 |
| | | cloudPushNavigationInfo(requestId, routeID, stringR.getData(), orderType, orderId, xpVehicle.getVehicleVin(), xpVehicle.getXpuId(), taskId); |
| | | log.info("完成下发XPU导航偏离后新的导航数据:" + orderId); |
| | | //直接响应回最新导航数据 |
| | | if(StringUtils.isNotEmpty(routeID)){ |
| | | //推送小程序新的导航数据 |
| | | if(orderType.equals(OrderType.USER_ORDER)){ |
| | | //缓存导航数据,用于后面的逻辑中给乘客端推送导航数据 |
| | | redisService.setCacheObject(key, JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS); |
| | | PushOrderRouteDTO dto = new PushOrderRouteDTO(); |
| | | dto.setOrderId(Long.parseLong(orderId)); |
| | | dto.setRouteType(1); |
| | | dto.setLongitude(longitude); |
| | | dto.setLatitude(latitude); |
| | | dto.setSpeed(speed); |
| | | if (null != routeVo) { |
| | | dto.setDuration(null == routeVo.getDuration() ? 0 : routeVo.getDuration().doubleValue()); |
| | | dto.setDistance(null == routeVo.getDistance() ? 0 : routeVo.getDistance().doubleValue()); |
| | | dto.setDirection(null == routeVo.getDirection() ? 0 : routeVo.getDirection().intValue()); |
| | | } |
| | | dto.setMessageType(PushMessageTypeEnum.ORDER_UPDATE_LINE.getDesc()); |
| | | xpPushMessageClient.pushOrderRoute(dto); |
| | | log.info("完成小程序下发导航偏离后的新轨迹:" + orderId); |
| | | } |
| | | |
| | | XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData(); |
| | | R<String> stringR = xpMapClient.queryRouted(routeID); |
| | | if (200 != stringR.getCode()) { |
| | | throw new RuntimeException("根据导航ID获取车端需要的导航数据失败"); |
| | | } |
| | | log.info("开始下发XPU导航偏离后新的导航数据:" + orderId); |
| | | //构建响应导航数据给车端 |
| | | cloudPushNavigationInfo(requestId, routeID, stringR.getData(), orderType, orderId, xpVehicle.getVehicleVin(), xpVehicle.getXpuId(), taskId); |
| | | log.info("完成下发XPU导航偏离后新的导航数据:" + orderId); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | }finally { |
| | | lock.unlock(); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | } |
| | | |
| | | ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(20); |
| | | |
| | | @Resource OrderMissionClient orderMissionClient; |
| | | /** |
| | | * 订单状态更新事件 |
| | | * @param msgContent |
| | |
| | | testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.READY_DEPART.getCode()); |
| | | }else{ |
| | | buildPushOrderStatus(cmd, orderId, OrderStatusEnum.READY_DEPART, sequence); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.READY_DEPART.getCode()); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.READY_DEPART.getCode(), false); |
| | | } |
| | | } |
| | | break; |
| | |
| | | testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.PICK_UP.getCode()); |
| | | }else{ |
| | | buildPushOrderStatus(cmd, orderId, OrderStatusEnum.PICK_UP, sequence); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PICK_UP.getCode()); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PICK_UP.getCode(), false); |
| | | } |
| | | } |
| | | break; |
| | |
| | | testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.PICK_UP_GUESTS.getCode()); |
| | | }else{ |
| | | buildPushOrderStatus(cmd, orderId, OrderStatusEnum.PICK_UP_GUESTS, sequence); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PICK_UP_GUESTS.getCode()); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PICK_UP_GUESTS.getCode(), false); |
| | | } |
| | | } |
| | | break; |
| | | case ORDER_PASSENGER_ONBOARD: |
| | | //先手动暂停触发,因为现目前车机响应状态时机不对 |
| | | try { |
| | | Thread.sleep(waittime); |
| | | } catch (InterruptedException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | //乘客已上车 |
| | | if(!orderId.contains("XU")){ |
| | | if(orderId.contains("TEST")){ |
| | | testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.PASSENGER_BOARDED.getCode()); |
| | | }else{ |
| | | buildPushOrderStatus(cmd, orderId, OrderStatusEnum.PASSENGER_BOARDED, sequence); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PASSENGER_BOARDED.getCode()); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.PASSENGER_BOARDED.getCode(), false); |
| | | } |
| | | } |
| | | break; |
| | |
| | | testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.IN_SERVICE.getCode()); |
| | | }else{ |
| | | buildPushOrderStatus(cmd, orderId, OrderStatusEnum.IN_SERVICE, sequence); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.IN_SERVICE.getCode()); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.IN_SERVICE.getCode(), false); |
| | | } |
| | | } |
| | | break; |
| | |
| | | log.info("到达目的地,不做任何处理:{}", orderId); |
| | | break; |
| | | case ORDER_WAITING_FOR_DROPOFF: |
| | | // 根据车辆id查询订单,如果未完成订单数量不唯一则下发循环订单任务 |
| | | List ret = new ArrayList(2);//TODO |
| | | if(ret.size() > 1){ |
| | | scheduler.schedule(() -> { |
| | | //下发循环订单任务 |
| | | // xpOrderClient.createLoopOrderTask(vin, orderId); |
| | | log.info("下发循环订单任务:{}", orderId); |
| | | // 修改订单状态,和推送消息的状态 |
| | | }, 3, TimeUnit.SECONDS); |
| | | |
| | | break; |
| | | } |
| | | |
| | | //等待乘客下车,开始倒计时发下巡游单 |
| | | if(!orderId.contains("XU")){ |
| | | if(orderId.contains("TEST")){ |
| | | testOrderClient.updateOrderStatus(Long.parseLong(orderId.substring(4)), OrderStatusEnum.SEE_OFF_GUESTS.getCode()); |
| | | }else{ |
| | | buildPushOrderStatus(cmd, orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode()); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode(), false); |
| | | } |
| | | } |
| | | |
| | | break; |
| | | case ORDER_DROPOFF_COMPLETED: |
| | | //下车完成,不需要处理状态,由后续的乘客主动触发或者定时任务触发 |
| | |
| | | log.info("改派旧车取消回调,跳过订单取消处理,orderId: {}, taskId: {}, cancelScene: {}, context: {}", |
| | | orderId, taskId, reassignCancelContext.getString("cancelScene"), reassignCancelContext); |
| | | //响应消息 |
| | | String responseVin = resolveReassignCancelResponseVin(reassignCancelContext); |
| | | String responseVin = resolveReassignCancelResponseVin(orderId, reassignCancelContext); |
| | | if (StringUtils.isNotEmpty(responseVin)) { |
| | | responseMessage(cmd, sequence, responseVin); |
| | | } else { |
| | |
| | | }}; |
| | | if(xczqx.contains(xpOrder.getStatus())){//行程中取消订单,按照行程结束处理 |
| | | buildPushOrderStatus(cmd, orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode()); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.SEE_OFF_GUESTS.getCode(), true); |
| | | redisService.setCacheObject("ORDER_STATUS:" + orderId, OrderStatusEnum.SEE_OFF_GUESTS.getCode(), 24L, TimeUnit.HOURS); |
| | | // 判断当前订单的车辆是否有连环派单,然后判断是都还满足连环派单的条件,不满足则需要重新派单 |
| | | String json = redisService.getCacheObject(CacheConstants.nextOrder(orderId)); |
| | | if (StringUtils.isNotEmpty(json)){ |
| | | JSONObject jsonObject = JSON.parseObject(json); |
| | | Long nextOrderId = jsonObject.getLong("orderId"); |
| | | XpOrder nextOrder = xpOrderClient.queryOrderById(nextOrderId).getData(); |
| | | if(null != nextOrder && nextOrder.getStatus() == OrderStatusEnum.PICK_UP.getCode()){ |
| | | redisService.setCacheObject(CacheConstants.nextOrder(orderId),null); |
| | | ReassignOrderDTO reassignOrderDTO = new ReassignOrderDTO(); |
| | | reassignOrderDTO.setUid(xpOrder.getAppUserId().toString()); |
| | | reassignOrderDTO.setOrderNo(xpOrder.getOrderNumber()); |
| | | reassignOrderDTO.setCount(10); |
| | | reassignOrderDTO.setLongitude(xpOrder.getStartLon()); |
| | | reassignOrderDTO.setLatitude(xpOrder.getStartLon()); |
| | | reassignOrderClient.reassignOrder(reassignOrderDTO); |
| | | } |
| | | } |
| | | redisService.getCacheObject("ORDER_CONNECT_ORDER:" + orderId); |
| | | |
| | | }else{ |
| | | buildPushOrderStatus(cmd, orderId, OrderStatusEnum.CANCELED, sequence); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.CANCELED.getCode()); |
| | | xpOrderClient.updateOrderStatus(Long.parseLong(orderId), OrderStatusEnum.CANCELED.getCode(), true); |
| | | redisService.setCacheObject("ORDER_STATUS:" + orderId, OrderStatusEnum.CANCELED.getCode(), 24L, TimeUnit.HOURS); |
| | | } |
| | | } |
| | |
| | | newXpCruiseOrder.setStartPointName(xpCruiseOrder.getEndPointName()); |
| | | newXpCruiseOrder.setStatus(1); |
| | | newXpCruiseOrder.setLastOrderId(xpCruiseOrder.getId()); |
| | | xpCruiseOrder.setXpuTaskId(snowflake.nextId() + ""); |
| | | |
| | | // 通过车找终点id |
| | | CruisePointDto cruisePointDto = new CruisePointDto(); |
| | |
| | | cruisePointDto.setOrderReverse(xpCruiseOrder.getOrderReverse()); |
| | | R<XpCruiseOrder> cruisePoint = xpCruisePlanClient.getCruisePoint(cruisePointDto); |
| | | if(cruisePoint!=null){ |
| | | xpCruiseOrderClient.addCruiseOrder(cruisePoint.getData()); |
| | | XpCruiseOrder cruiseOrder1 = cruisePoint.getData(); |
| | | //不停车替换新任务 |
| | | cruiseOrder1.setLastOrderId1("XU" + xpCruiseOrder.getId()); |
| | | cruiseOrder1.setLastXpuTaskId(xpCruiseOrder.getXpuTaskId()); |
| | | cruiseOrder1.setTaskActionType(TaskActionType.kTerminateForNewTask); |
| | | xpCruiseOrderClient.addCruiseOrder(cruiseOrder1); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 当前 cancelOrder 指令是按 taskId 记录取消上下文。 |
| | | * 改派旧车取消回调优先读取该上下文,避免依赖订单当前车/状态造成竞态误判。 |
| | | */ |
| | | private JSONObject getReassignCancelContext(String orderId) { |
| | | if (StringUtils.isEmpty(orderId)) { |
| | | return null; |
| | |
| | | if (OrderStateChangeSource.ORDER_STATE_CHANGE_SOURCE_VEHICLE != orderStatusInfo.getChangeSource()) { |
| | | return null; |
| | | } |
| | | JSONObject cancelContext = getReassignCancelContext(orderId); |
| | | String taskId = orderStatusInfo.getTaskId(); |
| | | // 先按 taskId 读取当前生效的取消上下文,再兼容历史按 orderId 存储的改派上下文。 |
| | | JSONObject cancelContext = getCancelOrderContext(taskId); |
| | | if (cancelContext == null) { |
| | | cancelContext = getReassignCancelContext(orderId); |
| | | } |
| | | if (cancelContext == null) { |
| | | log.info("改派取消回调未命中专用上下文,orderId: {}, taskId: {}, missReason: context_not_found", |
| | | orderId, taskId); |
| | | return null; |
| | | } |
| | | String cancelScene = cancelContext.getString("cancelScene"); |
| | | if (CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE != CancelOrderSceneEnum.fromCode(cancelScene)) { |
| | | log.info("改派取消回调未命中专用上下文,orderId: {}, taskId: {}, missReason: scene_not_match, cancelScene: {}, context: {}", |
| | | orderId, taskId, cancelScene, cancelContext); |
| | | return null; |
| | | } |
| | | String contextOrderId = cancelContext.getString("orderId"); |
| | | if (StringUtils.isNotEmpty(contextOrderId) && !Objects.equals(contextOrderId, orderId)) { |
| | | log.info("改派取消回调未命中专用上下文,orderId: {}, taskId: {}, missReason: order_not_match, contextOrderId: {}, context: {}", |
| | | orderId, taskId, contextOrderId, cancelContext); |
| | | return null; |
| | | } |
| | | return cancelContext; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 当前 cancelOrder 指令是按 taskId 记录取消上下文。 |
| | | * 改派旧车取消回调优先读取该上下文,避免依赖订单当前车/状态造成竞态误判。 |
| | | */ |
| | | private JSONObject getCancelOrderContext(String taskId) { |
| | | if (StringUtils.isEmpty(taskId)) { |
| | | return null; |
| | | } |
| | | Object cacheObject = redisService.getCacheObject(CANCEL_ORDER_CONTEXT_PREFIX + taskId); |
| | | if (cacheObject == null) { |
| | | return null; |
| | | } |
| | | return JSON.parseObject(cacheObject.toString()); |
| | | } |
| | | |
| | | |
| | | private String resolveReassignCancelResponseVin(String orderId, JSONObject cancelContext) { |
| | | if (cancelContext == null) { |
| | | return null; |
| | | } |
| | | String vin = cancelContext.getString("vin"); |
| | | if (StringUtils.isNotEmpty(vin)) { |
| | | return vin; |
| | | } |
| | | if (CancelOrderSceneEnum.REASSIGN_OLD_VEHICLE != CancelOrderSceneEnum.fromCode( |
| | | cancelContext.getString("cancelScene"))) { |
| | |
| | | boolean vehicleMatched = Objects.nonNull(newVehicleId) && Objects.equals(newVehicleId, xpOrder.getVehicleId()); |
| | | boolean statusMatched = Objects.nonNull(currentStatus) && currentStatus > 0 && currentStatus < 8; |
| | | if (vehicleMatched && statusMatched) { |
| | | return cancelContext; |
| | | } |
| | | log.info("改派取消回调未命中专用上下文,orderId: {}, currentVehicleId: {}, newVehicleId: {}, currentStatus: {}", |
| | | orderId, xpOrder.getVehicleId(), newVehicleId, currentStatus); |
| | | return null; |
| | | } |
| | | |
| | | private String resolveReassignCancelResponseVin(JSONObject cancelContext) { |
| | | if (cancelContext == null) { |
| | | return null; |
| | | return newVehicleId.toString(); |
| | | } |
| | | String oldVehicleVin = cancelContext.getString("oldVehicleVin"); |
| | | if (StringUtils.isNotEmpty(oldVehicleVin)) { |
| | |
| | | } |
| | | R<XpVehicle> vehicleResult = xpVehicleClient.queryById(oldVehicleId); |
| | | XpVehicle xpVehicle = vehicleResult == null ? null : vehicleResult.getData(); |
| | | log.info("改派取消回调未命中专用上下文,orderId: {}, currentVehicleId: {}, newVehicleId: {}, currentStatus: {}", |
| | | orderId, xpOrder.getVehicleId(), newVehicleId, currentStatus); |
| | | return xpVehicle == null ? null : xpVehicle.getVehicleVin(); |
| | | } |
| | | |
| | |
| | | log.info("推送导航的响应消息,{}", JSON.toJSONString(mqttPublishDto)); |
| | | } |
| | | |
| | | |
| | | |
| | | //靠边停车处理逻辑 |
| | | public void pulloverStatusEvent(MsgContent msgContent){ |
| | | // todo 等对接完成数据结构后再实现相关功能 |
| | | //开始处理消息对应的业务逻辑 |
| | | NavigationRequest naviRequest = msgContent.getNavigationRequest(); |
| | | String requestId = naviRequest.getRequestId(); |
| | | String orderId = naviRequest.getOrderId(); |
| | | String taskId = naviRequest.getTaskId(); |
| | | OrderPhase orderPhase = naviRequest.getOrderPhase(); |
| | | log.info("订单ID:{}", orderId); |
| | | log.info("任务ID:{}", taskId); |
| | | |
| | | //获取系统异常订单超时配置,创建定时任务取消订单 |
| | | if(!orderId.contains("XU")){ |
| | | XpSystemSetting xpSystemSetting = systemSettingClient.getSystemSettingOne().getData(); |
| | | Map<String, ? extends Object> jobMaps = |
| | | new ImmutableMap.Builder<String, String>() |
| | | .put("id", orderId) |
| | | .put("orderType", orderId.contains("TEST") ? OrderType.TEST_ORDER : OrderType.USER_ORDER) |
| | | .build(); |
| | | QuartzManager.addJob( |
| | | OrderExceptionJob.class, |
| | | (OrderExceptionJob.name + orderId).toUpperCase(), |
| | | TimeJobType.ERROR_ORDER_CANCEL, |
| | | DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(xpSystemSetting.getOrderExceptionalTimeout())), |
| | | jobMaps |
| | | ); |
| | | } |
| | | |
| | | } |
| | | } |