xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java
@@ -127,6 +127,13 @@ log.error("确定用户类型失败,原因: {}", cause.getMessage()); return R.fail("确定用户类型失败"); } @Override public R<Long> getUserOrderNum(Long userId) { log.error("获取用户订单数量失败,原因: {}", cause.getMessage()); return R.fail("获取用户订单数量失败"); } }; } } xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpOrderClient.java
@@ -160,4 +160,13 @@ */ @PostMapping("/logan/inner/order/determineUserType") R<Integer> determineUserType(@RequestParam Long userId); /** * 获取用户订单数量 * @param userId * @return */ @PostMapping("/logan/inner/order/getUserOrderNum") R<Long> getUserOrderNum(@RequestParam Long userId); } xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/map/XpTestGeoFencingProhibitedPolygon.java
New file @@ -0,0 +1,50 @@ package com.xiaopeng.api.model.map; import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.geo.GeoJsonPolygon; import org.springframework.data.mongodb.core.index.GeoSpatialIndexType; import org.springframework.data.mongodb.core.index.GeoSpatialIndexed; import org.springframework.data.mongodb.core.mapping.Document; import java.io.Serializable; /** * 禁行地理围栏-多边形 * @author zhibing.pu * @date 2023/4/29 23:53 */ @Data @Document(collection = "test_prohibited_area") public class XpTestGeoFencingProhibitedPolygon implements Serializable { private static final long serialVersionUID = 4508868382007529971L; @Id private String id; /** * 围栏id */ private String fenceId; /** * 围栏名称 */ private String name; /** * 围栏区域id */ private String areaId; /** * 场站id */ private String stationId; /** * 多边形经纬度 */ @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE) private GeoJsonPolygon points; } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -1202,12 +1202,6 @@ } break; case ORDER_PASSENGER_ONBOARD: // //先手动暂停触发,因为现目前车机响应状态时机不对 // try { // Thread.sleep(waittime); // } catch (InterruptedException e) { // throw new RuntimeException(e); // } //乘客已上车 if(!orderId.contains("XU")){ if(orderId.contains("TEST")){ xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/constant/I18nKeyConstant.java
@@ -12,7 +12,9 @@ String NO_CURRENT_REGION = "no.current.region"; String NO_PERMISSION = "no.permission"; String MAX_ORDER_NUM = "max.order.num"; String NO_CURRENT_POINT = "no.current.point"; xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -8,12 +8,15 @@ import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaopeng.api.dto.account.GetUserCouponDto; import com.xiaopeng.api.dto.account.UcUserInfo; import com.xiaopeng.api.dto.map.RouteAndFareDto; import com.xiaopeng.api.dto.map.RouteStaleCheckDto; import com.xiaopeng.api.dto.map.SelectNavigationRouteDto; import com.xiaopeng.api.enums.RouteStrategyKind; import com.xiaopeng.api.feignClient.account.UserResourcesClient; import com.xiaopeng.api.feignClient.account.UserRoutePlanRuleClient; import com.xiaopeng.api.feignClient.account.XpAppUserClient; import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient; @@ -145,6 +148,8 @@ private XpTargetedServiceClient xpTargetedServiceClient; @Resource private XpTradingStrategyClient xpTradingStrategyClient; @Resource private UserResourcesClient userResourcesClient; @Resource(name = "hutoolSnowflake") private Snowflake snowflake; @@ -557,6 +562,21 @@ @Override public String saveOrder(XpOrderDto dto, String uid) { //校验白名单用户 UcUserInfo userInfo = userResourcesClient.getBaseUserByUid(uid); XpWhitelist xpWhitelist = xpWhitelistMapper.selectOne(new QueryWrapper<XpWhitelist>().eq("account", userInfo.getMobile()) .eq("status", 1).last(" and (DATE(expire_time) < DATE(NOW()) or expire_time is null)")); if(null == xpWhitelist){ throw new ServiceException("未授权用户,不能使用该功能", I18nKeyConstant.NO_PERMISSION); } //判断最大下单数 if(null != xpWhitelist.getMaxOrderNum() && xpWhitelist.getMaxOrderNum()>0){ Long count = xpOrderClient.getUserOrderNum(Long.valueOf(uid)).getData(); if(xpWhitelist.getMaxOrderNum() <= count){ throw new ServiceException("已达到最大下单数量,不能使用该功能", I18nKeyConstant.MAX_ORDER_NUM); } } // 是否在运营区域时间内 XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(dto.getXpElectronicFenceAreaId()); XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(xpElectronicFenceArea.getElectronicId()); xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages.properties
@@ -7,4 +7,6 @@ to.work=当前的接送点距离过近。建议步行前往 wait.time=当前区域正在等待中,请耐心等待 walking.route.not.found=未找到步行路线 welcome.message=欢迎来到我们的应用程序! welcome.message=欢迎来到我们的应用程序! no.permission=未授权用户,不能使用该功能 max.order.num=已达到最大下单数量,不能使用该功能 xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_en_US.properties
@@ -7,4 +7,6 @@ to.work=\ The current pick-up and drop-off points are too close to each other. It is recommended to walk there wait.time=The current area is in a waiting state. Please be patient walking.route.not.found=walking.route.not.found welcome.message=Welcome to our application! welcome.message=Welcome to our application! no.permission=Unauthorized users are not allowed to use this function. max.order.num=The maximum order quantity has been reached. This function cannot be used. xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -7,4 +7,6 @@ to.work=当前的接送点距离过近。建议步行前往 wait.time=当前区域正在等待中,请耐心等待 walking.route.not.found=未找到步行路线 welcome.message=欢迎来到我们的应用程序! welcome.message=欢迎来到我们的应用程序! no.permission=未授权用户,不能使用该功能 max.order.num=已达到最大下单数量,不能使用该功能 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestElectronicFenceManagementController.java
@@ -85,17 +85,8 @@ PageInfo<XpTestElectronicFence> pageList = xpElectronicFenceService.pageList(query); return R.ok(pageList); } /** * 电子围栏列表接口 * * @return 电子围栏列表 */ @ApiOperation(value = "电子围栏列表接口", tags = {"运维APP-电子围栏"}) @GetMapping("/maintenance-app/api/v1/electronicFence/list") public R<List<XpTestElectronicFence>> vehicleMap() { List<XpTestElectronicFence> list = xpElectronicFenceService.list(); return R.ok(list); } /** * 新增电子围栏 */ xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpTestElectronicFenceServiceImpl.java
@@ -12,6 +12,8 @@ import com.xiaopeng.api.dto.operation.TestElectronicFenceUpdateDto; import com.xiaopeng.api.model.map.XpGeoFencingPolygon; import com.xiaopeng.api.model.map.XpGeoFencingProhibitedPolygon; import com.xiaopeng.api.model.map.XpTestGeoFencingPolygon; import com.xiaopeng.api.model.map.XpTestGeoFencingProhibitedPolygon; import com.xiaopeng.api.model.operation.*; import com.xiaopeng.api.query.operation.ElectronicPageListQuery; import com.xiaopeng.common.core.domain.R; @@ -235,7 +237,7 @@ newArea.getFencePoints(), existingArea.getFencePoints())) { throw new ServiceException( "运营区域{}与现有运营区域{}发生重叠", "运营区域{}与现有测试区域{}发生重叠", I18nKeyConstant.AREA_OVERLAP_ERROR, new Object[]{existingArea.getAreaName(), existingArea.getAreaName()} ); @@ -312,7 +314,7 @@ for (XpTestElectronicFenceArea newElectronicFenceArea : newElectronicFenceAreas) { if (newElectronicFenceArea.getAreaType() == 1 && newElectronicFenceArea.getAreaStatus() == 1) { XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon(); XpTestGeoFencingPolygon xpGeoFencingPolygon = new XpTestGeoFencingPolygon(); xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName()); xpGeoFencingPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId())); @@ -325,7 +327,7 @@ } if (newElectronicFenceArea.getAreaType() == 2 && newElectronicFenceArea.getAreaStatus() == 1) { XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon(); XpTestGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpTestGeoFencingProhibitedPolygon(); xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName()); xpGeoFencingProhibitedPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId())); @@ -371,7 +373,7 @@ res.add(updatedArea.getAreaName()); res.add(existingArea.getAreaName()); throw new ServiceException( "运营区域{}与现有运营区域{}发生重叠,请编辑已有的运营区域", "运营区域{}与现有测试区域{}发生重叠,请编辑已有的运营区域", I18nKeyConstant.AREA_OVERLAP_ERROR, res.toArray() ); @@ -442,10 +444,10 @@ Query delMongoQuery = new Query(); delMongoQuery.addCriteria(Criteria.where("fenceId").is(String.valueOf(dto.getId()))); delMongoQuery.addCriteria(Criteria.where("areaId").in(toDeleteAreaIdStrings)); mongoTemplate.remove(delMongoQuery, XpGeoFencingProhibitedPolygon.class); mongoTemplate.remove(delMongoQuery, XpTestGeoFencingProhibitedPolygon.class); } // 删除旧的区域数据,然后保存新的区域数据 mongoTemplate.remove(new Query(Criteria.where("fenceId").is(String.valueOf(dto.getId()))), XpGeoFencingPolygon.class); mongoTemplate.remove(new Query(Criteria.where("fenceId").is(String.valueOf(dto.getId()))), XpTestGeoFencingPolygon.class); if (xpElectronicFence.getStatus() == 2) { // 设置电子围栏ID并保存区域数据 for (XpTestElectronicFenceArea area : updatedElectronicFenceAreas) { @@ -487,7 +489,7 @@ query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); XpGeoFencingPolygon old = mongoTemplate.findOne(query, XpGeoFencingPolygon.class); if (old == null) { XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon(); XpTestGeoFencingPolygon xpGeoFencingPolygon = new XpTestGeoFencingPolygon(); xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName()); xpGeoFencingPolygon.setCityCode(cityCode); @@ -520,7 +522,7 @@ query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); XpGeoFencingProhibitedPolygon old = mongoTemplate.findOne(query, XpGeoFencingProhibitedPolygon.class); if (old == null) { XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon(); XpTestGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpTestGeoFencingProhibitedPolygon(); xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId())); xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName()); xpGeoFencingProhibitedPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId())); @@ -542,7 +544,7 @@ Query query = new Query(); query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId()))); query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId()))); mongoTemplate.remove(query, XpGeoFencingProhibitedPolygon.class); mongoTemplate.remove(query, XpTestGeoFencingProhibitedPolygon.class); } } } @@ -616,11 +618,11 @@ continue; } try { boolean inOperatingArea = xpGeoFencingPolygonService.isInFence(lon, lat, fenceId, "operating_area"); boolean inOperatingArea = xpGeoFencingPolygonService.isInFence(lon, lat, fenceId, "test_operating_area"); if (!inOperatingArea) { continue; } boolean inProhibitedArea = xpGeoFencingPolygonService.isInFence(lon, lat, fenceId, "prohibited_area"); boolean inProhibitedArea = xpGeoFencingPolygonService.isInFence(lon, lat, fenceId, "test_prohibited_area"); if (inProhibitedArea) { continue; } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/constant/I18nKeyConstant.java
@@ -19,6 +19,9 @@ String ORDER_REASSIGN_NEW_VEHICLE_NOT_IN_ACCEPT_MODE = "order.reassign.new.vehicle.not.in.accept.mode"; String ORDER_REASSIGN_NEW_VEHICLE_NOT_START_ACCEPT = "order.reassign.new.vehicle.not.start.accept"; String ORDER_REASSIGN_NEW_VEHICLE_NOT_FREE = "order.reassign.new.vehicle.not.free"; String ORDER_REASSIGN_NEW_VEHICLE_NOT_OPERATIONAL = "order.reassign.new.vehicle.not.operational"; String ORDER_REASSIGN_NEW_VEHICLE_NOT_POSITION = "order.reassign.new.vehicle.not.position"; String ORDER_REASSIGN_NEW_VEHICLE_BATTERY_LOW = "order.reassign.new.vehicle.battery"; String ORDER_STATUS_ERROR = "order.status.error"; String ORDER_CHANGE_AMOUNT_ID_REQUIRED = "order.change.amount.id.required"; String ORDER_CHANGE_AMOUNT_AMOUNT_REQUIRED = "order.change.amount.amount.required"; xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -730,4 +730,17 @@ return R.ok(3); } } /** * 获取用户订单数量 * @param userId * @return */ @PostMapping("/logan/inner/order/getUserOrderNum") public R<Long> getUserOrderNum(@RequestParam Long userId){ long count = xpOrderService.count(new QueryWrapper<XpOrder>().eq("app_user_id", userId) .ne("status", 0).eq("is_deleted", 0)); return R.ok(count); } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/TimeJobType.java
@@ -6,6 +6,7 @@ */ public enum TimeJobType { ORDER_CANCEL("order_cancel","订单取消"), TEST_ORDER_CANCEL("test_order_cancel","测试订单取消"), ADD_CRUISE_MISSION("add_cruise_mission","添加巡游任务"), ADD_CHAIN_REACTION_ORDER_MISSION("add_cruise_mission","添加派送连环单任务"), END_TRIP("end_trip","自动结束行程"); xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/TestOrderCancelJob.java
New file @@ -0,0 +1,58 @@ package com.xiaopeng.order.job.jobs; import com.xiaopeng.api.model.order.XpOrder; import com.xiaopeng.api.model.order.XpTestOrder; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.order.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.Objects; /** * 直播推送定时任务 * @author Administrator * */ @Slf4j public class TestOrderCancelJob extends AbstractJob { public static final String name = "testOrderCancel_"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long orderId = maps.getLong("id"); try { log.info("开始执行订单取消任务"); XpTestOrder xpOrder = testOrderService.getById(orderId); if(Objects.nonNull(xpOrder) && (xpOrder.getStatus()==4 || xpOrder.getStatus()==5)){ Integer status = xpOrder.getStatus(); log.info("订单取消开始"); testOrderService.cancelTestOrderById(xpOrder.getId()); // 下发命令 if (null != xpOrder.getVehicleId()) { R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId()); XpVehicle xpVehicle = xpVehicleR.getData(); //还原车辆状态为空闲 if(1 == xpVehicle.getState()){ XpVehicle vehicle1 = new XpVehicle(); vehicle1.setId(xpVehicle.getId()); vehicle1.setState(0); xpVehicleClient.updateVehicleById(vehicle1); log.info("订单定时取消,车辆状态修改0 {}", xpVehicle.getPlateNumber()); } //下发车机取消命令 } log.info("订单取消状态修改完成"); } }catch(Exception e){ e.printStackTrace(); } } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -1015,6 +1015,16 @@ if (Objects.isNull(newVehicle.getState()) || newVehicle.getState() != 0) { throw new ServiceException("新车辆已接单,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_FREE); } if (newVehicle.getOperatingStatus() != 1){ throw new ServiceException("新车辆状态为非运营状态,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_OPERATIONAL); } VehiclePosition vehiclePosition = mongoTemplate.findOne(Query.query(Criteria.where("vin").is(newVehicle.getVehicleVin())), VehiclePosition.class); if(null == vehiclePosition){ throw new ServiceException("未能获取到新车的定位数据,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_POSITION); } if(vehiclePosition.getCurrentElectricity() < 20){ throw new ServiceException("新车电量不足,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_BATTERY_LOW); } // 6. 保存原车辆和车队信息 Long oldVehicleId = order.getVehicleId(); xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java
@@ -52,6 +52,7 @@ import com.xiaopeng.order.job.base.TimeJobType; import com.xiaopeng.order.job.jobs.EndTripJob; import com.xiaopeng.order.job.jobs.OrderCancelJob; import com.xiaopeng.order.job.jobs.TestOrderCancelJob; import com.xiaopeng.order.mangodb.model.OrderTrajectory; import com.xiaopeng.order.mapper.XpCruiseOrderMapper; import com.xiaopeng.order.mapper.XpTestOrderDetailMapper; @@ -138,6 +139,9 @@ @Resource private BootCommonService bootCommonService; @Resource private XpTradingStrategyClient tradingStrategyClient; @Resource(name = "hutoolSnowflake") private Snowflake snowflake; @@ -896,9 +900,9 @@ put("id", xpOrder.getId()) .build(); QuartzManager.addJob( OrderCancelJob.class, (OrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ORDER_CANCEL, TestOrderCancelJob.class, (TestOrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.TEST_ORDER_CANCEL, DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(xpPoint.getParkingTimeLimit())), cancelJobMaps ); @@ -910,9 +914,27 @@ xpOrder.setBoardingTime(now); xpOrder.setRideTime(now); // 删除定时任务job QuartzManager.removeJob((OrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ORDER_CANCEL); QuartzManager.removeJob((TestOrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.TEST_ORDER_CANCEL); //乘客已上车,重新倒计时不开始行程取消订单 XpTestPoint xpPoint1 = xpTestPointClient.queryById(xpOrder.getStartTestPointId()).getData(); XpTradingStrategy tradingStrategy = tradingStrategyClient.getTradingStrategyByCityCode(xpPoint1.getCityCode()).getData(); if(null != tradingStrategy){ Map<String, ? extends Object> cancelJobMaps1 = new ImmutableMap.Builder<String, Long>() .put("id", xpOrder.getId()) .build(); QuartzManager.addJob( TestOrderCancelJob.class, (TestOrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.TEST_ORDER_CANCEL, DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(tradingStrategy.getBdNotBoardedTime())), cancelJobMaps1 ); } break; case 6: // 删除定时任务job QuartzManager.removeJob((TestOrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.TEST_ORDER_CANCEL); // 行程开始时间 xpOrder.setTripBegin(LocalDateTime.now()); redisService.deleteObject("TEST_ORDER_NAVIGATION_START_DATA:" + xpOrder.getVehicleId()); xp-robotaxi-order-boot/src/main/resources/i18n/messages.properties
@@ -19,3 +19,6 @@ order.change.amount.status.invalid=当前订单状态不允许改价,只有待付款状态的订单可以改价 order.change.amount.failed=订单改价失败,请稍后重试 path.not.found=获取导航信息失败 order.reassign.new.vehicle.not.operational=新车辆状态为非运营状态,请重新选择 order.reassign.new.vehicle.not.position=未能获取到新车的定位数据,请重新选择 order.reassign.new.vehicle.battery=新车电量不足,请重新选择 xp-robotaxi-order-boot/src/main/resources/i18n/messages_en_US.properties
@@ -20,3 +20,6 @@ order.change.amount.status.invalid=The current order status does not allow price changes. Only pending payment orders can be changed. order.change.amount.failed=Failed to change order amount. Please try again later. path.not.found=Failed to obtain navigation information order.reassign.new.vehicle.not.operational=The status of the new vehicle is not in operation. Please select again. order.reassign.new.vehicle.not.position=Failed to obtain the positioning data of the new car. Please select again. order.reassign.new.vehicle.battery=The battery of the new car is low. Please choose another one. xp-robotaxi-order-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -20,3 +20,6 @@ order.change.amount.status.invalid=当前订单状态不允许改价,只有待付款状态的订单可以改价 order.change.amount.failed=订单改价失败,请稍后重试 path.not.found=获取导航信息失败 order.reassign.new.vehicle.not.operational=新车辆状态为非运营状态,请重新选择 order.reassign.new.vehicle.not.position=未能获取到新车的定位数据,请重新选择 order.reassign.new.vehicle.battery=新车电量不足,请重新选择