| | |
| | | import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; |
| | | import com.xiaopeng.api.dto.automaticPilot.VehicleEventDTO; |
| | | import com.xiaopeng.api.dto.map.OrderRouteAndFareDto; |
| | | import com.xiaopeng.api.dto.operation.CruisePointDto; |
| | | import com.xiaopeng.api.dto.map.RouteAndFareDto; |
| | | import com.xiaopeng.api.dto.operation.LonLatDto; |
| | | import com.xiaopeng.api.dto.order.GetOrderNumDto; |
| | | import com.xiaopeng.api.dto.order.HistoryEndPointsDto; |
| | |
| | | import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO; |
| | | import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO; |
| | | import com.xiaopeng.api.dto.vehicleConvoy.BaseVehicleUserDto; |
| | | import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto; |
| | | import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto; |
| | | import com.xiaopeng.api.feignClient.account.UserResourcesClient; |
| | | import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; |
| | | import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; |
| | | import com.xiaopeng.api.feignClient.automaticPilot.VehicleBuriedPointClient; |
| | | import com.xiaopeng.api.feignClient.maintenance.XpTaskRuleClient; |
| | | import com.xiaopeng.api.feignClient.map.XpMapClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpCruisePlanClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpPointClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpPricingClient; |
| | | import com.xiaopeng.api.feignClient.operation.XpSystemSettingClient; |
| | | import com.xiaopeng.api.feignClient.operation.*; |
| | | import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; |
| | | import com.xiaopeng.api.feignClient.vehicleConvoy.*; |
| | | import com.xiaopeng.api.model.maintenance.XpTaskRule; |
| | |
| | | import com.xiaopeng.api.model.order.*; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpFleet; |
| | | import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; |
| | | import com.xiaopeng.api.service.BootCommonService; |
| | | import com.xiaopeng.api.vo.OrderType; |
| | | import com.xiaopeng.api.vo.account.UserCouponVo; |
| | | import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; |
| | |
| | | import com.xiaopeng.order.utils.GDMapGeocodingUtil; |
| | | import com.xiaopeng.order.utils.TaxiPricingDemoService; |
| | | import com.xiaopeng.order.utils.RegionCodeFilterUtil; |
| | | import com.xiaopeng.order.utils.TaxiPricingDemoService; |
| | | import com.xiaopeng.order.utils.XpPricingUtil; |
| | | import com.xiaopeng.order.utils.holiday.HolidayUtil; |
| | | import com.xiaopeng.order.vo.OrderDetailVo; |
| | |
| | | private final VehicleBuriedPointClient vehicleBuriedPointClient; |
| | | private final IXpTestOrderService xpTestOrderService; |
| | | private final XpMapClient xpMapClient; |
| | | @Resource |
| | | private XpRoutePlanClient xpRoutePlanClient; |
| | | @Resource |
| | | private BootCommonService bootCommonService; |
| | | |
| | | |
| | | @Autowired |
| | |
| | | @ShardingSphereTransactionType(TransactionType.BASE) |
| | | public void cancelOrder(Long orderId, String uid) { |
| | | XpOrder order = this.getById(orderId); |
| | | if (order.getStatus() == 0) { |
| | | return; |
| | | } |
| | | if (order == null) { |
| | | throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | | } |
| | | if (order.getStatus() == 0) { |
| | | return; |
| | | } |
| | | if (!order.getAppUserId().toString().equals(uid)) { |
| | | throw new ServiceException("订单不存在", I18nKeyConstant.ORDER_NOT_EXISTS); |
| | |
| | | if (order.getStatus() > 5 || order.getStatus() < 1) { |
| | | throw new ServiceException("订单状态错误", I18nKeyConstant.ORDER_STATUS_ERROR); |
| | | } |
| | | |
| | | try { |
| | | redisService.removeByPattern(order.getQueueName(), order.getOrderNumber()); |
| | | } catch (Exception e) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (order.getStatus() == 1) { |
| | | order.setStatus(0); |
| | | order.setAppUserId(null); |
| | | baseMapper.updateById(order); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | return; |
| | | } |
| | | /* |
| | | order.setStatus(0); |
| | | order.setAppUserId(null); |
| | | baseMapper.updateById(order); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | XpOrderCancel xpOrderCancel = new XpOrderCancel(); |
| | | xpOrderCancel.setOrderId(orderId); |
| | | xpOrderCancel.setUserId(Long.valueOf(uid)); |
| | | xpOrderCancel.setCancelSource(1); |
| | | xpOrderCancel.setCancelReason("用户取消订单"); |
| | | xpOrderCancelService.save(xpOrderCancel); |
| | | */ |
| | | |
| | | // 移除mongo数据 |
| | | xpPricingClient.deleteXpGeoQueryEntity(order.getId().toString()); |
| | | |
| | | // 下发命令 |
| | | if (null != order.getVehicleId()) { |
| | | else{// 下发命令 |
| | | R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(order.getVehicleId()); |
| | | // 组装调用车机参数 |
| | | CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo(); |
| | | XpVehicle xpVehicle = xpVehicleR.getData(); |
| | | if (xpVehicle == null) { |
| | | throw new ServiceException("车辆不存在", I18nKeyConstant.VEHICLE_NOT_EXISTS); |
| | | } |
| | | //是否能取消行程 |
| | | boolean cancelShow = this.isCancelShow(order,xpVehicle.getVehicleVin()); |
| | | if(cancelShow){ |
| | | throw new ServiceException("当前订单状态不允许取消,行程即将完成", I18nKeyConstant.ORDER_CANCEL_FAILED); |
| | | } |
| | | |
| | | // 组装调用车机参数 |
| | | CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo(); |
| | | cancelTaxiPassengerVo.setVin(xpVehicle.getVehicleVin()); |
| | | cancelTaxiPassengerVo.setUid(uid); |
| | | cancelTaxiPassengerVo.setOrderNo(order.getOrderNumber()); |
| | |
| | | //车辆继续巡游 |
| | | addCruiseMission(xpVehicle.getId()); |
| | | } |
| | | order.setStatus(0); |
| | | order.setAppUserId(null); |
| | | baseMapper.updateById(order); |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 0, 24L, TimeUnit.HOURS); |
| | | |
| | | XpOrderCancel xpOrderCancel = new XpOrderCancel(); |
| | | xpOrderCancel.setOrderId(orderId); |
| | | xpOrderCancel.setUserId(Long.valueOf(uid)); |
| | | xpOrderCancel.setCancelSource(1); |
| | | xpOrderCancel.setCancelReason("用户取消订单"); |
| | | xpOrderCancelService.save(xpOrderCancel); |
| | | // 移除mongo数据 |
| | | xpPricingClient.deleteXpGeoQueryEntity(order.getId().toString()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | redisService.setCacheObject("ORDER_STATUS:" + order.getId(), 8, 24L, TimeUnit.HOURS); |
| | | |
| | | // 根据订单所属开通城市id 查询定价 |
| | | R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId()); |
| | | XpPricing pricing = pricingByCityId.getData(); |
| | | XpPricing pricing = bootCommonService.getXpPricing(order.getCityId(),order.getVehicleId()); |
| | | if (pricing == null) { |
| | | throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS); |
| | | } |
| | | |
| | | |
| | | |
| | | // 费用 |
| | | // 查询订单轨迹 |
| | | List<OrderTrajectory> trajectories = mongoTemplate.find( |
| | |
| | | * |
| | | * @param order |
| | | */ |
| | | |
| | | @Override |
| | | public void addCruiseMission(Long vehicleId, XpOrder order) { |
| | | XpVehicle vehicle = xpVehicleClient.queryById(vehicleId).getData(); |
| | | log.info("添加巡游订单 {}", vehicle.getPlateNumber()); |
| | |
| | | @Override |
| | | public R<String> feeDescription(Long orderId, String uid) { |
| | | XpOrder order = this.getById(orderId); |
| | | R<XpPricing> pricingByCityId = xpPricingClient.getPricingByCid(order.getCityId()); |
| | | XpPricing pricing = pricingByCityId.getData(); |
| | | if (pricing == null) { |
| | | XpPricing xpPricing = bootCommonService.getXpPricing(order.getCityId(), order.getVehicleId()); |
| | | if (xpPricing == null) { |
| | | throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS); |
| | | } else { |
| | | return R.ok(pricing.getPriceRule()); |
| | | return R.ok(xpPricing.getPriceRule()); |
| | | } |
| | | } |
| | | |
| | |
| | | if (xpOrder.getVehicleId() != null) { |
| | | R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId()); |
| | | XpVehicle vehicle = xpVehicleR.getData(); |
| | | xpOrderDetailVO.setVehicleVin(vehicle.getVehicleVin()); |
| | | xpOrderDetailVO.setVehicleModel(vehicle.getVehicleModel()); |
| | | xpOrderDetailVO.setVehicleColor(vehicle.getVehicleColor()); |
| | | xpOrderDetailVO.setPlateNumber(vehicle.getPlateNumber()); |
| | | xpOrderDetailVO.setVehiclePictures(vehicle.getVehiclePictures()); |
| | | } |
| | |
| | | xpOrder.setAppUserId(null); |
| | | this.updateById(xpOrder); |
| | | } |
| | | Boolean cancelShow = true; //是否能取消行程 |
| | | xpOrderDetailVO.setCancelShow(cancelShow); |
| | | |
| | | |
| | | |
| | | return xpOrderDetailVO; |
| | | } |
| | | |
| | | @Override |
| | | public XpOrderDetailVO getActiveOrder_itineraryManage(String uid){ |
| | | XpOrderDetailVO xpOrderDetailVO = new XpOrderDetailVO(); |
| | | XpOrder xpOrder = this.baseMapper.selectOne(new LambdaQueryWrapper<XpOrder>().eq(XpOrder::getAppUserId, Long.parseLong(uid)).in(XpOrder::getStatus, Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)).orderByDesc(BaseModel::getCreateTime).last("LIMIT 1")); |
| | | if (xpOrder == null) { |
| | | return null; |
| | | } |
| | | BeanUtils.copyProperties(xpOrder, xpOrderDetailVO); |
| | | if (xpOrder.getVehicleId() != null) { |
| | | R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId()); |
| | | XpVehicle vehicle = xpVehicleR.getData(); |
| | | xpOrderDetailVO.setVehicleVin(vehicle.getVehicleVin()); |
| | | xpOrderDetailVO.setVehicleModel(vehicle.getVehicleModel()); |
| | | xpOrderDetailVO.setVehicleColor(vehicle.getVehicleColor()); |
| | | xpOrderDetailVO.setPlateNumber(vehicle.getPlateNumber()); |
| | | |
| | | xpOrderDetailVO.setVehiclePictures(vehicle.getVehiclePictures()); |
| | | } |
| | | Boolean cancelShow = isCancelShow(xpOrder,xpOrderDetailVO.getVehicleVin()); //是否能取消行程 |
| | | xpOrderDetailVO.setCancelShow(cancelShow); |
| | | return xpOrderDetailVO; |
| | | } |
| | | /** |
| | | * 取消行程:若处于“送驾中”且离目的地小于10分钟路程(后台配置),【取消行程】按钮应置灰; |
| | | * 修改行程: |
| | | * 1. 当前剩余里程 < 800米 (后台配置)或 剩余时间 < 5分钟(后台配置)(以先到者为准),禁止修改,按钮置灰。 |
| | | * 2. 单次行程最多允许修改 2次 (后台配置)目的地,防恶意高频调用 |
| | | * 特殊豁免:若系统检测到车辆在当前坐标时速 < 3km/h 且持续时间 > 3分钟(后台配置)(判定为极度拥堵或异常停滞),此时解除限制,允许用户修改目的地或新增途径点以寻找更近的下车位置。 |
| | | * @return |
| | | */ |
| | | private Boolean isCancelShow(){ |
| | | private boolean isCancelShow(XpOrder xpOrder,String vehicleVin) { |
| | | boolean isCancel = false; |
| | | //获取配置文件 |
| | | int sylc = 800;//单位米 todo yyy 需要读取后台配置文件 |
| | | int sysj = 5;//单位分钟 todo yyy 需要读取后台配置文件 |
| | | // 减少3分钟 获取3分账内的 行程数据 |
| | | long minute =3;//todo yyy 需要读取后台配置文件 |
| | | |
| | | return true; |
| | | |
| | | List<OrderTrajectory> orderTrajectories = queryOrderTrajectories(xpOrder.getId()); |
| | | if(!orderTrajectories.isEmpty()){// 减少3分钟 获取3分账内的 行程数据 |
| | | //3千米/小时 转换成分钟 50米/分钟 |
| | | BigDecimal suduDefault = new BigDecimal("3");//3千米/小时 |
| | | BigDecimal suduDefault1 = suduDefault.multiply(BigDecimal.valueOf(1000)) ; |
| | | BigDecimal suduDefaultNew =suduDefault1.divide(BigDecimal.valueOf(60),2,RoundingMode.HALF_EVEN); |
| | | |
| | | LocalDateTime minutesBefore = LocalDateTime.now().minusMinutes(minute); |
| | | long milliseconds = DateUtils.getMilliseconds(minutesBefore); |
| | | List<OrderTrajectory> orderTrajectoriesNew = new ArrayList<>(); |
| | | for (OrderTrajectory orderTrajectory : orderTrajectories) { |
| | | if(orderTrajectory.getLocatetime() > milliseconds){ |
| | | orderTrajectoriesNew.add(orderTrajectory); |
| | | } |
| | | } |
| | | /* |
| | | 获取最近3分钟的 数据 速度、平均 |
| | | */ |
| | | //计算行驶总距离和时长 |
| | | Double reduce = orderTrajectoriesNew.stream().map(OrderTrajectory::getDistance).reduce(0.0, Double::sum); |
| | | BigDecimal xcsudu = new BigDecimal(reduce).divide(new BigDecimal(minute),2, RoundingMode.HALF_EVEN);//米/分钟 |
| | | |
| | | //特殊豁免:若系统检测到车辆在当前坐标时速 < 3km/h 且持续时间 > 3分钟(后台配置)(判定为极度拥堵或异常停滞),此时解除限制,允许用户修改目的地或新增途径点以寻找更近的下车位置。 |
| | | if(xcsudu.compareTo(suduDefaultNew)<0){ |
| | | return true; |
| | | } |
| | | } |
| | | RouteVo routeVo = this.getRouteVo(xpOrder, vehicleVin); |
| | | if(routeVo.getDistance() <sylc){ |
| | | isCancel = true; |
| | | } |
| | | if(routeVo.getDuration() < sysj){ |
| | | isCancel = true; |
| | | } |
| | | |
| | | return isCancel; |
| | | } |
| | | |
| | | /** |
| | | * 获取两个点位车的距离 和时间 |
| | | * @param xpOrder |
| | | * @param vehicleVin |
| | | * @return |
| | | */ |
| | | private RouteVo getRouteVo(XpOrder xpOrder,String vehicleVin){ |
| | | |
| | | VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vehicleVin)), VehiclePosition.class); |
| | | // 计算距离 和 时间 |
| | | 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(xpOrder.getEndLon()); |
| | | lonLatDto1.setLatitude(xpOrder.getEndLat()); |
| | | routeAndFareDto.setDestination(lonLatDto1); |
| | | |
| | | // XpOpenCity xpOpenCity = xpOpenCityMapper.selectById(dto.getOpenCityId()); |
| | | // xpRoutePlanClient. |
| | | XpRoutePlan xpRoutePlan = xpRoutePlanClient.getXpRoutePlanOpenCityId(xpOrder.getCityId()).getData(); |
| | | if (xpRoutePlan != null) { |
| | | routeAndFareDto.setRoutePlanRule(xpRoutePlan.getRoutePlanRule()); |
| | | } |
| | | R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto); |
| | | if(distanceAndDuration.getCode()!=200){ |
| | | throw new ServiceException("未找到路径", I18nKeyConstant.PATH_NOT_FOUND); |
| | | } |
| | | return distanceAndDuration.getData(); |
| | | } |
| | | |
| | | |