From c4650572e6dc6c6efb6e1c61c11dcae0706105c7 Mon Sep 17 00:00:00 2001 From: 44323 <443237572@qq.com> Date: 星期二, 04 六月 2024 21:11:20 +0800 Subject: [PATCH] Merge branch '2.0' of http://120.76.84.145:10101/gitblit/r/java/IgoTravel into 2.0 --- ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java | 895 +++++++++++++++ UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java | 99 + ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TIntegralOrderController.java | 105 + ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tOrderPrivateCar/tOrderPrivateCar_orderDetail.html | 2 UserIGOTravel/guns-admin/pom.xml | 7 DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SettlementRecordServiceImpl.java | 7 DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverOnlineServiceImpl.java | 7 UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/controller/OrderLogisticsController.java | 12 UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/CarModelMapper.java | 11 UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java | 40 ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TDriverController.java | 7 DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java | 5 ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TUser.java | 15 UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/CarModelMapper.tld | 6 ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/home.html | 2 DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverServiceImpl.java | 36 ManagementIGOTravel/guns-admin/pom.xml | 6 DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java | 37 ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderPrivateCarController.java | 14 UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java | 895 +++++++++++++++ ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java | 2 UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java | 2 DriverIGOTravel/guns-admin/pom.xml | 7 UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/CarModel.java | 120 ++ ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderLogisticsController.java | 12 DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java | 48 DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/BalanceUsageRecordServiceImpl.java | 9 DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java | 895 +++++++++++++++ DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java | 2 29 files changed, 3,260 insertions(+), 45 deletions(-) diff --git a/DriverIGOTravel/guns-admin/pom.xml b/DriverIGOTravel/guns-admin/pom.xml index 3368502..fb326c6 100644 --- a/DriverIGOTravel/guns-admin/pom.xml +++ b/DriverIGOTravel/guns-admin/pom.xml @@ -296,6 +296,13 @@ <artifactId>c3p0</artifactId> <version>0.9.5.5</version> </dependency> + + <!--Google ODRD--> + <dependency> + <groupId>com.google.maps</groupId> + <artifactId>fleetengine-auth</artifactId> + <version>1.11.0</version> + </dependency> </dependencies> <build> diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java index 633bdf4..de6609c 100644 --- a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java @@ -1196,7 +1196,6 @@ return ResultUtil.tokenErr(); } List<Map<String, Object>> list = driverService.queryTotalRevenue(language, uid, pageNum, size); - // TODO 待翻译 List<BaseWarpper> data = new ArrayList<>(); for(Map<String, Object> map : list){ String type = map.get("type").toString(); @@ -1207,7 +1206,7 @@ switch (Integer.valueOf(String.valueOf(null != map.get("orderType") ? map.get("orderType") : 0))){ case 1: OrderPrivateCar orderPrivateCar = orderPrivateCarService.selectById(map.get("incomeId").toString()); - baseWarpper.setName(language == 1 ? (orderPrivateCar.getCancelMidway() == 0 ? "" : "【途中取消】") + "打车" : language == 2 ? (orderPrivateCar.getCancelMidway() == 0 ? "" : "【】") + "Ride" : (orderPrivateCar.getCancelMidway() == 0 ? "" : "【】") + "Course"); + baseWarpper.setName(language == 1 ? (orderPrivateCar.getCancelMidway() == 0 ? "" : "【途中取消】") + "打车" : language == 2 ? (orderPrivateCar.getCancelMidway() == 0 ? "" : "【Cancelled during the trip】") + "Ride" : (orderPrivateCar.getCancelMidway() == 0 ? "" : "【Annulé en cours de voyage】") + "Course"); break; case 2: baseWarpper.setName(language == 1 ? "出租车" : language == 2 ? "taxi" : "taxi"); @@ -1217,7 +1216,7 @@ break; case 4: OrderLogistics orderLogistics = orderLogisticsService.selectById(map.get("incomeId").toString()); - baseWarpper.setName(language == 1 ? (orderLogistics.getCancelMidway() == 0 ? "" : "【途中取消】") + "包裹" : language == 2 ? (orderLogistics.getCancelMidway() == 0 ? "" : "【】") + "Delivery" : (orderLogistics.getCancelMidway() == 0 ? "" : "【】") + "Livraison"); + baseWarpper.setName(language == 1 ? (orderLogistics.getCancelMidway() == 0 ? "" : "【途中取消】") + "包裹" : language == 2 ? (orderLogistics.getCancelMidway() == 0 ? "" : "【Cancelled during the trip】") + "Delivery" : (orderLogistics.getCancelMidway() == 0 ? "" : "【Annulé en cours de voyage】") + "Livraison"); break; case 5: baseWarpper.setName(language == 1 ? "跨城小件物流" : language == 2 ? "Cross-city small parts logistics" : "Logistique des petites pièces à travers la ville"); diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java index 94d9f52..107208a 100644 --- a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java @@ -11,13 +11,11 @@ import com.stylefeng.guns.modular.smallLogistics.server.IOrderLogisticsService; import com.stylefeng.guns.modular.smallLogistics.server.IOrderLogisticsSpreadService; import com.stylefeng.guns.modular.specialTrain.model.OrderPrivateCar; -import com.stylefeng.guns.modular.system.dao.CarMapper; -import com.stylefeng.guns.modular.system.dao.RegionMapper; -import com.stylefeng.guns.modular.system.dao.SystemPriceMapper; -import com.stylefeng.guns.modular.system.dao.UserInfoMapper; +import com.stylefeng.guns.modular.system.dao.*; import com.stylefeng.guns.modular.system.model.*; import com.stylefeng.guns.modular.system.service.*; import com.stylefeng.guns.modular.system.util.*; +import com.stylefeng.guns.modular.system.util.GoogleMap.FleetEngineUtil; import com.stylefeng.guns.modular.system.util.itextpdf.HtmlToPdfUtils; import com.stylefeng.guns.modular.system.util.quartz.QuartzUtil; import com.stylefeng.guns.modular.system.util.quartz.jobs.OrderTimeOutJob; @@ -115,6 +113,15 @@ @Resource private SystemPriceMapper systemPriceMapper; + + @Autowired + private FleetEngineUtil fleetEngineUtil; + + @Resource + private CarModelMapper carModelMapper; + + @Autowired + private ICarService carService; @@ -168,7 +175,6 @@ driver.setState(3); driverService.updateById(driver); - //todo 待翻译 //添加定时任务(普通任务) ReminderRules reminderRules = reminderRulesService.selectOne(new EntityWrapper<ReminderRules>().eq("companyId", driver.getCompanyId())); if(null != reminderRules){ @@ -179,13 +185,26 @@ jobDataMap.put("driverId", uid); jobDataMap.put("orderId", orderLogistics.getId()); jobDataMap.put("orderType", 4); - jobDataMap.put("describe", "您的包裹订单已超时" + m + "分钟,请抓紧!"); + jobDataMap.put("describe", language == 1 ? "您的包裹订单已超时" + m + "分钟,请抓紧!" : language == 2 ? "Your delivery order is overdue for " + m + " minute(s), please go faster." : "Votre commande de livraison est en retard depuis " + m + " minute(s), veuillez aller plus vite."); QuartzUtil.addSimpleQuartzTask( new OrderTimeOutJob().buildQuartzJob(UUIDUtil.getRandomCode(5) + "_" + orderLogistics.getId() + "_4", "ORDER_TIME_OUT", jobDataMap) , new Date(packageTimeoutReminderInterval), packageTimeoutReminderInterval, -1); } - - + + String trip = fleetEngineUtil.getTrip(1, orderLogistics.getId()); + if(ToolUtil.isEmpty(trip)){ + String vehicles = fleetEngineUtil.getVehicles(orderLogistics.getCarId()); + if(ToolUtil.isEmpty(vehicles)){ + Car car = carService.selectById(orderLogistics.getCarId()); + CarModel carModel = carModelMapper.selectById(car.getCarModelId()); + fleetEngineUtil.createVehicles(carModel.getSeat() - 1, car.getCarLicensePlate(), car.getId()); + } + fleetEngineUtil.createTrip(orderLogistics.getCarId(), 1, 4, orderLogistics.getId(), + orderLogistics.getStartLat().toString(), orderLogistics.getStartLon().toString(), orderLogistics.getEndLat().toString(), orderLogistics.getEndLon().toString()); + }else{ + //开始修改行程数据 + fleetEngineUtil.updateTrip(null, driver.getCarId(), null, 4, orderLogistics.getId(), null, null, null, null); + } //推送相关代码------------------start---------------- new Thread(new Runnable() { @@ -257,19 +276,22 @@ } List<OrderLogisticsSpread> orderLogisticsId = spreadService.selectList(new EntityWrapper<OrderLogisticsSpread>().eq("orderLogisticsId", orderLogistics.getId()).eq("payType",4)); - - + + + String tripStatus = "UNKNOWN_TRIP_STATUS"; switch (state){ case 3://出发前往预约点 orderLogistics.setState(3); orderLogistics.setSetOutTime(new Date()); systemNoticeService.addSystemNotice(1, language == 1 ? "司机已出发,请耐心等待" : language == 2 ? "The driver is on the way, please wait." : "Le chauffeur est en route. Veuillez patienter.", orderLogistics.getUserId()); pushUtil.pushDriverPosition(orderId, 4); + tripStatus = "ENROUTE_TO_PICKUP"; break; case 4://到达预约点,等待客户上车 orderLogistics.setState(4); orderLogistics.setArriveTime(new Date()); systemNoticeService.addSystemNotice(1, language == 1 ? "司机已到达您设置的预约地点。" : language == 2 ? "The driver has arrived at the reserved location." : "Le chauffeur est arrivé à l'endroit prévu.", orderLogistics.getUserId()); + tripStatus = "ARRIVED_AT_PICKUP"; break; case 5://开始服务 orderLogistics.setBoardingLon(lon); @@ -278,6 +300,7 @@ orderLogistics.setBoardingTime(new Date()); orderLogistics.setState(5); orderLogistics.setStartServiceTime(new Date()); + tripStatus = "ENROUTE_TO_DROPOFF"; break; case 6://结束服务 orderLogistics.setGetoffLon(lon); @@ -286,9 +309,14 @@ orderLogistics.setGetoffTime(new Date()); orderLogistics.setEndServiceTime(new Date()); orderLogistics.setState(6); + tripStatus = "COMPLETE"; break; } this.updateById(orderLogistics); + + Driver driver = driverService.selectById(orderLogistics.getDriverId()); + //修改行程数据 + fleetEngineUtil.updateTrip(tripStatus, null, null, 4, orderLogistics.getId(), null, null, null, null); // TODO: 2020/6/5 推送状态 new Thread(new Runnable() { diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java index 2337ffb..222bdfa 100644 --- a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java @@ -8,12 +8,14 @@ import com.stylefeng.guns.modular.specialTrain.dao.OrderPrivateCarMapper; import com.stylefeng.guns.modular.specialTrain.model.OrderPrivateCar; import com.stylefeng.guns.modular.specialTrain.server.IOrderPrivateCarService; +import com.stylefeng.guns.modular.system.dao.CarModelMapper; import com.stylefeng.guns.modular.system.dao.RegionMapper; import com.stylefeng.guns.modular.system.dao.SystemPriceMapper; import com.stylefeng.guns.modular.system.dao.UserInfoMapper; import com.stylefeng.guns.modular.system.model.*; import com.stylefeng.guns.modular.system.service.*; import com.stylefeng.guns.modular.system.util.*; +import com.stylefeng.guns.modular.system.util.GoogleMap.FleetEngineUtil; import com.stylefeng.guns.modular.system.util.quartz.QuartzUtil; import com.stylefeng.guns.modular.system.util.quartz.jobs.OrderTimeOutJob; import com.stylefeng.guns.modular.taxi.model.OrderTaxi; @@ -95,6 +97,15 @@ @Autowired private IReminderRulesService reminderRulesService; + + @Autowired + private FleetEngineUtil fleetEngineUtil; + + @Resource + private CarModelMapper carModelMapper; + + @Autowired + private ICarService carService; @@ -214,7 +225,6 @@ } - //todo 待翻译 //添加定时任务(普通任务) ReminderRules reminderRules = reminderRulesService.selectOne(new EntityWrapper<ReminderRules>().eq("companyId", driver.getCompanyId())); if(null != reminderRules){ @@ -227,7 +237,7 @@ jobDataMap.put("driverId", uid); jobDataMap.put("orderId", orderPrivateCar.getId()); jobDataMap.put("orderType", 1); - jobDataMap.put("describe", "您的打车订单已超时" + m + "分钟,请抓紧!"); + jobDataMap.put("describe", language == 1 ? "您的打车订单已超时" + m + "分钟,请抓紧!" : language == 2 ? "Your ride order is overdue for " + m + " minute(s), please go faster." : "Votre commande de course est en retard depuis " + m + " minute(s), veuillez aller plus vite."); QuartzUtil.addSimpleQuartzTask( new OrderTimeOutJob().buildQuartzJob(UUIDUtil.getRandomCode(5) + "_" + orderPrivateCar.getId() + "_1", "ORDER_TIME_OUT", jobDataMap) , new Date(specialCarTimeoutReminderInterval), specialCarTimeoutReminderInterval, -1); @@ -257,6 +267,20 @@ , new Date(appointmentReminder + appointmentTimeoutReminderInterval), appointmentTimeoutReminderInterval, -1); } } + + String trip = fleetEngineUtil.getTrip(1, orderPrivateCar.getId()); + if(ToolUtil.isEmpty(trip)){ + String vehicles = fleetEngineUtil.getVehicles(orderPrivateCar.getCarId()); + if(ToolUtil.isEmpty(vehicles)){ + Car car = carService.selectById(orderPrivateCar.getCarId()); + CarModel carModel = carModelMapper.selectById(car.getCarModelId()); + fleetEngineUtil.createVehicles(carModel.getSeat() - 1, car.getCarLicensePlate(), car.getId()); + } + fleetEngineUtil.createTrip(orderPrivateCar.getCarId(), 1, 1, orderPrivateCar.getId(), + orderPrivateCar.getStartLat().toString(), orderPrivateCar.getStartLon().toString(), orderPrivateCar.getEndLat().toString(), orderPrivateCar.getEndLon().toString()); + } + //开始修改行程数据 + fleetEngineUtil.updateTrip(null, driver.getCarId(), null, 1, orderPrivateCar.getId(), null, null, null, null); //推送相关代码------------------start---------------- new Thread(new Runnable() { @@ -320,12 +344,14 @@ if(state==4 && orderPrivateCar.getState()!=3){ return ResultUtil.error(language == 1 ? "当前订单不能到达预约地点" : language == 2 ? "The current order cannot arrive at the reservation" : "La commande en cours ne peut pas atteindre le rendez-vous"); } + String tripStatus = "UNKNOWN_TRIP_STATUS"; switch (state){ case 3://出发前往预约点 orderPrivateCar.setState(3); orderPrivateCar.setSetOutTime(new Date()); systemNoticeService.addSystemNotice(1, language == 1 ? "司机已出发,请耐心等待" : language == 2 ? "The driver is on the way, please wait." : "Le chauffeur est en route. Veuillez patienter.", orderPrivateCar.getUserId()); pushUtil.pushDriverPosition(orderPrivateCar.getId(), 1);//主动推送司机定位 + tripStatus = "ENROUTE_TO_PICKUP"; break; case 4://到达预约点,等待客户上车 orderPrivateCar.setState(4); @@ -333,6 +359,7 @@ systemNoticeService.addSystemNotice(1, language == 1 ? "司机已到达您设置的预约地点,请及时上车" : language == 2 ? "The driver has arrived at the reserved location, please get in timely." : "Le chauffeur est arrivé à l'endroit prévu, veuillez monter dans la voiture à temps.", orderPrivateCar.getUserId()); + tripStatus = "ARRIVED_AT_PICKUP"; break; case 5://开始服务 orderPrivateCar.setBoardingLon(lon); @@ -365,6 +392,7 @@ out.write(JSON.toJSONString(orderPositions)); out.flush(); out.close(); + tripStatus = "ENROUTE_TO_DROPOFF"; break; case 6://结束服务(专车可以返回继续服务)不修改状态 orderPrivateCar.setState(6); @@ -373,9 +401,14 @@ orderPrivateCar.setGetoffAddress(address); orderPrivateCar.setGetoffTime(new Date()); orderPrivateCar.setEndServiceTime(new Date()); + tripStatus = "COMPLETE"; break; } this.updateById(orderPrivateCar); + + Driver driver = driverService.selectById(orderPrivateCar.getDriverId()); + //修改行程数据 + fleetEngineUtil.updateTrip(tripStatus, null, 1, 1, orderPrivateCar.getId(), null, null, null, null); // TODO: 2020/6/5 推送状态 OrderPrivateCar finalOrderPrivateCar = orderPrivateCar; diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/BalanceUsageRecordServiceImpl.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/BalanceUsageRecordServiceImpl.java index 87347a9..a1917fc 100644 --- a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/BalanceUsageRecordServiceImpl.java +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/BalanceUsageRecordServiceImpl.java @@ -34,7 +34,6 @@ pageNum = (pageNum - 1) * size; List<Map<String, Object>> list = this.baseMapper.queryBalanceUsageRecord(driverId, type, pageNum, size); List<BalanceUsageRecordList> datas = new ArrayList<>(); - // TODO 待翻译 for (Map<String, Object> map : list) { BalanceUsageRecordList balanceUsageRecordList = new BalanceUsageRecordList(); if(null != map.get("createTime")){ @@ -52,16 +51,16 @@ balanceUsageRecordList.setContent(language == 1 ? "包裹支付" : language == 2 ? "" : ""); break; case "3": - balanceUsageRecordList.setContent(language == 1 ? "日结算" : language == 2 ? "" : ""); + balanceUsageRecordList.setContent(language == 1 ? "日结算" : language == 2 ? "Daily settlement" : "Règlement quotidien"); break; case "4": - balanceUsageRecordList.setContent(language == 1 ? "周结算" : language == 2 ? "" : ""); + balanceUsageRecordList.setContent(language == 1 ? "周结算" : language == 2 ? "Weekly settlement" : "Règlement hebdomadaire"); break; case "5": - balanceUsageRecordList.setContent(language == 1 ? "月结算" : language == 2 ? "" : ""); + balanceUsageRecordList.setContent(language == 1 ? "月结算" : language == 2 ? "Monthly settlement" : "Règlement mensuel"); break; case "6": - balanceUsageRecordList.setContent(language == 1 ? "提现" : language == 2 ? "" : ""); + balanceUsageRecordList.setContent(language == 1 ? "提现" : language == 2 ? "Withdraw" : "Retirer"); break; } } diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverOnlineServiceImpl.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverOnlineServiceImpl.java index 1a42934..f88985a 100644 --- a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverOnlineServiceImpl.java +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverOnlineServiceImpl.java @@ -182,6 +182,7 @@ continue; } Integer driverId = driverOnline.getDriverId(); + Driver driver1 = driverService.selectById(driverId); long m = Double.valueOf(driverActivityOnline.getOfflineTime() * 3600000L).longValue(); //找出最后一次接单的时间 @@ -207,8 +208,10 @@ Driver driver = driverService.selectById(driverWork.getDriverId()); driver.setState(1); driverService.updateById(driver); - // TODO 待翻译 - pushUtil.pushOffline(driverOnline.getDriverId(), 2, "您已连续" + driverActivityOnline.getOfflineTime() + "小时未接单,系统将强制更改您的状态为:下班"); + Integer language = driver.getLanguage(); + pushUtil.pushOffline(driverOnline.getDriverId(), 2, language == 1 ? "您已连续" + driverActivityOnline.getOfflineTime() + "小时未接单,系统将强制更改您的状态为:下班" : + language == 2 ? "You have not been accepting orders for " + driverActivityOnline.getOfflineTime() + " hour(s) System will change your state to Off-work" : + "Vous n’acceptez pas de commandes depuis " + driverActivityOnline.getOfflineTime() + " heure(s) Le système changera votre état en Hors travail"); } } diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverServiceImpl.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverServiceImpl.java index f471517..a28d5db 100644 --- a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverServiceImpl.java +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DriverServiceImpl.java @@ -18,6 +18,7 @@ import com.stylefeng.guns.modular.system.service.*; import com.stylefeng.guns.modular.system.util.*; import com.stylefeng.guns.modular.system.util.GoogleMap.AddressComponentsVo; +import com.stylefeng.guns.modular.system.util.GoogleMap.FleetEngineUtil; import com.stylefeng.guns.modular.system.util.GoogleMap.GoogleMapUtil; import com.stylefeng.guns.modular.system.util.GoogleMap.ReverseGeocodeVo; import com.stylefeng.guns.modular.system.util.itextpdf.HtmlToPdfUtils; @@ -153,6 +154,13 @@ @Autowired private TEmailService emailService; + + @Autowired + private FleetEngineUtil fleetEngineUtil; + + + @Resource + private CarModelMapper carModelMapper; @Override @@ -1091,6 +1099,14 @@ loginWarpper.setJumpCode("200000"); } } + + //司机登录,添加谷歌上的车辆信息 + Car car = carService.selectById(driver.getCarId()); + String vehicles = fleetEngineUtil.getVehicles(driver.getCarId()); + if(ToolUtil.isEmpty(vehicles)){ + CarModel carModel = carModelMapper.selectById(car.getCarModelId()); + fleetEngineUtil.createVehicles(carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + } return ResultUtil.success(loginWarpper); } @@ -1164,6 +1180,7 @@ public ResultUtil work(Integer uid, String type, Integer language) throws Exception { DriverWork driverWork = driverWorkMapper.queryNewWork(uid, null, 1); Driver driver = this.selectById(uid); + Car car = carService.selectById(driver.getCarId()); if(null != driverWork){//作下班操作 //检测是否有未完成的订单 List<Map<String, Object>> list = orderService.queryOrderList(1, 1, 10, uid, language); @@ -1174,6 +1191,15 @@ driverWork.setState(2); driverWorkMapper.updateById(driverWork); driver.setState(1); + + //司机下班,修改谷歌上的车辆信息 + CarModel carModel = carModelMapper.selectById(car.getCarModelId()); + String vehicles = fleetEngineUtil.getVehicles(driver.getCarId()); + if(ToolUtil.isEmpty(vehicles)){ + fleetEngineUtil.createVehicles(carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + }else{ + fleetEngineUtil.updateVehicles("OFFLINE", carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + } }else{ LoginWarpper loginWarpper = new LoginWarpper(); if(driver.getCompanyId()==null){ @@ -1192,7 +1218,6 @@ if(driver.getAuthState()==4){ return ResultUtil.error(language == 1 ? "请完善资料后再出车" : language == 2 ? "Please complete data before driving." : "Veuillez compléter les données avant de conduire."); } - Car car = carService.selectById(driver.getCarId()); if(car==null){ return ResultUtil.error(language == 1 ? "请完善资料后再出车" : language == 2 ? "Please complete data before driving." : "Veuillez compléter les données avant de conduire."); } @@ -1209,6 +1234,15 @@ driverWork.setType(type); driverWorkMapper.insert(driverWork); driver.setState(2); + + //司机上班,修改谷歌上的车辆信息 + CarModel carModel = carModelMapper.selectById(car.getCarModelId()); + String vehicles = fleetEngineUtil.getVehicles(driver.getCarId()); + if(ToolUtil.isEmpty(vehicles)){ + fleetEngineUtil.createVehicles(carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + }else{ + fleetEngineUtil.updateVehicles("ONLINE", carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + } } this.updateById(driver); return ResultUtil.success(); diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SettlementRecordServiceImpl.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SettlementRecordServiceImpl.java index c2738ae..dc8cfd9 100644 --- a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SettlementRecordServiceImpl.java +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SettlementRecordServiceImpl.java @@ -217,18 +217,17 @@ if(null != map.get("type")){ queryHistoricalSettlement.setType(Integer.valueOf(map.get("type").toString())); } - // TODO 待翻译 if(null != map.get("payType")){ Integer balanceType = Integer.valueOf(map.get("balanceType").toString()); switch (map.get("payType").toString()){ case "1": - queryHistoricalSettlement.setPayType(language == 1 ? "手机支付" : language == 2 ? "" : ""); + queryHistoricalSettlement.setPayType(language == 1 ? "手机支付" : language == 2 ? "Mobile Money" : "Paiement mobile"); break; case "2": - queryHistoricalSettlement.setPayType(language == 1 ? "线上支付" : language == 2 ? "" : ""); + queryHistoricalSettlement.setPayType(language == 1 ? "线上支付" : language == 2 ? "Bank Card" : "Carte bancaire"); break; default: - queryHistoricalSettlement.setPayType(language == 1 ? "余额支付(" + (balanceType == 1 ? "奖励" : "收入") + ")" : language == 2 ? "" : ""); + queryHistoricalSettlement.setPayType(language == 1 ? "余额支付(" + (balanceType == 1 ? "奖励" : "收入") + ")" : language == 2 ? "Wallet (" + (balanceType == 1 ? "Reward" : "Income") + ")" : "Portefeuille (" + (balanceType == 1 ? "Récompense" : "Revenu") + ")"); break; } } diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java new file mode 100644 index 0000000..75d54bf --- /dev/null +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java @@ -0,0 +1,895 @@ +package com.stylefeng.guns.modular.system.util.GoogleMap; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import cn.hutool.http.Method; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.fleetengine.auth.AuthTokenMinter; +import com.google.fleetengine.auth.token.FleetEngineToken; +import com.google.fleetengine.auth.token.TripClaims; +import com.google.fleetengine.auth.token.VehicleClaims; +import com.google.fleetengine.auth.token.factory.signer.*; +import com.stylefeng.guns.modular.system.util.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Fleet Engine API 工具类 + * @author zhibing.pu + * @Date 2024/5/17 9:59 + */ +@Slf4j +@Component +public class FleetEngineUtil { + + static Logger logger = LoggerFactory.getLogger(FleetEngineUtil.class); + + private final String SERVICE_ACCOUNT = "odrd2024@i-go-odrd-testing.iam.gserviceaccount.com"; + + private final String privateKeyId = "0a9a480fafb6469c0c1b2fa6dbdf6d4bebe1ebed"; + + private final String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXZoPEFZeZb0C7DXzpPsloB+rQVQAJuR+z4T9uRCz33gBsIqrz1s5Iwd8vXYKKWzukMdXkwqR4WapI/4GtcpbJkRK93mKXvEE3sDz27BnRrZL4gHeECVpFy0egw29sqFM/x/cpst0goqq4/f3ZFGtQGIhSEEHMySQgTbZDIhXMIls1etRsM4K2bTXeMPn89ablPBdbKtTAJy1EI+ZLKbxnl9StyqBam+d+UsfVmNG19MsNbSzCKc+QPnPXb7dj9KxJ/2whog8w15qXQdJHAMeHZyNlqE0zVP7G1VdWo6Q4QtzmENANxBpJIEbAqY2sq3BZSqDd5XS9Dr9BR4XzQqQnAgMBAAECggEABFABAj4eph1vxVYRBH2TpvDGFU3uW7VBPjwp7JzntLAN8eNoPlqmEDP16y6D/HMmfftpAI3TvWA3+ZEPkiX6nVDyW6sGCodyP0QuJEob1HKHFYntzGtHhGg1KCOacLey6TYbJJmUtcsduQXGkocOPaLXNvjzr2mY2zthTDzJ6HzjDo3d2x/O+lUVlNjubTFydgU9bQP8zS389GgZkO/YebK9+qPRBXv1R2fmj0rhpLqC03jL/mUMKi5tW628OiJGdvzLXlAGyJ9CtVDjfrwUgLf8ML+3yfdmv7yFeWuJ2NEgQxKACixHM05qkCW2bOkPIi9+wb1BbVvMdYL+GCPvmQKBgQD/DZ8zpWfNAkl8h8NI0E7sPdN6wgGfPpaC8VpOE3EM2eEijkZZT6XjfxXjMv1vXg1UoeYVscPb99Ux6u2gq+ZJj6+IstNIObXgvrqNxKPw6OO2xCb6UmA4rQ74xe4d1KLN+C1zepgFYgU4ejungWzuPVL7x8xjdyBAvqgPqP1IbQKBgQDYMzXs2QcWr9tVwq1O3D/H6qX2DvelAj7j0vuXGtop1/aJW7bPlGJd9NGim8dnXLVSFyRteuVl4epa/C9h50g3FM/lFMl9lmp1HwpDeiSJYAGRH8cnPJjN/IV3cRl5qN8KUQE2a3BRP+6IPHJiF1Bc1vj08nTMsWmN+K6VcAzqYwKBgGGJ7RNMM0kkkcPtC5LCDxyrfD/bB9HFlrvW3ykyqC44+K9FZ8PqAM/inxU3P9KiTkjKbXpodDWgLskbResHMld5erC1arWZVGPxrNhgli2gcs1HcHyUmjWygSJEV47S7bwFKCScgpy0Yri5jiy+A1GM5Dpjq1dyjEQWZaEviEV1AoGBALoKn023l/T60QgkZNQmjS/wCG4LhSjWHN4ZMOxfa/pz369lX5OSwW7OfBKscFPOoC0Kwwr+pSYd2HgA6Jkb17WmUBt13skWRXeRhVh5Y7VfCxohuVNXPrqKoSMeDOj22y9ac2ur2lPgateLBHbKTxoE1uiZNs7pn8ZOh5UKfeK3AoGBAKjklIbZ05nvM/mzdPk9JfCFJ6SaQqeaQcU9AoLEQdOzIrrI660Ignn4hOzLSYac0GxytYTQzDt5xDHKBYqJfem7IqxkIj9hSnIZFnUxp6+VfBhXdWHGn+GDTQa1iDvfpy/h6Gr4NL+p/EoA17qtUqOlYxJ1Dkbaw3SqUtkbuv2G"; + + private final String provider = "i-go-odrd-testing"; + + @Autowired + private RedisUtil redisUtil; + + + + + + + /** + * 获取jwt token + * @param type 0=服务端,1=乘客,2=司机 + * @return + */ + public String fleetEngineAuth(int type, Integer id){ + try { + //谷歌云服务器使用这部分代码 +// AuthTokenMinter minter = AuthTokenMinter.builder() +// //服务端签名 +// .setServerSigner(DefaultServiceAccountSigner.create()) +// //司机端签名 +// .setDriverSigner(ImpersonatedSigner.create(SERVICE_ACCOUNT)) +// //乘客端签名 +// .setConsumerSigner(ImpersonatedSigner.create(SERVICE_ACCOUNT)) +// .build(); + AuthTokenMinter minter = AuthTokenMinter.builder() + //服务端签名 + .setServerSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + //司机端签名 + .setDriverSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + //乘客端签名 + .setConsumerSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + .build(); + + String jwt = ""; + if(0 == type){ + FleetEngineToken serverToken = minter.getServerToken(); + jwt = serverToken.jwt(); + } + if(1 == type){ + FleetEngineToken consumerToken = minter.getConsumerToken(TripClaims.create("I-GO-USER" + id)); + jwt = consumerToken.jwt(); + } + if(2 == type){ + FleetEngineToken driverToken = minter.getDriverToken(VehicleClaims.create("I-GO-CAR" + id)); + jwt = driverToken.jwt(); + } + return jwt; + } catch (SigningTokenException e) { + throw new RuntimeException(e); + } + } + + + + + /** + * 添加车辆 + * @param maximumCapacity 这辆车可以搭载的乘客总数 + * @param licensePlate 车牌号 + * @param id 车辆id + */ + public String createVehicles(int maximumCapacity, String licensePlate, Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles?vehicleId=" + "I-GO-CAR" + id; + HttpRequest post = HttpUtil.createPost(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + post.addHeaders(headers); + + JSONObject body = new JSONObject(); + body.put("vehicleState", "OFFLINE"); + body.put("supportedTripTypes", Arrays.asList("SHARED", "EXCLUSIVE")); + body.put("maximumCapacity", maximumCapacity); + + JSONObject category = new JSONObject(); + category.put("category", "TAXI"); + body.put("vehicleType", category); + JSONObject licensePlate1 = new JSONObject(); + licensePlate1.put("countryCode", "GH"); + licensePlate1.put("lastCharacter", getLastNumber(licensePlate)); + body.put("licensePlate", licensePlate1); + logger.info("创建车辆请求:{}", body.toJSONString()); + HttpRequest request = post.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("创建车辆结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return createVehicles(maximumCapacity, licensePlate, id); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "AUTO" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "3" + * }, + * "currentRouteSegmentVersion": "2024-05-23T03:05:23.293329Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + return response.body(); + } + + + /** + * 修改车辆信息 + * @param maximumCapacity + * @param licensePlate + * @param id + * @return + */ + public String updateVehicles(String vehicleState, Integer maximumCapacity, String licensePlate, Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles/" + "I-GO-CAR" + id + "?updateMask="; + List<String> sb = new ArrayList<>(); + if(!StringUtils.hasLength(vehicleState)){ + sb.add("vehicleState"); + } + if(null != maximumCapacity){ + sb.add("maximumCapacity"); + } + if(!StringUtils.hasLength(licensePlate)){ + sb.add("licensePlate"); + } + String collect = sb.stream().collect(Collectors.joining(",")); + url += collect; + + HttpRequest put = HttpUtil.createRequest(Method.PUT, url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + put.addHeaders(headers); + + JSONObject body = new JSONObject(); + /** + * UNKNOWN_VEHICLE_STATE 默认,用于未指定或无法识别的车辆状态。 + * OFFLINE 车辆不接受新行程。注意:在完成分配给车辆的行程时,车辆仍可继续在此状态下运行。 + * ONLINE 车辆正在接受新行程。 + */ + if(!StringUtils.hasLength(vehicleState)){ + body.put("vehicleState", vehicleState); + } + if(null != maximumCapacity){ + body.put("maximumCapacity", maximumCapacity); + } + if(!StringUtils.hasLength(licensePlate)){ + JSONObject licensePlate1 = new JSONObject(); + licensePlate1.put("countryCode", "GH"); + licensePlate1.put("lastCharacter", getLastNumber(licensePlate)); + body.put("licensePlate", licensePlate1); + } + body.put("supportedTripTypes", Arrays.asList("SHARED", "EXCLUSIVE")); + + JSONObject category = new JSONObject(); + category.put("category", "TAXI"); + body.put("vehicleType", category); + put.body(body.toJSONString()); + logger.info("修改车辆信息请求:{}", body.toJSONString()); + HttpResponse response = put.execute(); + logger.info("修改车辆信息结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return updateVehicles(vehicleState, maximumCapacity, licensePlate, id); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "TAXI" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "5" + * }, + * "currentRouteSegmentVersion": "2024-05-23T06:08:14.968942Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + return response.body(); + } + + + /** + * 获取车辆信息 + * @param id 车辆id + * @return + */ + public String getVehicles(Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles" + (null != id ? "/I-GO-CAR" + id : ""); + HttpRequest get = HttpUtil.createGet(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + get.addHeaders(headers); + + HttpResponse response = get.execute(); + logger.info("查询车辆结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 404){ + return ""; + } + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return getVehicles(id); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "vehicles": [ + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "AUTO" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "3" + * }, + * "currentRouteSegmentVersion": "2024-05-23T03:05:23.293329Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + * ], + * "totalSize": "1" + * } + * + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "TAXI" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "5" + * }, + * "currentRouteSegmentVersion": "2024-05-23T06:08:14.968942Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + + return response.body(); + } + + + + /** + * 获取最后一个数字 + * @param str + * @return + */ + private String getLastNumber(String str){ + for (int i = str.length(); i > 0; i--) { + char c = str.charAt(i - 1); + if(String.valueOf(c).matches("\\d")){ + return str.substring(i - 1, i); + } + } + return "-1"; + } + + + /** + * 创建新的行程 + * @param vehicleId 车辆id + * @param numberOfPassengers 人数 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @param start_lat 起点纬度 + * @param start_lng 起点经度 + * @param end_lat 终点纬度 + * @param end_lng 终点经度 + * @return + */ + public String createTrip(Integer vehicleId, Integer numberOfPassengers, Integer orderType, Integer orderId, String start_lat, String start_lng, String end_lat, String end_lng) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips?tripId=" + "I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId; + HttpRequest post = HttpUtil.createPost(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + post.addHeaders(headers); + + JSONObject body = new JSONObject(); + body.put("vehicleId", "I-GO-CAR" + vehicleId); + body.put("tripStatus", "NEW"); + body.put("tripType", "SHARED"); + body.put("numberOfPassengers", numberOfPassengers); + + JSONObject pickupPoint = new JSONObject(); + JSONObject point = new JSONObject(); + point.put("latitude", start_lat); + point.put("longitude", start_lng); + pickupPoint.put("point", point); + body.put("pickupPoint", pickupPoint); + + JSONObject dropoffPoint = new JSONObject(); + JSONObject end_point = new JSONObject(); + end_point.put("latitude", end_lat); + end_point.put("longitude", end_lng); + dropoffPoint.put("point", end_point); + body.put("dropoffPoint", dropoffPoint); + logger.info("创建行程请求:{}", body.toJSONString()); + HttpRequest request = post.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("创建行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return createTrip(vehicleId, numberOfPassengers, orderType, orderId, start_lat, start_lng, end_lat, end_lng); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "NEW", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:05:37.935052Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:18:35.934167Z", + * "numberOfPassengers": 1, + * "remainingDistanceMeters": 0, + * "etaToFirstWaypoint": "2024-05-27T02:05:37.935052Z", + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:05:37.935052Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:18:35.934167Z", + * "duration": "777.999115s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentVersion": "2024-05-27T02:05:37.941167Z", + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "vehicleWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:05:37.935052Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:18:35.934167Z", + * "duration": "777.999115s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentEndPoint": { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE" + * }, + * "remainingWaypointsRouteVersion": "2024-05-27T02:05:37.941167Z", + * "currentRouteSegmentTrafficVersion": "2024-05-27T02:05:37.941167Z" + * } + */ + return response.body(); + } + + + /** + * 修改行程 + * @param tripStatus 行程状态 + * @param vehicleId 车辆id + * @param numberOfPassengers 人数 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @param start_lat 起点纬度 + * @param start_lng 起点经度 + * @param end_lat 终点纬度 + * @param end_lng 终点经度 + * @return + */ + public String updateTrip(String tripStatus, Integer vehicleId, Integer numberOfPassengers, Integer orderType, Integer orderId, String start_lat, String start_lng, String end_lat, String end_lng) throws Exception { + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips/" + "I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId + "?updateMask="; + List<String> sb = new ArrayList<>(); + if(null != vehicleId){ + sb.add("vehicleId"); + } + if(!StringUtils.hasLength(tripStatus)){ + sb.add("tripStatus"); + } + if(null != numberOfPassengers){ + sb.add("numberOfPassengers"); + } + if(!StringUtils.hasLength(start_lat) && !StringUtils.hasLength(start_lng)){ + sb.add("pickupPoint"); + } + + if(!StringUtils.hasLength(end_lat) && !StringUtils.hasLength(end_lng)){ + sb.add("dropoffPoint"); + } + String collect = sb.stream().collect(Collectors.joining(",")); + url += collect; + + HttpRequest put = HttpUtil.createRequest(Method.PUT, url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + put.addHeaders(headers); + + JSONObject body = new JSONObject(); + if(null != vehicleId){ + body.put("vehicleId", "I-GO-CAR" + vehicleId); + } + /** + * UNKNOWN_TRIP_STATUS 默认,用于未指定或无法识别的行程状态。 + * NEW 新建行程。 + * ENROUTE_TO_PICKUP 司机正在前往上车点。 + * ARRIVED_AT_PICKUP 司机已到达上车点。 + * ARRIVED_AT_INTERMEDIATE_DESTINATION 司机已到达中转目的地,正在等待乘客。 + * ENROUTE_TO_INTERMEDIATE_DESTINATION 司机正在前往中间目的地(而非下车点)。 + * ENROUTE_TO_DROPOFF 司机已接起乘客,正在前往下一个目的地。 + * COMPLETE 乘客已下车,行程已完成。 + * CANCELED 在司机、乘客或拼车服务提供商取车之前,行程被取消。 + */ + if(!StringUtils.hasLength(tripStatus)){ + body.put("tripStatus", tripStatus); + } + if(null != numberOfPassengers){ + body.put("numberOfPassengers", numberOfPassengers); + } + if(!StringUtils.hasLength(start_lat) && !StringUtils.hasLength(start_lng)){ + JSONObject pickupPoint = new JSONObject(); + JSONObject point = new JSONObject(); + point.put("latitude", start_lat); + point.put("longitude", start_lng); + pickupPoint.put("point", point); + body.put("pickupPoint", pickupPoint); + } + + if(!StringUtils.hasLength(end_lat) && !StringUtils.hasLength(end_lng)){ + JSONObject dropoffPoint = new JSONObject(); + JSONObject end_point = new JSONObject(); + end_point.put("latitude", end_lat); + end_point.put("longitude", end_lng); + dropoffPoint.put("point", end_point); + body.put("dropoffPoint", dropoffPoint); + } + logger.info("修改行程请求:{}", body.toJSONString()); + HttpRequest request = put.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("修改行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return updateTrip(tripStatus, vehicleId, numberOfPassengers, orderType, orderId, start_lat, start_lng, end_lat, end_lng); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "ENROUTE_TO_PICKUP", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:07:38.562717Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:20:36.562375Z", + * "numberOfPassengers": 1, + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "eta": "2024-05-27T02:07:38.562717Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:20:36.562375Z", + * "duration": "777.999658s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "vehicleWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "eta": "2024-05-27T02:07:38.562717Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:20:36.562375Z", + * "duration": "777.999658s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "remainingWaypointsRouteVersion": "2024-05-27T02:07:38.570569Z" + * } + * + * 取消订单后返回的结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "tripStatus": "CANCELED", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "numberOfPassengers": 1 + * } + */ + return response.body(); + } + + + + /** + * 获取行程信息 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @return + */ + public String getTrip(Integer orderType, Integer orderId) throws Exception { + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips/I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId; + HttpRequest get = HttpUtil.createGet(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + get.addHeaders(headers); + + HttpResponse response = get.execute(); + logger.info("查询行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 404){ + return ""; + } + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return getTrip(orderType, orderId); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "ENROUTE_TO_PICKUP", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:10:39.763347Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:23:37.762549Z", + * "numberOfPassengers": 1, + * "remainingDistanceMeters": 0, + * "etaToFirstWaypoint": "2024-05-27T02:10:39.763347Z", + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:10:39.763347Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:23:37.762549Z", + * "duration": "777.999202s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentVersion": "2024-05-27T02:10:39.773373Z", + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "currentRouteSegmentEndPoint": { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE" + * }, + * "remainingWaypointsRouteVersion": "2024-05-27T02:10:39.773373Z", + * "currentRouteSegmentTrafficVersion": "2024-05-27T02:10:39.773373Z", + * "view": "SDK" + * } + */ + + return response.body(); + } +} diff --git a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java index 6983802..72c49d9 100644 --- a/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java +++ b/DriverIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java @@ -10,7 +10,7 @@ */ public class GoogleMapUtil { - private final static String key = "AIzaSyA_FEliOkbkL1IAHQsnBpbpo9MlIp729H0"; + private final static String key = "AIzaSyCG6PsfkaCEc94VK2vIAZk1YYKvOS_Ewts"; /** diff --git a/ManagementIGOTravel/guns-admin/pom.xml b/ManagementIGOTravel/guns-admin/pom.xml index 605cfe5..8545c52 100644 --- a/ManagementIGOTravel/guns-admin/pom.xml +++ b/ManagementIGOTravel/guns-admin/pom.xml @@ -196,6 +196,12 @@ <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> </dependency> + <!--Google ODRD--> + <dependency> + <groupId>com.google.maps</groupId> + <artifactId>fleetengine-auth</artifactId> + <version>1.11.0</version> + </dependency> <!--邮件发送依赖--> <dependency> <groupId>org.springframework.boot</groupId> diff --git a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TDriverController.java b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TDriverController.java index 566845d..989966a 100644 --- a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TDriverController.java +++ b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TDriverController.java @@ -79,6 +79,9 @@ @Value("${spring.mail.template-path}") private String templatePath; + + @Autowired + private RedisUtil redisUtil; @@ -766,9 +769,7 @@ tDriverService.updateById(driver); return SUCCESS_TIP; } - - @Autowired - private RedisUtil redisUtil; + /** * 操作司机状态 */ diff --git a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TIntegralOrderController.java b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TIntegralOrderController.java index c240920..111aee9 100644 --- a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TIntegralOrderController.java +++ b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TIntegralOrderController.java @@ -5,7 +5,18 @@ import com.stylefeng.guns.core.common.constant.factory.PageFactory; import com.stylefeng.guns.core.shiro.ShiroKit; import com.stylefeng.guns.core.util.SinataUtil; +import com.stylefeng.guns.core.util.ToolUtil; +import com.stylefeng.guns.modular.system.model.TEmail; import com.stylefeng.guns.modular.system.model.TOrderCharter; +import com.stylefeng.guns.modular.system.model.TUser; +import com.stylefeng.guns.modular.system.service.ITUserService; +import com.stylefeng.guns.modular.system.service.IUserService; +import com.stylefeng.guns.modular.system.service.TEmailService; +import com.stylefeng.guns.modular.system.util.EmailUtil; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -17,6 +28,10 @@ import com.stylefeng.guns.modular.system.model.TIntegralOrder; import com.stylefeng.guns.modular.system.service.ITIntegralOrderService; +import javax.annotation.Resource; +import java.io.File; +import java.io.FileWriter; +import java.util.Date; import java.util.Map; /** @@ -33,6 +48,20 @@ @Autowired private ITIntegralOrderService tIntegralOrderService; + + @Autowired + private ITUserService userService; + + @Value("${spring.mail.template-path}") + private String templatePath; + + @Resource + private TEmailService emailService; + + + + + /** * 跳转到积分兑换订单首页 @@ -94,6 +123,82 @@ tIntegralOrder.setRemark(null); tIntegralOrderService.updateById(tIntegralOrder); + + new Thread(new Runnable() { + @Override + public void run() { + TUser tUser = userService.selectById(tIntegralOrder.getUserId()); + if(ToolUtil.isNotEmpty(tUser.getEmail())){ + try { + Integer language = tUser.getLanguage(); + String nickName = tUser.getNickName(); + String email = tUser.getEmail(); + + String path = templatePath + "user/pointExchange.html"; + Document document = Jsoup.parse(new File(path), "UTF-8"); + if(1 == language){ + document.getElementById("english").remove(); + document.getElementById("french").remove(); + document.getElementsByTag("title").get(0).text("积分兑换已通过审核"); + Element user_chinese = document.getElementById("user_chinese"); + user_chinese.text("您好 " + nickName + ","); + } + if(2 == language){ + document.getElementById("chinese").remove(); + document.getElementById("french").remove(); + document.getElementsByTag("title").get(0).text("Points redemption approved"); + Element user_chinese = document.getElementById("user_english"); + user_chinese.text("Hello " + nickName + ","); + } + if(3 == language){ + document.getElementById("chinese").remove(); + document.getElementById("english").remove(); + document.getElementsByTag("title").get(0).text("Approbation de l’échange de points"); + Element user_french = document.getElementById("user_french"); + user_french.text("Bonjour " + nickName + ","); + } + EmailUtil.send(email, language == 1 ? "积分兑换已通过审核" : language == 2 ? "Points redemption approved" : "Approbation de l’échange de points", document.html()); + + //开始生成pdf收据和html收据 + File file = new File("/usr/local/nginx/html/files/html/"); + if(!file.exists()){ + file.mkdirs(); + } + String randomString = ToolUtil.getRandomString(10); + file = new File("/usr/local/nginx/html/files/html/complaint_" + randomString + ".html"); + if(!file.exists()){ + file.createNewFile(); + } + FileWriter fileWriter = new FileWriter(file); + fileWriter.write(document.html()); + fileWriter.flush(); + fileWriter.close(); + + String link ="http://182.160.16.251:81/files/html/complaint_" + randomString + ".html"; + TEmail tEmail = new TEmail(); + tEmail.setLink(link); + tEmail.setUserId(tUser.getId()); + tEmail.setType(1); + tEmail.setName(language == 1 ? "积分兑换已通过审核" : language == 2 ? "Points redemption approved" : "Approbation de l’échange de points"); + tEmail.setCreateTime(new Date()); + int i = cn.hutool.core.date.DateUtil.dayOfWeek(new Date())-1; + tEmail.setWeek(EmailUtil.getWeek(language,i)); + boolean am = cn.hutool.core.date.DateUtil.isAM(new Date()); + if(am){ + tEmail.setAmOrPm(language==1?"上午":language==2?"morning":"matin"); + }else { + tEmail.setAmOrPm(language==1?"下午":language==2?"afternoon":"après-midi"); + } + emailService.insert(tEmail); + }catch (Exception e){ + e.printStackTrace(); + } + } + + + } + }).start(); + return SUCCESS_TIP; } diff --git a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderLogisticsController.java b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderLogisticsController.java index f8a9c87..f2e5e35 100644 --- a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderLogisticsController.java +++ b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderLogisticsController.java @@ -8,6 +8,7 @@ import com.stylefeng.guns.modular.system.model.TDriver; import com.stylefeng.guns.modular.system.model.TOrderPrivateCar; import com.stylefeng.guns.modular.system.service.ITDriverService; +import com.stylefeng.guns.modular.system.util.GoogleMap.FleetEngineUtil; import com.stylefeng.guns.modular.system.util.HttpRequestUtil; import com.stylefeng.guns.modular.system.util.PushURL; import org.springframework.stereotype.Controller; @@ -38,6 +39,9 @@ @Autowired private ITOrderLogisticsService tOrderLogisticsService; + + @Autowired + private FleetEngineUtil fleetEngineUtil; /** * 跳转到小件物流订单首页 @@ -114,6 +118,14 @@ tOrderLogistics.setState(10); tOrderLogisticsService.updateById(tOrderLogistics); + //修改行程信息 + try { + fleetEngineUtil.updateTrip("CANCELED", null, null, 4, tOrderLogistics.getId(), null, null, null, null); + } catch (Exception e) { + throw new RuntimeException(e); + } + + //增加推送 Map<String,String> map = new HashMap<>(); map.put("id", tOrderLogistics.getId().toString()); diff --git a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderPrivateCarController.java b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderPrivateCarController.java index 3fe3dad..9ab9a5b 100644 --- a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderPrivateCarController.java +++ b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TOrderPrivateCarController.java @@ -14,6 +14,7 @@ import com.stylefeng.guns.modular.system.dao.OrderCancelMapper; import com.stylefeng.guns.modular.system.model.*; import com.stylefeng.guns.modular.system.service.*; +import com.stylefeng.guns.modular.system.util.GoogleMap.FleetEngineUtil; import com.stylefeng.guns.modular.system.util.HttpRequestUtil; import com.stylefeng.guns.modular.system.util.PushURL; import com.stylefeng.guns.modular.system.util.ResultUtil; @@ -62,6 +63,9 @@ @Value("${filePath}") private String filePath; + + @Autowired + private FleetEngineUtil fleetEngineUtil; @@ -302,7 +306,15 @@ orderCancel.setState(2); orderCancel.setInsertTime(new Date()); orderCancelMapper.insert(orderCancel); - + + //修改行程信息 + try { + fleetEngineUtil.updateTrip("CANCELED", null, null, 1, tOrderPrivateCar.getId(), null, null, null, null); + } catch (Exception e) { + throw new RuntimeException(e); + } + + //增加推送 Map<String,String> map = new HashMap<>(); map.put("id", tOrderPrivateCar.getId().toString()); diff --git a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TUser.java b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TUser.java index cc9d0a5..14b6578 100644 --- a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TUser.java +++ b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TUser.java @@ -158,6 +158,11 @@ */ @TableField("uid") private Integer uid; + /** + * 语言类型(1=简体中文,2=英语,3=法语) + */ + @TableField("language") + private Integer language; public Integer getId() { @@ -415,7 +420,15 @@ public void setUid(Integer uid) { this.uid = uid; } - + + public Integer getLanguage() { + return language; + } + + public void setLanguage(Integer language) { + this.language = language; + } + @Override protected Serializable pkVal() { return this.id; diff --git a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java new file mode 100644 index 0000000..75d54bf --- /dev/null +++ b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java @@ -0,0 +1,895 @@ +package com.stylefeng.guns.modular.system.util.GoogleMap; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import cn.hutool.http.Method; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.fleetengine.auth.AuthTokenMinter; +import com.google.fleetengine.auth.token.FleetEngineToken; +import com.google.fleetengine.auth.token.TripClaims; +import com.google.fleetengine.auth.token.VehicleClaims; +import com.google.fleetengine.auth.token.factory.signer.*; +import com.stylefeng.guns.modular.system.util.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Fleet Engine API 工具类 + * @author zhibing.pu + * @Date 2024/5/17 9:59 + */ +@Slf4j +@Component +public class FleetEngineUtil { + + static Logger logger = LoggerFactory.getLogger(FleetEngineUtil.class); + + private final String SERVICE_ACCOUNT = "odrd2024@i-go-odrd-testing.iam.gserviceaccount.com"; + + private final String privateKeyId = "0a9a480fafb6469c0c1b2fa6dbdf6d4bebe1ebed"; + + private final String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXZoPEFZeZb0C7DXzpPsloB+rQVQAJuR+z4T9uRCz33gBsIqrz1s5Iwd8vXYKKWzukMdXkwqR4WapI/4GtcpbJkRK93mKXvEE3sDz27BnRrZL4gHeECVpFy0egw29sqFM/x/cpst0goqq4/f3ZFGtQGIhSEEHMySQgTbZDIhXMIls1etRsM4K2bTXeMPn89ablPBdbKtTAJy1EI+ZLKbxnl9StyqBam+d+UsfVmNG19MsNbSzCKc+QPnPXb7dj9KxJ/2whog8w15qXQdJHAMeHZyNlqE0zVP7G1VdWo6Q4QtzmENANxBpJIEbAqY2sq3BZSqDd5XS9Dr9BR4XzQqQnAgMBAAECggEABFABAj4eph1vxVYRBH2TpvDGFU3uW7VBPjwp7JzntLAN8eNoPlqmEDP16y6D/HMmfftpAI3TvWA3+ZEPkiX6nVDyW6sGCodyP0QuJEob1HKHFYntzGtHhGg1KCOacLey6TYbJJmUtcsduQXGkocOPaLXNvjzr2mY2zthTDzJ6HzjDo3d2x/O+lUVlNjubTFydgU9bQP8zS389GgZkO/YebK9+qPRBXv1R2fmj0rhpLqC03jL/mUMKi5tW628OiJGdvzLXlAGyJ9CtVDjfrwUgLf8ML+3yfdmv7yFeWuJ2NEgQxKACixHM05qkCW2bOkPIi9+wb1BbVvMdYL+GCPvmQKBgQD/DZ8zpWfNAkl8h8NI0E7sPdN6wgGfPpaC8VpOE3EM2eEijkZZT6XjfxXjMv1vXg1UoeYVscPb99Ux6u2gq+ZJj6+IstNIObXgvrqNxKPw6OO2xCb6UmA4rQ74xe4d1KLN+C1zepgFYgU4ejungWzuPVL7x8xjdyBAvqgPqP1IbQKBgQDYMzXs2QcWr9tVwq1O3D/H6qX2DvelAj7j0vuXGtop1/aJW7bPlGJd9NGim8dnXLVSFyRteuVl4epa/C9h50g3FM/lFMl9lmp1HwpDeiSJYAGRH8cnPJjN/IV3cRl5qN8KUQE2a3BRP+6IPHJiF1Bc1vj08nTMsWmN+K6VcAzqYwKBgGGJ7RNMM0kkkcPtC5LCDxyrfD/bB9HFlrvW3ykyqC44+K9FZ8PqAM/inxU3P9KiTkjKbXpodDWgLskbResHMld5erC1arWZVGPxrNhgli2gcs1HcHyUmjWygSJEV47S7bwFKCScgpy0Yri5jiy+A1GM5Dpjq1dyjEQWZaEviEV1AoGBALoKn023l/T60QgkZNQmjS/wCG4LhSjWHN4ZMOxfa/pz369lX5OSwW7OfBKscFPOoC0Kwwr+pSYd2HgA6Jkb17WmUBt13skWRXeRhVh5Y7VfCxohuVNXPrqKoSMeDOj22y9ac2ur2lPgateLBHbKTxoE1uiZNs7pn8ZOh5UKfeK3AoGBAKjklIbZ05nvM/mzdPk9JfCFJ6SaQqeaQcU9AoLEQdOzIrrI660Ignn4hOzLSYac0GxytYTQzDt5xDHKBYqJfem7IqxkIj9hSnIZFnUxp6+VfBhXdWHGn+GDTQa1iDvfpy/h6Gr4NL+p/EoA17qtUqOlYxJ1Dkbaw3SqUtkbuv2G"; + + private final String provider = "i-go-odrd-testing"; + + @Autowired + private RedisUtil redisUtil; + + + + + + + /** + * 获取jwt token + * @param type 0=服务端,1=乘客,2=司机 + * @return + */ + public String fleetEngineAuth(int type, Integer id){ + try { + //谷歌云服务器使用这部分代码 +// AuthTokenMinter minter = AuthTokenMinter.builder() +// //服务端签名 +// .setServerSigner(DefaultServiceAccountSigner.create()) +// //司机端签名 +// .setDriverSigner(ImpersonatedSigner.create(SERVICE_ACCOUNT)) +// //乘客端签名 +// .setConsumerSigner(ImpersonatedSigner.create(SERVICE_ACCOUNT)) +// .build(); + AuthTokenMinter minter = AuthTokenMinter.builder() + //服务端签名 + .setServerSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + //司机端签名 + .setDriverSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + //乘客端签名 + .setConsumerSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + .build(); + + String jwt = ""; + if(0 == type){ + FleetEngineToken serverToken = minter.getServerToken(); + jwt = serverToken.jwt(); + } + if(1 == type){ + FleetEngineToken consumerToken = minter.getConsumerToken(TripClaims.create("I-GO-USER" + id)); + jwt = consumerToken.jwt(); + } + if(2 == type){ + FleetEngineToken driverToken = minter.getDriverToken(VehicleClaims.create("I-GO-CAR" + id)); + jwt = driverToken.jwt(); + } + return jwt; + } catch (SigningTokenException e) { + throw new RuntimeException(e); + } + } + + + + + /** + * 添加车辆 + * @param maximumCapacity 这辆车可以搭载的乘客总数 + * @param licensePlate 车牌号 + * @param id 车辆id + */ + public String createVehicles(int maximumCapacity, String licensePlate, Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles?vehicleId=" + "I-GO-CAR" + id; + HttpRequest post = HttpUtil.createPost(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + post.addHeaders(headers); + + JSONObject body = new JSONObject(); + body.put("vehicleState", "OFFLINE"); + body.put("supportedTripTypes", Arrays.asList("SHARED", "EXCLUSIVE")); + body.put("maximumCapacity", maximumCapacity); + + JSONObject category = new JSONObject(); + category.put("category", "TAXI"); + body.put("vehicleType", category); + JSONObject licensePlate1 = new JSONObject(); + licensePlate1.put("countryCode", "GH"); + licensePlate1.put("lastCharacter", getLastNumber(licensePlate)); + body.put("licensePlate", licensePlate1); + logger.info("创建车辆请求:{}", body.toJSONString()); + HttpRequest request = post.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("创建车辆结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return createVehicles(maximumCapacity, licensePlate, id); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "AUTO" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "3" + * }, + * "currentRouteSegmentVersion": "2024-05-23T03:05:23.293329Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + return response.body(); + } + + + /** + * 修改车辆信息 + * @param maximumCapacity + * @param licensePlate + * @param id + * @return + */ + public String updateVehicles(String vehicleState, Integer maximumCapacity, String licensePlate, Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles/" + "I-GO-CAR" + id + "?updateMask="; + List<String> sb = new ArrayList<>(); + if(!StringUtils.hasLength(vehicleState)){ + sb.add("vehicleState"); + } + if(null != maximumCapacity){ + sb.add("maximumCapacity"); + } + if(!StringUtils.hasLength(licensePlate)){ + sb.add("licensePlate"); + } + String collect = sb.stream().collect(Collectors.joining(",")); + url += collect; + + HttpRequest put = HttpUtil.createRequest(Method.PUT, url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + put.addHeaders(headers); + + JSONObject body = new JSONObject(); + /** + * UNKNOWN_VEHICLE_STATE 默认,用于未指定或无法识别的车辆状态。 + * OFFLINE 车辆不接受新行程。注意:在完成分配给车辆的行程时,车辆仍可继续在此状态下运行。 + * ONLINE 车辆正在接受新行程。 + */ + if(!StringUtils.hasLength(vehicleState)){ + body.put("vehicleState", vehicleState); + } + if(null != maximumCapacity){ + body.put("maximumCapacity", maximumCapacity); + } + if(!StringUtils.hasLength(licensePlate)){ + JSONObject licensePlate1 = new JSONObject(); + licensePlate1.put("countryCode", "GH"); + licensePlate1.put("lastCharacter", getLastNumber(licensePlate)); + body.put("licensePlate", licensePlate1); + } + body.put("supportedTripTypes", Arrays.asList("SHARED", "EXCLUSIVE")); + + JSONObject category = new JSONObject(); + category.put("category", "TAXI"); + body.put("vehicleType", category); + put.body(body.toJSONString()); + logger.info("修改车辆信息请求:{}", body.toJSONString()); + HttpResponse response = put.execute(); + logger.info("修改车辆信息结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return updateVehicles(vehicleState, maximumCapacity, licensePlate, id); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "TAXI" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "5" + * }, + * "currentRouteSegmentVersion": "2024-05-23T06:08:14.968942Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + return response.body(); + } + + + /** + * 获取车辆信息 + * @param id 车辆id + * @return + */ + public String getVehicles(Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles" + (null != id ? "/I-GO-CAR" + id : ""); + HttpRequest get = HttpUtil.createGet(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + get.addHeaders(headers); + + HttpResponse response = get.execute(); + logger.info("查询车辆结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 404){ + return ""; + } + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return getVehicles(id); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "vehicles": [ + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "AUTO" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "3" + * }, + * "currentRouteSegmentVersion": "2024-05-23T03:05:23.293329Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + * ], + * "totalSize": "1" + * } + * + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "TAXI" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "5" + * }, + * "currentRouteSegmentVersion": "2024-05-23T06:08:14.968942Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + + return response.body(); + } + + + + /** + * 获取最后一个数字 + * @param str + * @return + */ + private String getLastNumber(String str){ + for (int i = str.length(); i > 0; i--) { + char c = str.charAt(i - 1); + if(String.valueOf(c).matches("\\d")){ + return str.substring(i - 1, i); + } + } + return "-1"; + } + + + /** + * 创建新的行程 + * @param vehicleId 车辆id + * @param numberOfPassengers 人数 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @param start_lat 起点纬度 + * @param start_lng 起点经度 + * @param end_lat 终点纬度 + * @param end_lng 终点经度 + * @return + */ + public String createTrip(Integer vehicleId, Integer numberOfPassengers, Integer orderType, Integer orderId, String start_lat, String start_lng, String end_lat, String end_lng) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips?tripId=" + "I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId; + HttpRequest post = HttpUtil.createPost(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + post.addHeaders(headers); + + JSONObject body = new JSONObject(); + body.put("vehicleId", "I-GO-CAR" + vehicleId); + body.put("tripStatus", "NEW"); + body.put("tripType", "SHARED"); + body.put("numberOfPassengers", numberOfPassengers); + + JSONObject pickupPoint = new JSONObject(); + JSONObject point = new JSONObject(); + point.put("latitude", start_lat); + point.put("longitude", start_lng); + pickupPoint.put("point", point); + body.put("pickupPoint", pickupPoint); + + JSONObject dropoffPoint = new JSONObject(); + JSONObject end_point = new JSONObject(); + end_point.put("latitude", end_lat); + end_point.put("longitude", end_lng); + dropoffPoint.put("point", end_point); + body.put("dropoffPoint", dropoffPoint); + logger.info("创建行程请求:{}", body.toJSONString()); + HttpRequest request = post.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("创建行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return createTrip(vehicleId, numberOfPassengers, orderType, orderId, start_lat, start_lng, end_lat, end_lng); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "NEW", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:05:37.935052Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:18:35.934167Z", + * "numberOfPassengers": 1, + * "remainingDistanceMeters": 0, + * "etaToFirstWaypoint": "2024-05-27T02:05:37.935052Z", + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:05:37.935052Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:18:35.934167Z", + * "duration": "777.999115s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentVersion": "2024-05-27T02:05:37.941167Z", + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "vehicleWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:05:37.935052Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:18:35.934167Z", + * "duration": "777.999115s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentEndPoint": { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE" + * }, + * "remainingWaypointsRouteVersion": "2024-05-27T02:05:37.941167Z", + * "currentRouteSegmentTrafficVersion": "2024-05-27T02:05:37.941167Z" + * } + */ + return response.body(); + } + + + /** + * 修改行程 + * @param tripStatus 行程状态 + * @param vehicleId 车辆id + * @param numberOfPassengers 人数 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @param start_lat 起点纬度 + * @param start_lng 起点经度 + * @param end_lat 终点纬度 + * @param end_lng 终点经度 + * @return + */ + public String updateTrip(String tripStatus, Integer vehicleId, Integer numberOfPassengers, Integer orderType, Integer orderId, String start_lat, String start_lng, String end_lat, String end_lng) throws Exception { + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips/" + "I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId + "?updateMask="; + List<String> sb = new ArrayList<>(); + if(null != vehicleId){ + sb.add("vehicleId"); + } + if(!StringUtils.hasLength(tripStatus)){ + sb.add("tripStatus"); + } + if(null != numberOfPassengers){ + sb.add("numberOfPassengers"); + } + if(!StringUtils.hasLength(start_lat) && !StringUtils.hasLength(start_lng)){ + sb.add("pickupPoint"); + } + + if(!StringUtils.hasLength(end_lat) && !StringUtils.hasLength(end_lng)){ + sb.add("dropoffPoint"); + } + String collect = sb.stream().collect(Collectors.joining(",")); + url += collect; + + HttpRequest put = HttpUtil.createRequest(Method.PUT, url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + put.addHeaders(headers); + + JSONObject body = new JSONObject(); + if(null != vehicleId){ + body.put("vehicleId", "I-GO-CAR" + vehicleId); + } + /** + * UNKNOWN_TRIP_STATUS 默认,用于未指定或无法识别的行程状态。 + * NEW 新建行程。 + * ENROUTE_TO_PICKUP 司机正在前往上车点。 + * ARRIVED_AT_PICKUP 司机已到达上车点。 + * ARRIVED_AT_INTERMEDIATE_DESTINATION 司机已到达中转目的地,正在等待乘客。 + * ENROUTE_TO_INTERMEDIATE_DESTINATION 司机正在前往中间目的地(而非下车点)。 + * ENROUTE_TO_DROPOFF 司机已接起乘客,正在前往下一个目的地。 + * COMPLETE 乘客已下车,行程已完成。 + * CANCELED 在司机、乘客或拼车服务提供商取车之前,行程被取消。 + */ + if(!StringUtils.hasLength(tripStatus)){ + body.put("tripStatus", tripStatus); + } + if(null != numberOfPassengers){ + body.put("numberOfPassengers", numberOfPassengers); + } + if(!StringUtils.hasLength(start_lat) && !StringUtils.hasLength(start_lng)){ + JSONObject pickupPoint = new JSONObject(); + JSONObject point = new JSONObject(); + point.put("latitude", start_lat); + point.put("longitude", start_lng); + pickupPoint.put("point", point); + body.put("pickupPoint", pickupPoint); + } + + if(!StringUtils.hasLength(end_lat) && !StringUtils.hasLength(end_lng)){ + JSONObject dropoffPoint = new JSONObject(); + JSONObject end_point = new JSONObject(); + end_point.put("latitude", end_lat); + end_point.put("longitude", end_lng); + dropoffPoint.put("point", end_point); + body.put("dropoffPoint", dropoffPoint); + } + logger.info("修改行程请求:{}", body.toJSONString()); + HttpRequest request = put.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("修改行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return updateTrip(tripStatus, vehicleId, numberOfPassengers, orderType, orderId, start_lat, start_lng, end_lat, end_lng); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "ENROUTE_TO_PICKUP", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:07:38.562717Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:20:36.562375Z", + * "numberOfPassengers": 1, + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "eta": "2024-05-27T02:07:38.562717Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:20:36.562375Z", + * "duration": "777.999658s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "vehicleWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "eta": "2024-05-27T02:07:38.562717Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:20:36.562375Z", + * "duration": "777.999658s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "remainingWaypointsRouteVersion": "2024-05-27T02:07:38.570569Z" + * } + * + * 取消订单后返回的结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "tripStatus": "CANCELED", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "numberOfPassengers": 1 + * } + */ + return response.body(); + } + + + + /** + * 获取行程信息 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @return + */ + public String getTrip(Integer orderType, Integer orderId) throws Exception { + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips/I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId; + HttpRequest get = HttpUtil.createGet(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + get.addHeaders(headers); + + HttpResponse response = get.execute(); + logger.info("查询行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 404){ + return ""; + } + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return getTrip(orderType, orderId); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "ENROUTE_TO_PICKUP", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:10:39.763347Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:23:37.762549Z", + * "numberOfPassengers": 1, + * "remainingDistanceMeters": 0, + * "etaToFirstWaypoint": "2024-05-27T02:10:39.763347Z", + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:10:39.763347Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:23:37.762549Z", + * "duration": "777.999202s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentVersion": "2024-05-27T02:10:39.773373Z", + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "currentRouteSegmentEndPoint": { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE" + * }, + * "remainingWaypointsRouteVersion": "2024-05-27T02:10:39.773373Z", + * "currentRouteSegmentTrafficVersion": "2024-05-27T02:10:39.773373Z", + * "view": "SDK" + * } + */ + + return response.body(); + } +} diff --git a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java index 63e5782..ff03db9 100644 --- a/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java +++ b/ManagementIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java @@ -11,7 +11,7 @@ */ public class GoogleMapUtil { - private final static String key = "AIzaSyA_FEliOkbkL1IAHQsnBpbpo9MlIp729H0"; + private final static String key = "AIzaSyCG6PsfkaCEc94VK2vIAZk1YYKvOS_Ewts"; /** diff --git a/ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/home.html b/ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/home.html index acf7ed8..3de5469 100644 --- a/ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/home.html +++ b/ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/home.html @@ -227,7 +227,7 @@ </div> </div> </div> -<script async src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA_FEliOkbkL1IAHQsnBpbpo9MlIp729H0&callback=initMap&v=weekly"></script> +<script async src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCG6PsfkaCEc94VK2vIAZk1YYKvOS_Ewts&callback=initMap&v=weekly"></script> <script src="${ctxPath}/static/home.js"></script> <script src="${ctxPath}/static/js/jquery.sparkline 2.1.2.js"></script> @} diff --git a/ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tOrderPrivateCar/tOrderPrivateCar_orderDetail.html b/ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tOrderPrivateCar/tOrderPrivateCar_orderDetail.html index 3dc8e68..a22a8ad 100644 --- a/ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tOrderPrivateCar/tOrderPrivateCar_orderDetail.html +++ b/ManagementIGOTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tOrderPrivateCar/tOrderPrivateCar_orderDetail.html @@ -107,6 +107,6 @@ </div> </div> </div> -<script defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA_FEliOkbkL1IAHQsnBpbpo9MlIp729H0&callback=initMap&v=weekly"></script> +<script defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCG6PsfkaCEc94VK2vIAZk1YYKvOS_Ewts&callback=initMap&v=weekly"></script> <script src="${ctxPath}/static/modular/system/tOrderPrivateCar/tOrderPrivateCar_info.js"></script> @} diff --git a/UserIGOTravel/guns-admin/pom.xml b/UserIGOTravel/guns-admin/pom.xml index 09ff01d..3ca1bae 100644 --- a/UserIGOTravel/guns-admin/pom.xml +++ b/UserIGOTravel/guns-admin/pom.xml @@ -259,6 +259,13 @@ <artifactId>font-asian</artifactId> <version>7.1.13</version> </dependency> + + <!--Google ODRD--> + <dependency> + <groupId>com.google.maps</groupId> + <artifactId>fleetengine-auth</artifactId> + <version>1.11.0</version> + </dependency> </dependencies> diff --git a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/controller/OrderLogisticsController.java b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/controller/OrderLogisticsController.java index 214e75f..c1ed62c 100644 --- a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/controller/OrderLogisticsController.java +++ b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/controller/OrderLogisticsController.java @@ -316,8 +316,16 @@ orderTimeInfo.setStartServiceTime(sdf.format(orderLogistics.getStartServiceTime())); } long time = System.currentTimeMillis() - orderLogistics.getSnatchOrderTime().getTime() / 60000; - //TODO 待翻译 - orderTimeInfo.setUsedTime(Double.valueOf(time / 60).intValue() + "小时" + time % 60 + "分钟"); + + int h = Double.valueOf(time / 60).intValue(); + long m = time % 60; + String usedTime = ""; + if(0 == h){ + usedTime = language == 1 ? m + "分钟" : language == 2 ? m + "-minute" : m + "-minute"; + }else{ + usedTime = language == 1 ? h + "小时" + m + "分钟" : language == 2 ? h + "-hour" + m + "-minute" : h + "-hour" + m + "-minute"; + } + orderTimeInfo.setUsedTime(usedTime); if(null != orderLogistics.getEndServiceTime()){ orderTimeInfo.setEndServiceTime(sdf.format(orderLogistics.getEndServiceTime())); } diff --git a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java index 20b67fb..b51a178 100644 --- a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java +++ b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/smallLogistics/server/impl/OrderLogisticsServiceImpl.java @@ -198,6 +198,15 @@ @Autowired private IUserActivityRedenvelopeService userActivityRedenvelopeService; + + @Autowired + private FleetEngineUtil fleetEngineUtil; + + @Resource + private CarModelMapper carModelMapper; + + @Autowired + private ICarService carService; @@ -683,6 +692,26 @@ orderLogistics.setIsDelete(1); this.insert(orderLogistics); + + Integer vehicleId = null; + if(null != orderLogistics.getDriverId()){ + Driver driver = driverService.selectById(orderLogistics.getDriverId()); + vehicleId = driver.getCarId(); + //查询车辆信息,没有则创建信息 + String vehicles = fleetEngineUtil.getVehicles(vehicleId); + if(ToolUtil.isEmpty(vehicles)){ + Car car = carService.selectById(vehicleId); + CarModel carModel = carModelMapper.selectById(car.getCarModelId()); + fleetEngineUtil.createVehicles(carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + fleetEngineUtil.updateVehicles("ONLINE", carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + } + + } + //创建行程数据 + fleetEngineUtil.createTrip(vehicleId, 1, 4, orderLogistics.getId(), + orderLogistics.getStartLat().toString(), orderLogistics.getStartLon().toString(), orderLogistics.getEndLat().toString(), orderLogistics.getEndLon().toString()); + + if(orderSource == 2){//扫码下单 new Thread(new Runnable() { @Override @@ -836,7 +865,7 @@ if(null != couponId){ //TODO 待翻译 if(null != redDeduction && 1 == redDeduction){ - return ResultUtil.error(language == 1 ? "优惠券和红包不能同时使用" : language == 2 ? "" : "", ""); + return ResultUtil.error(language == 1 ? "优惠券和红包不能同时使用" : language == 2 ? "Coupons and lucky-promo cannot be used at the same time." : "Les coupons et les bonus ne peuvent pas être utilisés en même temps", ""); } userCouponRecord = userCouponRecordService.selectById(couponId); if(userCouponRecord.getCompanyId() != orderLogistics.getCompanyId()){ @@ -1100,6 +1129,13 @@ title_chinese.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",您在I-GO此订单消费GHS " + orderLogistics.getPayMoney()); Element xcf_chinese = document.getElementById("xcf_chinese"); xcf_chinese.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_chinese = document.getElementById("bcj_chinese"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_chinese.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_chinese_div = document.getElementById("bcj_chinese_div"); + bcj_chinese_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_chinese = document.getElementById("yhq_chinese"); yhq_chinese.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -1160,6 +1196,13 @@ title_english.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",You spent GHS " + orderLogistics.getPayMoney() + " on the trip "); Element xcf_english = document.getElementById("xcf_english"); xcf_english.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_english = document.getElementById("bcj_english"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_english.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_english_div = document.getElementById("bcj_english_div"); + bcj_english_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_english = document.getElementById("yhq_english"); yhq_english.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -1220,6 +1263,13 @@ title_french.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",Vous consommez GHS " + orderLogistics.getPayMoney() + " sur votre commande i-go1 le "); Element xcf_french = document.getElementById("xcf_french"); xcf_french.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_french = document.getElementById("bcj_french"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_french.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_french_div = document.getElementById("bcj_french_div"); + bcj_french_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_french = document.getElementById("yhq_french"); yhq_french.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -1503,6 +1553,13 @@ title_chinese.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",您在I-GO此订单消费GHS " + orderLogistics.getPayMoney()); Element xcf_chinese = document.getElementById("xcf_chinese"); xcf_chinese.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_chinese = document.getElementById("bcj_chinese"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_chinese.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_chinese_div = document.getElementById("bcj_chinese_div"); + bcj_chinese_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_chinese = document.getElementById("yhq_chinese"); yhq_chinese.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -1563,6 +1620,13 @@ title_english.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",You spent GHS " + orderLogistics.getPayMoney() + " on the trip "); Element xcf_english = document.getElementById("xcf_english"); xcf_english.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_english = document.getElementById("bcj_english"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_english.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_english_div = document.getElementById("bcj_english_div"); + bcj_english_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_english = document.getElementById("yhq_english"); yhq_english.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -1623,6 +1687,13 @@ title_french.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",Vous consommez GHS " + orderLogistics.getPayMoney() + " sur votre commande i-go1 le "); Element xcf_french = document.getElementById("xcf_french"); xcf_french.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_french = document.getElementById("bcj_french"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_french.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_french_div = document.getElementById("bcj_french_div"); + bcj_french_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_french = document.getElementById("yhq_french"); yhq_french.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -2008,6 +2079,13 @@ title_chinese.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",您在I-GO此订单消费GHS " + orderLogistics.getPayMoney()); Element xcf_chinese = document.getElementById("xcf_chinese"); xcf_chinese.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_chinese = document.getElementById("bcj_chinese"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_chinese.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_chinese_div = document.getElementById("bcj_chinese_div"); + bcj_chinese_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_chinese = document.getElementById("yhq_chinese"); yhq_chinese.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -2068,6 +2146,13 @@ title_english.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",You spent GHS " + orderLogistics.getPayMoney() + " on the trip "); Element xcf_english = document.getElementById("xcf_english"); xcf_english.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_english = document.getElementById("bcj_english"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_english.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_english_div = document.getElementById("bcj_english_div"); + bcj_english_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_english = document.getElementById("yhq_english"); yhq_english.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -2128,6 +2213,13 @@ title_french.text(DateUtil.conversionFormat(language, sdf2.format(orderLogistics.getTravelTime())) + ",Vous consommez GHS " + orderLogistics.getPayMoney() + " sur votre commande i-go1 le "); Element xcf_french = document.getElementById("xcf_french"); xcf_french.text("GHS " + new BigDecimal(orderLogistics.getOrderMoney()).setScale(2, RoundingMode.HALF_EVEN)); + Element bcj_french = document.getElementById("bcj_french"); + if(null != orderLogistics.getPriceDifference() && orderLogistics.getPriceDifference() > 0){ + bcj_french.text("GHS " + new BigDecimal(orderLogistics.getPriceDifference()).setScale(2, RoundingMode.HALF_EVEN)); + }else{ + Element bcj_french_div = document.getElementById("bcj_french_div"); + bcj_french_div.remove(); + } if(null != orderLogistics.getCouponMoney() && orderLogistics.getCouponMoney() > 0){ Element yhq_french = document.getElementById("yhq_french"); yhq_french.text("GHS -" + new BigDecimal(orderLogistics.getCouponMoney()).setScale(2, RoundingMode.HALF_EVEN)); @@ -2469,7 +2561,10 @@ driver.setState(2); driverService.updateById(driver); } - + + //修改行程信息 + fleetEngineUtil.updateTrip("CANCELED", null, null, 4, orderLogistics.getId(), null, null, null, null); + //添加消息 systemNoticeService.addSystemNotice(1, language == 1 ? "您已成功取消包裹订单,谢谢使用!" : language == 2 ? "You've cancelled the delivery order successfully, thank you for using I-GO " : "Vous avez annulé la commande de livraison avec succès, merci d’utiliser I-GO", orderLogistics.getUserId(), 1); diff --git a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java index 673d31a..bbcb17b 100644 --- a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java +++ b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java @@ -20,6 +20,7 @@ import com.stylefeng.guns.modular.system.service.*; import com.stylefeng.guns.modular.system.util.*; import com.stylefeng.guns.modular.system.util.GoogleMap.DistancematrixVo; +import com.stylefeng.guns.modular.system.util.GoogleMap.FleetEngineUtil; import com.stylefeng.guns.modular.system.util.GoogleMap.GoogleMapUtil; import com.stylefeng.guns.modular.system.util.GoogleMap.ReverseGeocodeVo; import com.stylefeng.guns.modular.system.util.Tingg.TinggPayUtil; @@ -199,6 +200,15 @@ @Autowired private IRedEnvelopePaymentSettingsService redEnvelopePaymentSettingsService; + + @Autowired + private FleetEngineUtil fleetEngineUtil; + + @Resource + private CarModelMapper carModelMapper; + + @Autowired + private ICarService carService; @@ -345,6 +355,26 @@ orderPrivateCar.setIsReassign(1); orderPrivateCar.setIsDelete(1); this.insert(orderPrivateCar); + + + Integer vehicleId = null; + if(null != orderPrivateCar.getDriverId()){ + Driver driver = driverService.selectById(orderPrivateCar.getDriverId()); + vehicleId = driver.getCarId(); + //查询车辆信息,没有则创建信息 + String vehicles = fleetEngineUtil.getVehicles(vehicleId); + if(ToolUtil.isEmpty(vehicles)){ + Car car = carService.selectById(vehicleId); + CarModel carModel = carModelMapper.selectById(car.getCarModelId()); + fleetEngineUtil.createVehicles(carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + fleetEngineUtil.updateVehicles("ONLINE", carModel.getSeat() - 1, car.getCarLicensePlate(), driver.getCarId()); + } + + } + //创建行程数据 + fleetEngineUtil.createTrip(vehicleId, 1, 1, orderPrivateCar.getId(), + orderPrivateCar.getStartLat().toString(), orderPrivateCar.getStartLon().toString(), orderPrivateCar.getEndLat().toString(), orderPrivateCar.getEndLon().toString()); + if(orderSource == 2){//扫码下单 new Thread(new Runnable() { @@ -686,6 +716,10 @@ driver.setState(2); driverService.updateById(driver); } + + //修改行程信息 + fleetEngineUtil.updateTrip("CANCELED", null, null, 1, orderPrivateCar.getId(), null, null, null, null); + //添加消息 systemNoticeService.addSystemNotice(1, language == 1 ? "您已成功取消出行订单,谢谢使用!" : language == 2 ? "You've cancelled the ride order successfully, thank you for using I-GO " : "Vous avez annulé la commande de course avec succès, merci d’utiliser I-GO", orderPrivateCar.getUserId(), 1); @@ -994,9 +1028,8 @@ //计算优惠券 UserCouponRecord userCouponRecord = null; if(null != couponId){ - //TODO 待翻译 if(null != redDeduction && 1 == redDeduction){ - return ResultUtil.error(language == 1 ? "优惠券和红包不能同时使用" : language == 2 ? "" : "", ""); + return ResultUtil.error(language == 1 ? "优惠券和红包不能同时使用" : language == 2 ? "Coupons and lucky-promo cannot be used at the same time." : "Les coupons et les bonus ne peuvent pas être utilisés en même temps", ""); } userCouponRecord = userCouponRecordService.selectById(couponId); if(!userCouponRecord.getCompanyId().equals(orderPrivateCar.getCompanyId())){ @@ -1985,8 +2018,7 @@ query.setRedPacketActivityId(id.getId()); userRedPacketRecordService.updateById(query); - // todo 待翻译 - String content = 1 == language ? ("您收到一个额度为GHS " + money + " 的红包,请查收") : 2 == language ? "" : ""; + String content = 1 == language ? ("您收到一个额度为GHS " + money + " 的红包,请查收") : 2 == language ? "You have received a lucky promo of GHS " + money + ", please check" : "Vous avez reçu un bonus de GHS " + money + ", veuillez vérifier"; systemNoticeService.addSystemNotice(1, content, query.getUserId(), 1); UserInfo userInfo = userInfoService.selectById(orderPrivateCar.getUserId()); diff --git a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/CarModelMapper.java b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/CarModelMapper.java new file mode 100644 index 0000000..ab316a7 --- /dev/null +++ b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/CarModelMapper.java @@ -0,0 +1,11 @@ +package com.stylefeng.guns.modular.system.dao; + +import com.baomidou.mybatisplus.mapper.BaseMapper; +import com.stylefeng.guns.modular.system.model.CarModel; + +/** + * @author zhibing.pu + * @Date 2024/5/27 14:03 + */ +public interface CarModelMapper extends BaseMapper<CarModel> { +} diff --git a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/CarModelMapper.tld b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/CarModelMapper.tld new file mode 100644 index 0000000..5961af1 --- /dev/null +++ b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/CarModelMapper.tld @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.stylefeng.guns.modular.system.dao.CarModelMapper"> + + +</mapper> \ No newline at end of file diff --git a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/CarModel.java b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/CarModel.java new file mode 100644 index 0000000..b923ded --- /dev/null +++ b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/CarModel.java @@ -0,0 +1,120 @@ +package com.stylefeng.guns.modular.system.model; + +import com.baomidou.mybatisplus.annotations.TableField; +import com.baomidou.mybatisplus.annotations.TableId; +import com.baomidou.mybatisplus.annotations.TableName; +import com.baomidou.mybatisplus.enums.IdType; + +import java.util.Date; + +/** + * 车辆型号 + */ +@TableName("t_car_model") +public class CarModel { + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + @TableField("id") + private Integer id; + /** + * 名称 + */ + @TableField("name") + private String name; + /** + * 备注 + */ + @TableField("remark") + private String remark; + /** + * 添加时间 + */ + @TableField("insertTime") + private Date insertTime; + /** + * 状态(1=正常,2=删除) + */ + @TableField("state") + private Integer state; + /** + * 座位数 + */ + @TableField("seat") + private Integer seat; + /** + * 车辆品牌id + */ + @TableField("brandId") + private Integer brandId; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public Date getInsertTime() { + return insertTime; + } + + public void setInsertTime(Date insertTime) { + this.insertTime = insertTime; + } + + public Integer getState() { + return state; + } + + public void setState(Integer state) { + this.state = state; + } + + public Integer getSeat() { + return seat; + } + + public void setSeat(Integer seat) { + this.seat = seat; + } + + public Integer getBrandId() { + return brandId; + } + + public void setBrandId(Integer brandId) { + this.brandId = brandId; + } + + @Override + public String toString() { + return "CarModel{" + + "id=" + id + + ", name='" + name + '\'' + + ", remark='" + remark + '\'' + + ", insertTime=" + insertTime + + ", state=" + state + + ", seat=" + seat + + ", brandId=" + brandId + + '}'; + } +} diff --git a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java new file mode 100644 index 0000000..cb511e9 --- /dev/null +++ b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/FleetEngineUtil.java @@ -0,0 +1,895 @@ +package com.stylefeng.guns.modular.system.util.GoogleMap; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import cn.hutool.http.Method; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.fleetengine.auth.AuthTokenMinter; +import com.google.fleetengine.auth.token.FleetEngineToken; +import com.google.fleetengine.auth.token.TripClaims; +import com.google.fleetengine.auth.token.VehicleClaims; +import com.google.fleetengine.auth.token.factory.signer.*; +import com.stylefeng.guns.modular.system.util.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Fleet Engine API 工具类 + * @author zhibing.pu + * @Date 2024/5/17 9:59 + */ +@Slf4j +@Component +public class FleetEngineUtil { + + static Logger logger = LoggerFactory.getLogger(FleetEngineUtil.class); + + private final String SERVICE_ACCOUNT = "odrd2024@i-go-odrd-testing.iam.gserviceaccount.com"; + + private final String privateKeyId = "0a9a480fafb6469c0c1b2fa6dbdf6d4bebe1ebed"; + + private final String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXZoPEFZeZb0C7DXzpPsloB+rQVQAJuR+z4T9uRCz33gBsIqrz1s5Iwd8vXYKKWzukMdXkwqR4WapI/4GtcpbJkRK93mKXvEE3sDz27BnRrZL4gHeECVpFy0egw29sqFM/x/cpst0goqq4/f3ZFGtQGIhSEEHMySQgTbZDIhXMIls1etRsM4K2bTXeMPn89ablPBdbKtTAJy1EI+ZLKbxnl9StyqBam+d+UsfVmNG19MsNbSzCKc+QPnPXb7dj9KxJ/2whog8w15qXQdJHAMeHZyNlqE0zVP7G1VdWo6Q4QtzmENANxBpJIEbAqY2sq3BZSqDd5XS9Dr9BR4XzQqQnAgMBAAECggEABFABAj4eph1vxVYRBH2TpvDGFU3uW7VBPjwp7JzntLAN8eNoPlqmEDP16y6D/HMmfftpAI3TvWA3+ZEPkiX6nVDyW6sGCodyP0QuJEob1HKHFYntzGtHhGg1KCOacLey6TYbJJmUtcsduQXGkocOPaLXNvjzr2mY2zthTDzJ6HzjDo3d2x/O+lUVlNjubTFydgU9bQP8zS389GgZkO/YebK9+qPRBXv1R2fmj0rhpLqC03jL/mUMKi5tW628OiJGdvzLXlAGyJ9CtVDjfrwUgLf8ML+3yfdmv7yFeWuJ2NEgQxKACixHM05qkCW2bOkPIi9+wb1BbVvMdYL+GCPvmQKBgQD/DZ8zpWfNAkl8h8NI0E7sPdN6wgGfPpaC8VpOE3EM2eEijkZZT6XjfxXjMv1vXg1UoeYVscPb99Ux6u2gq+ZJj6+IstNIObXgvrqNxKPw6OO2xCb6UmA4rQ74xe4d1KLN+C1zepgFYgU4ejungWzuPVL7x8xjdyBAvqgPqP1IbQKBgQDYMzXs2QcWr9tVwq1O3D/H6qX2DvelAj7j0vuXGtop1/aJW7bPlGJd9NGim8dnXLVSFyRteuVl4epa/C9h50g3FM/lFMl9lmp1HwpDeiSJYAGRH8cnPJjN/IV3cRl5qN8KUQE2a3BRP+6IPHJiF1Bc1vj08nTMsWmN+K6VcAzqYwKBgGGJ7RNMM0kkkcPtC5LCDxyrfD/bB9HFlrvW3ykyqC44+K9FZ8PqAM/inxU3P9KiTkjKbXpodDWgLskbResHMld5erC1arWZVGPxrNhgli2gcs1HcHyUmjWygSJEV47S7bwFKCScgpy0Yri5jiy+A1GM5Dpjq1dyjEQWZaEviEV1AoGBALoKn023l/T60QgkZNQmjS/wCG4LhSjWHN4ZMOxfa/pz369lX5OSwW7OfBKscFPOoC0Kwwr+pSYd2HgA6Jkb17WmUBt13skWRXeRhVh5Y7VfCxohuVNXPrqKoSMeDOj22y9ac2ur2lPgateLBHbKTxoE1uiZNs7pn8ZOh5UKfeK3AoGBAKjklIbZ05nvM/mzdPk9JfCFJ6SaQqeaQcU9AoLEQdOzIrrI660Ignn4hOzLSYac0GxytYTQzDt5xDHKBYqJfem7IqxkIj9hSnIZFnUxp6+VfBhXdWHGn+GDTQa1iDvfpy/h6Gr4NL+p/EoA17qtUqOlYxJ1Dkbaw3SqUtkbuv2G"; + + private final String provider = "i-go-odrd-testing"; + + @Autowired + private RedisUtil redisUtil; + + + + + + + /** + * 获取jwt token + * @param type 0=服务端,1=乘客,2=司机 + * @return + */ + public String fleetEngineAuth(int type, Integer id){ + try { + //谷歌云服务器使用这部分代码 +// AuthTokenMinter minter = AuthTokenMinter.builder() +// //服务端签名 +// .setServerSigner(DefaultServiceAccountSigner.create()) +// //司机端签名 +// .setDriverSigner(ImpersonatedSigner.create(SERVICE_ACCOUNT)) +// //乘客端签名 +// .setConsumerSigner(ImpersonatedSigner.create(SERVICE_ACCOUNT)) +// .build(); + AuthTokenMinter minter = AuthTokenMinter.builder() + //服务端签名 + .setServerSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + //司机端签名 + .setDriverSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + //乘客端签名 + .setConsumerSigner(LocalSigner.create(SERVICE_ACCOUNT, privateKeyId, privateKey)) + .build(); + + String jwt = ""; + if(0 == type){ + FleetEngineToken serverToken = minter.getServerToken(); + jwt = serverToken.jwt(); + } + if(1 == type){ + FleetEngineToken consumerToken = minter.getConsumerToken(TripClaims.create("I-GO-USER" + id)); + jwt = consumerToken.jwt(); + } + if(2 == type){ + FleetEngineToken driverToken = minter.getDriverToken(VehicleClaims.create("I-GO-CAR" + id)); + jwt = driverToken.jwt(); + } + return jwt; + } catch (SigningTokenException e) { + throw new RuntimeException(e); + } + } + + + + + /** + * 添加车辆 + * @param maximumCapacity 这辆车可以搭载的乘客总数 + * @param licensePlate 车牌号 + * @param id 车辆id + */ + public String createVehicles(int maximumCapacity, String licensePlate, Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles?vehicleId=" + "I-GO-CAR" + id; + HttpRequest post = HttpUtil.createPost(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + post.addHeaders(headers); + + JSONObject body = new JSONObject(); + body.put("vehicleState", "OFFLINE"); + body.put("supportedTripTypes", Arrays.asList("SHARED", "EXCLUSIVE")); + body.put("maximumCapacity", maximumCapacity); + + JSONObject category = new JSONObject(); + category.put("category", "TAXI"); + body.put("vehicleType", category); + JSONObject licensePlate1 = new JSONObject(); + licensePlate1.put("countryCode", "GH"); + licensePlate1.put("lastCharacter", getLastNumber(licensePlate)); + body.put("licensePlate", licensePlate1); + logger.info("创建车辆请求:{}", body.toJSONString()); + HttpRequest request = post.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("创建车辆结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return createVehicles(maximumCapacity, licensePlate, id); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "AUTO" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "3" + * }, + * "currentRouteSegmentVersion": "2024-05-23T03:05:23.293329Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + return response.body(); + } + + + /** + * 修改车辆信息 + * @param maximumCapacity + * @param licensePlate + * @param id + * @return + */ + public String updateVehicles(String vehicleState, Integer maximumCapacity, String licensePlate, Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles/" + "I-GO-CAR" + id + "?updateMask="; + List<String> sb = new ArrayList<>(); + if(!StringUtils.hasLength(vehicleState)){ + sb.add("vehicleState"); + } + if(null != maximumCapacity){ + sb.add("maximumCapacity"); + } + if(!StringUtils.hasLength(licensePlate)){ + sb.add("licensePlate"); + } + String collect = sb.stream().collect(Collectors.joining(",")); + url += collect; + + HttpRequest put = HttpUtil.createRequest(Method.PUT, url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + put.addHeaders(headers); + + JSONObject body = new JSONObject(); + /** + * UNKNOWN_VEHICLE_STATE 默认,用于未指定或无法识别的车辆状态。 + * OFFLINE 车辆不接受新行程。注意:在完成分配给车辆的行程时,车辆仍可继续在此状态下运行。 + * ONLINE 车辆正在接受新行程。 + */ + if(!StringUtils.hasLength(vehicleState)){ + body.put("vehicleState", vehicleState); + } + if(null != maximumCapacity){ + body.put("maximumCapacity", maximumCapacity); + } + if(!StringUtils.hasLength(licensePlate)){ + JSONObject licensePlate1 = new JSONObject(); + licensePlate1.put("countryCode", "GH"); + licensePlate1.put("lastCharacter", getLastNumber(licensePlate)); + body.put("licensePlate", licensePlate1); + } + body.put("supportedTripTypes", Arrays.asList("SHARED", "EXCLUSIVE")); + + JSONObject category = new JSONObject(); + category.put("category", "TAXI"); + body.put("vehicleType", category); + put.body(body.toJSONString()); + logger.info("修改车辆信息请求:{}", body.toJSONString()); + HttpResponse response = put.execute(); + logger.info("修改车辆信息结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return updateVehicles(vehicleState, maximumCapacity, licensePlate, id); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "TAXI" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "5" + * }, + * "currentRouteSegmentVersion": "2024-05-23T06:08:14.968942Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + return response.body(); + } + + + /** + * 获取车辆信息 + * @param id 车辆id + * @return + */ + public String getVehicles(Integer id) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/vehicles" + (null != id ? "/I-GO-CAR" + id : ""); + HttpRequest get = HttpUtil.createGet(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + get.addHeaders(headers); + + HttpResponse response = get.execute(); + logger.info("查询车辆结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 404){ + return ""; + } + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return getVehicles(id); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "vehicles": [ + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "AUTO" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "3" + * }, + * "currentRouteSegmentVersion": "2024-05-23T03:05:23.293329Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + * ], + * "totalSize": "1" + * } + * + * { + * "name": "providers/i-go-odrd-testing/vehicles/I-GO-CAR1", + * "vehicleState": "OFFLINE", + * "supportedTripTypes": [ + * "EXCLUSIVE", + * "SHARED" + * ], + * "maximumCapacity": 4, + * "vehicleType": { + * "category": "TAXI" + * }, + * "licensePlate": { + * "countryCode": "GH", + * "lastCharacter": "5" + * }, + * "currentRouteSegmentVersion": "2024-05-23T06:08:14.968942Z", + * "waypointsVersion": "2024-05-23T03:05:23.293329Z" + * } + */ + + return response.body(); + } + + + + /** + * 获取最后一个数字 + * @param str + * @return + */ + private String getLastNumber(String str){ + for (int i = str.length(); i > 0; i--) { + char c = str.charAt(i - 1); + if(String.valueOf(c).matches("\\d")){ + return str.substring(i - 1, i); + } + } + return "-1"; + } + + + /** + * 创建新的行程 + * @param vehicleId 车辆id + * @param numberOfPassengers 人数 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @param start_lat 起点纬度 + * @param start_lng 起点经度 + * @param end_lat 终点纬度 + * @param end_lng 终点经度 + * @return + */ + public String createTrip(Integer vehicleId, Integer numberOfPassengers, Integer orderType, Integer orderId, String start_lat, String start_lng, String end_lat, String end_lng) throws Exception{ + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips?tripId=" + "I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId; + HttpRequest post = HttpUtil.createPost(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + post.addHeaders(headers); + + JSONObject body = new JSONObject(); + body.put("vehicleId", "I-GO-CAR" + vehicleId); + body.put("tripStatus", "NEW"); + body.put("tripType", "SHARED"); + body.put("numberOfPassengers", numberOfPassengers); + + JSONObject pickupPoint = new JSONObject(); + JSONObject point = new JSONObject(); + point.put("latitude", start_lat); + point.put("longitude", start_lng); + pickupPoint.put("point", point); + body.put("pickupPoint", pickupPoint); + + JSONObject dropoffPoint = new JSONObject(); + JSONObject end_point = new JSONObject(); + end_point.put("latitude", end_lat); + end_point.put("longitude", end_lng); + dropoffPoint.put("point", end_point); + body.put("dropoffPoint", dropoffPoint); + logger.info("创建行程请求:{}", body.toJSONString()); + HttpRequest request = post.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("创建行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return createTrip(vehicleId, numberOfPassengers, orderType, orderId, start_lat, start_lng, end_lat, end_lng); + } + } + throw new Exception(body.toJSONString()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "NEW", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:05:37.935052Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:18:35.934167Z", + * "numberOfPassengers": 1, + * "remainingDistanceMeters": 0, + * "etaToFirstWaypoint": "2024-05-27T02:05:37.935052Z", + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:05:37.935052Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:18:35.934167Z", + * "duration": "777.999115s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentVersion": "2024-05-27T02:05:37.941167Z", + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "vehicleWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:05:37.935052Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:18:35.934167Z", + * "duration": "777.999115s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentEndPoint": { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE" + * }, + * "remainingWaypointsRouteVersion": "2024-05-27T02:05:37.941167Z", + * "currentRouteSegmentTrafficVersion": "2024-05-27T02:05:37.941167Z" + * } + */ + return response.body(); + } + + + /** + * 修改行程 + * @param tripStatus 行程状态 + * @param vehicleId 车辆id + * @param numberOfPassengers 人数 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @param start_lat 起点纬度 + * @param start_lng 起点经度 + * @param end_lat 终点纬度 + * @param end_lng 终点经度 + * @return + */ + public String updateTrip(String tripStatus, Integer vehicleId, Integer numberOfPassengers, Integer orderType, Integer orderId, String start_lat, String start_lng, String end_lat, String end_lng) throws Exception { + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips/" + "I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId + "?updateMask="; + List<String> sb = new ArrayList<>(); + if(null != vehicleId){ + sb.add("vehicleId"); + } + if(!StringUtils.hasLength(tripStatus)){ + sb.add("tripStatus"); + } + if(null != numberOfPassengers){ + sb.add("numberOfPassengers"); + } + if(!StringUtils.hasLength(start_lat) && !StringUtils.hasLength(start_lng)){ + sb.add("pickupPoint"); + } + + if(!StringUtils.hasLength(end_lat) && !StringUtils.hasLength(end_lng)){ + sb.add("dropoffPoint"); + } + String collect = sb.stream().collect(Collectors.joining(",")); + url += collect; + + HttpRequest put = HttpUtil.createRequest(Method.PUT, url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + put.addHeaders(headers); + + JSONObject body = new JSONObject(); + if(null != vehicleId){ + body.put("vehicleId", "I-GO-CAR" + vehicleId); + } + /** + * UNKNOWN_TRIP_STATUS 默认,用于未指定或无法识别的行程状态。 + * NEW 新建行程。 + * ENROUTE_TO_PICKUP 司机正在前往上车点。 + * ARRIVED_AT_PICKUP 司机已到达上车点。 + * ARRIVED_AT_INTERMEDIATE_DESTINATION 司机已到达中转目的地,正在等待乘客。 + * ENROUTE_TO_INTERMEDIATE_DESTINATION 司机正在前往中间目的地(而非下车点)。 + * ENROUTE_TO_DROPOFF 司机已接起乘客,正在前往下一个目的地。 + * COMPLETE 乘客已下车,行程已完成。 + * CANCELED 在司机、乘客或拼车服务提供商取车之前,行程被取消。 + */ + if(!StringUtils.hasLength(tripStatus)){ + body.put("tripStatus", tripStatus); + } + if(null != numberOfPassengers){ + body.put("numberOfPassengers", numberOfPassengers); + } + if(!StringUtils.hasLength(start_lat) && !StringUtils.hasLength(start_lng)){ + JSONObject pickupPoint = new JSONObject(); + JSONObject point = new JSONObject(); + point.put("latitude", start_lat); + point.put("longitude", start_lng); + pickupPoint.put("point", point); + body.put("pickupPoint", pickupPoint); + } + + if(!StringUtils.hasLength(end_lat) && !StringUtils.hasLength(end_lng)){ + JSONObject dropoffPoint = new JSONObject(); + JSONObject end_point = new JSONObject(); + end_point.put("latitude", end_lat); + end_point.put("longitude", end_lng); + dropoffPoint.put("point", end_point); + body.put("dropoffPoint", dropoffPoint); + } + logger.info("修改行程请求:{}", body.toJSONString()); + HttpRequest request = put.body(body.toJSONString()); + HttpResponse response = request.execute(); + logger.info("修改行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return updateTrip(tripStatus, vehicleId, numberOfPassengers, orderType, orderId, start_lat, start_lng, end_lat, end_lng); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "ENROUTE_TO_PICKUP", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:07:38.562717Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:20:36.562375Z", + * "numberOfPassengers": 1, + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "eta": "2024-05-27T02:07:38.562717Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:20:36.562375Z", + * "duration": "777.999658s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "vehicleWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "eta": "2024-05-27T02:07:38.562717Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:20:36.562375Z", + * "duration": "777.999658s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "remainingWaypointsRouteVersion": "2024-05-27T02:07:38.570569Z" + * } + * + * 取消订单后返回的结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "tripStatus": "CANCELED", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "numberOfPassengers": 1 + * } + */ + return response.body(); + } + + + + /** + * 获取行程信息 + * @param orderType 订单类型(1/4) + * @param orderId 订单id + * @return + */ + public String getTrip(Integer orderType, Integer orderId) throws Exception { + String google_token = redisUtil.getValue("google_token"); + if(!StringUtils.hasLength(google_token)){ + google_token = fleetEngineAuth(0, null); + redisUtil.setStrValue("google_token", google_token); + } + String url = "https://fleetengine.googleapis.com/v1/providers/" + provider + "/trips/I-GO-" + (orderType == 1 ? "RIDE" : "DELIVERY") + orderId; + HttpRequest get = HttpUtil.createGet(url); + Map<String, String> headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + google_token); + headers.put("Content-Type", "application/json"); + get.addHeaders(headers); + + HttpResponse response = get.execute(); + logger.info("查询行程结果:{}", response.body()); + JSONObject jsonObject = JSON.parseObject(response.body()); + JSONObject error = jsonObject.getJSONObject("error"); + if(null != error){ + Integer code = error.getInteger("code"); + if(code == 404){ + return ""; + } + if(code == 401){ + String reason = error.getJSONArray("details").getJSONObject(0).getString("reason"); + if(reason.equals("ACCESS_TOKEN_EXPIRED")){ + redisUtil.remove("google_token"); + return getTrip(orderType, orderId); + } + } + throw new Exception(response.body()); + } + /** + * 返回结果 + * { + * "name": "providers/i-go-odrd-testing/trips/I-GO-RIDE1", + * "vehicleId": "I-GO-CAR1", + * "tripStatus": "ENROUTE_TO_PICKUP", + * "tripType": "SHARED", + * "pickupPoint": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * }* }, + * "pickupTime": "2024-05-27T02:10:39.763347Z", + * "dropoffPoint": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "dropoffTime": "2024-05-27T02:23:37.762549Z", + * "numberOfPassengers": 1, + * "remainingDistanceMeters": 0, + * "etaToFirstWaypoint": "2024-05-27T02:10:39.763347Z", + * "remainingWaypoints": [ + * { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE", + * "distanceMeters": 0, + * "eta": "2024-05-27T02:10:39.763347Z", + * "duration": "0s" + * }, + * { + * "location": { + * "point": { + * "latitude": 30.636319, + * "longitude": 104.129219 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "DROP_OFF_WAYPOINT_TYPE", + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==", + * "distanceMeters": 8260, + * "eta": "2024-05-27T02:23:37.762549Z", + * "duration": "777.999202s", + * "trafficToWaypoint": { + * "speedReadingInterval": [ + * { + * "endPolylinePointIndex": 284, + * "speed": "NORMAL" + * } + * ], + * "encodedPathToWaypoint": "AhqdAq8NM2ZcYrZmDgDo4Z0B7887ka5C0v0Y8aUejs8f7gL98gGstAWPpQLU5gvsfcf3JPiXJ8vEDosr0coVsuEEwtYElQ2h6QGXHron0ALV4gTRlQHdiqEC5rWzAq6zBVPRrAX0rQS9mAGazgTx5ASmZ7EknJ4B2ALyGPAC8QO9DKY58RGtGoYGtASJEYAGxkzyFulZ0BbAEpOQAuQR2FfPlgKolAveP7u0CdC_JIy7Aojb6QHL2_EElKUCpgGgsiTbqQHHlgKPqAjHR8SIgQHnhinsjwqhFfZGk-cKlLUIy8cC498CxF28pwLcrginpiGQm5sB36aFAcuTJPCWCdiUCeh1w94JR7PiAsCKC-cTo-MLrLAm3JQJp7ML07sh4KEC0xLMhZAB65U6oO4m_7gh6IkLz-oh2-MCwLAC5OwC-wGbsQuouwiD9gKQsQLPQ_BN0-ICxwWo2QS3zwG_DewHyiTaBbcdzwimVL0jnYMC-5IC8VH3BcBDr2mVFLMKqQX0kQG54QH-Pqm3AdIHirsB8YEBooEBvSDF7QWK4wWhkUbymkPLCNEG_gi1nwTqnATlvgSupwEo5pwExgONJhj9CKEspblC2sVHwaYX8qYXheQF3rsBkrIBgcYRqoMBlpQBx4IB6owBhiq3jgGYpwGfuQHwuQWfKfUBmw70I5-5BeiREFPAC-cI8AgACFvHAgGIAq-HBcyYBefJFMjkFK-fFMyyBbOhAYCREIe_EbeFAcSSAY-wAegI_LwQ6I4BjW3r-hL8gRb_5gXkuAH7AcwMq8IE1C2ckgGHJ_wv--oEkLkBjC3ng17sxooCw5gBwAvz5hCM9BHzsxHomAHcqwW1jQX6gQWpvwGOuwGl-wWSgBPVxATZAa31BP7KEqnFE8LBBL0aiqsOnHBf-pIF6Q6ABNIHxTzezhLl3gSMDcXUBQzCiQG5pAHKiQTdsgGStAGQigGhkgXAuwWXhBD4lhSXlxScMtjEBfubAb-fBOAOgOsEiLETAA==" + * } + * } + * ], + * "currentRouteSegmentVersion": "2024-05-27T02:10:39.773373Z", + * "remainingWaypointsVersion": "2024-05-27T02:05:37.941167Z", + * "currentRouteSegmentEndPoint": { + * "location": { + * "point": { + * "latitude": 30.604131, + * "longitude": 104.151957 + * } + * }, + * "tripId": "I-GO-RIDE1", + * "waypointType": "PICKUP_WAYPOINT_TYPE" + * }, + * "remainingWaypointsRouteVersion": "2024-05-27T02:10:39.773373Z", + * "currentRouteSegmentTrafficVersion": "2024-05-27T02:10:39.773373Z", + * "view": "SDK" + * } + */ + + return response.body(); + } +} diff --git a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java index f15c5f7..74dce96 100644 --- a/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java +++ b/UserIGOTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GoogleMap/GoogleMapUtil.java @@ -11,7 +11,7 @@ */ public class GoogleMapUtil { - private final static String key = "AIzaSyA_FEliOkbkL1IAHQsnBpbpo9MlIp729H0"; + private final static String key = "AIzaSyCG6PsfkaCEc94VK2vIAZk1YYKvOS_Ewts"; /** -- Gitblit v1.7.1