xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/job/base/AbstractJob.java
New file @@ -0,0 +1,35 @@ package com.xiaopeng.automaticPilot.job.base; import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.order.job.utils.SpringContextsUtil; import com.xiaopeng.order.service.IXpCruiseOrderService; import com.xiaopeng.order.service.IXpOrderService; import com.xiaopeng.order.service.XpOrderTimeoutLogService; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class AbstractJob implements Job { protected Logger logger = LoggerFactory.getLogger(getClass()); @Override public abstract void execute(JobExecutionContext context) throws JobExecutionException; protected IXpOrderService xpOrderService; protected XpPushMessageClient xpPushMessageClient; protected XpOrderTimeoutLogService xpOrderTimeoutLogService; protected IXpCruiseOrderService xpCruiseOrderService; protected OrderMissionClient orderMissionClient; protected XpVehicleClient xpVehicleClient; public AbstractJob(){ this.xpOrderService = SpringContextsUtil.getBean(IXpOrderService.class); this.xpPushMessageClient = SpringContextsUtil.getBean(XpPushMessageClient.class); this.xpOrderTimeoutLogService = SpringContextsUtil.getBean(XpOrderTimeoutLogService.class); } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/job/base/QuartzManager.java
New file @@ -0,0 +1,129 @@ package com.xiaopeng.automaticPilot.job.base; import com.xiaopeng.order.job.base.TimeJobType; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import java.util.Date; import java.util.Map; public class QuartzManager { private static SchedulerFactory factory = new StdSchedulerFactory(); private static final String TRIGGER_NAME_PREFIX = "TRIGGER_PREFIX_"; private static final String JOB_NAME_PREFIX = "JOB_PREFIX_"; /** * 添加定时任务:具体某个时间点执行一次的任务,如:在某个2015-06-01 12:00发送一条消息 * * @param jobName * 具体的任务名+ID标识唯一 * @param jobType * @param date * @param jp */ public synchronized static void addJob(Class<? extends Job> jobClass, String jobName, TimeJobType jobType, Date date, Map<String, ? extends Object> jp) { //logger.debug("ADD JOB {},jobName={},jobTyep={},jobDate={},",jobClass.getName(),jobName,jobType,date); try { Scheduler sched = factory.getScheduler(); JobDetail job = JobBuilder.newJob(jobClass).withIdentity(JOB_NAME_PREFIX + jobName, jobType.getType()) .setJobData(new JobDataMap(jp)).build(); SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() .withIdentity(TRIGGER_NAME_PREFIX + jobName, jobType.getType()).startAt(date).build(); removeJob(jobName, jobType); sched.scheduleJob(job, trigger); if (!sched.isShutdown()) { sched.start(); } } catch (Exception e) { //logger.error("ADD JOB exception {},jobName={},jobTyep={},jobDate={},",jobClass.getName(),jobName,jobType,date); } } /** * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) * @param jobName * @param time */ public synchronized static void modifyJobTime(String jobName,TimeJobType jobType, Date time) { //logger.error("Update JOB exception,jobName={},jobTyep={},jobDate={}," ,jobName,jobType,time); try { JobKey jobKey = new JobKey(JOB_NAME_PREFIX + jobName, jobType.getType()); TriggerKey key = new TriggerKey(TRIGGER_NAME_PREFIX + jobName, jobType.getType()); Scheduler sched = factory.getScheduler(); SimpleTrigger trigger = (SimpleTrigger) sched.getTrigger(key); if(trigger == null) { return; } Date oldTime = trigger.getStartTime(); if (oldTime.getTime() != time.getTime()) { JobDetail jobDetail = sched.getJobDetail(jobKey); Class<? extends Job> objJobClass = jobDetail.getJobClass(); removeJob(jobName,jobType); Map<String, Object> jp = jobDetail.getJobDataMap(); addJob(objJobClass, jobName, jobType, time, jp); } } catch (Exception e) { // logger.error("Update JOB exception,jobName={},jobTyep={},jobDate={}," ,jobName,jobType,time); } } /** * 移除一个任务 * * @param jobName */ public synchronized static void removeJob(String jobName, TimeJobType jobType) { try { JobKey jobKey = new JobKey(JOB_NAME_PREFIX + jobName, jobType.getType()); TriggerKey key = new TriggerKey(TRIGGER_NAME_PREFIX + jobName, jobType.getType()); Scheduler sched = factory.getScheduler(); JobDetail detail = sched.getJobDetail(jobKey); if (detail != null) { sched.pauseJob(jobKey); sched.pauseTrigger(key);// 停止触发器 sched.unscheduleJob(key);// 移除触发器 sched.deleteJob(jobKey);// 删除任务 } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } /** * 启动所有定时任务 */ public synchronized static void startJobs() { try { Scheduler sched = factory.getScheduler(); sched.start(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } /** * 关闭所有定时任务 */ public synchronized static void shutdownJobs() { try { Scheduler sched = factory.getScheduler(); if (!sched.isShutdown()) { sched.shutdown(); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/job/base/TimeJobType.java
New file @@ -0,0 +1,30 @@ package com.xiaopeng.automaticPilot.job.base; /** * @Description 按时间点发布的任务类型 * @date 2025年2月17日 下午7:22:28 */ public enum TimeJobType { ORDER_CANCEL("order_cancel","订单取消"), ADD_CRUISE_MISSION("add_cruise_mission","添加巡游任务"), END_TRIP("end_trip","自动结束行程"); private String type; private String desc; private TimeJobType(String type, String desc) { this.type = type; this.desc = desc; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/job/exceptions/TimeException.java
New file @@ -0,0 +1,37 @@ package com.xiaopeng.automaticPilot.job.exceptions; /** * @文件说明:定时器任务执行异常 * @版权所有:成都喜来达 * @项目名称: fengsheng * @创建者: Leeyns * @创建日期: 2016年5月18日 * @最近修改者:Leeyns * @最近修改日期:2016年5月18日 */ public class TimeException extends Exception { /** * TODO */ private static final long serialVersionUID = 5703430073981692250L; private String message; public TimeException() { super(); } public TimeException(String message) { super(message); this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/job/jobs/AddCruiseMissionJob.java
New file @@ -0,0 +1,40 @@ package com.xiaopeng.automaticPilot.job.jobs; import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; import com.xiaopeng.api.model.order.XpCruiseOrder; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.order.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * 推送定时任务 * @author Administrator * */ @Slf4j public class AddCruiseMissionJob extends AbstractJob { public static final String name = "addCruiseMission_"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long orderId = maps.getLong("id"); try { log.info("开始执行添加任务"); XpCruiseOrder xpCruiseOrder = xpCruiseOrderService.getById(orderId); R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpCruiseOrder.getVehicleId()); if(xpVehicleR.getData().getState()==0){ orderMissionClient.pushOrder(new PushOrderDto(xpCruiseOrder.getVehicleVin(),xpCruiseOrder.getId(),null)); } }catch(Exception e){ e.printStackTrace(); } } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/job/jobs/EndTripJob.java
New file @@ -0,0 +1,41 @@ package com.xiaopeng.automaticPilot.job.jobs; import com.xiaopeng.api.model.order.XpOrder; import com.xiaopeng.api.model.order.XpOrderTimeoutLog; import com.xiaopeng.order.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * 推送定时任务 * @author Administrator * */ @Slf4j public class EndTripJob extends AbstractJob { public static final String name = "endTrip_"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long orderId = maps.getLong("id"); try { log.info("开始执行自动结束行程任务"); XpOrder xpOrder = xpOrderService.getById(orderId); xpOrderService.endTrip(xpOrder.getId(), String.valueOf(xpOrder.getAppUserId())); log.info("结束执行自动结束行程任务"); // 添加超时记录 XpOrderTimeoutLog xpOrderTimeoutLog = new XpOrderTimeoutLog(); xpOrderTimeoutLog.setOrderId(xpOrder.getId()); xpOrderTimeoutLog.setUserId(xpOrder.getAppUserId()); xpOrderTimeoutLogService.save(xpOrderTimeoutLog); }catch(Exception e){ e.printStackTrace(); } } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/job/jobs/OrderCancelJob.java
New file @@ -0,0 +1,40 @@ package com.xiaopeng.automaticPilot.job.jobs; import com.xiaopeng.api.model.order.XpOrder; import com.xiaopeng.order.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.Objects; /** * 直播推送定时任务 * @author Administrator * */ @Slf4j public class OrderCancelJob extends AbstractJob { public static final String name = "orderCancel_"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long orderId = maps.getLong("id"); try { log.info("开始执行订单取消任务"); XpOrder xpOrder = xpOrderService.getById(orderId); if(Objects.nonNull(xpOrder)){ log.info("订单取消开始"); xpOrderService.cancelOrder(String.valueOf(xpOrder.getId())); log.info("订单取消状态修改完成"); } }catch(Exception e){ e.printStackTrace(); } } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/job/utils/SpringContextsUtil.java
New file @@ -0,0 +1,37 @@ package com.xiaopeng.automaticPilot.job.utils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringContextsUtil implements ApplicationContextAware{ private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringContextsUtil.applicationContext == null) { SpringContextsUtil.applicationContext = applicationContext; } } // 获取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } // 通过name获取 Bean. public static Object getBean(String name) { return getApplicationContext().getBean(name); } // 通过class获取Bean. public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } // 通过name,以及Clazz返回指定的Bean public static <T> T getBean(String name, Class<T> clazz) { System.out.println(getApplicationContext().getBean(name, clazz)); return getApplicationContext().getBean(name, clazz); } } xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -27,6 +27,14 @@ import com.xiaopeng.api.vo.OrderType; import com.xiaopeng.api.vo.SystemEventType; import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.ActionType; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperationType; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.PointType; import com.xiaopeng.api.vo.automaticPilot.proto.up.navigationDeviationEvent.NavigationDeviationEvent; import com.xiaopeng.api.vo.automaticPilot.proto.up.navigationDeviationEvent.NavigationDeviationMessage; import com.xiaopeng.api.vo.automaticPilot.proto.up.orderStateUpdateEvent.OrderStatusInfoEvent; import com.xiaopeng.api.vo.automaticPilot.proto.up.systemStatusXpu.*; import com.xiaopeng.api.vo.automaticPilot.proto.up.xpuNavigationRequest.NavigationRequest; import com.xiaopeng.api.vo.automaticPilot.protobuf.*; import com.xiaopeng.api.vo.operation.RouteVo; import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo; @@ -846,6 +854,15 @@ lastXpCruiseOrder.setStatus(1); xpCruiseOrderClient.addCruiseOrder(lastXpCruiseOrder); // 获取点位id Long endPointId = xpCruiseOrder.getEndPointId(); // 获取点位信息 获取点位是否需要停车 // xpCruisePlanClient.getPlanPointInfo(endPointId); com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask.Builder taskBuilder = com.xiaopeng.api.vo.automaticPilot.protobuf.RtTask.newBuilder(); taskBuilder.setOrderId(lastXpCruiseOrder.getId()); taskBuilder.setTaskId("MISSION_"+ IdUtil.fastUUID()); xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleOperationsController.java
@@ -105,7 +105,8 @@ xpCruiseOrder.setOrderReverse(1); xpCruiseOrder.setLastOrderId(r.getData()); // 找到收车站点 R<XpCruiseOrder> returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder); if(returnCruisePoint!=null){ xpCruiseOrderClient.addCruiseOrder(returnCruisePoint.getData()); // 下发命令 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/AbstractJob.java
@@ -1,6 +1,10 @@ package com.xiaopeng.order.job.base; import com.xiaopeng.api.feignClient.automaticPilot.OrderMissionClient; import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.order.XpCruiseOrder; import com.xiaopeng.order.service.IXpCruiseOrderService; import com.xiaopeng.order.service.IXpOrderService; import com.xiaopeng.order.job.utils.SpringContextsUtil; import com.xiaopeng.order.service.XpOrderTimeoutLogService; @@ -19,7 +23,9 @@ protected IXpOrderService xpOrderService; protected XpPushMessageClient xpPushMessageClient; protected XpOrderTimeoutLogService xpOrderTimeoutLogService; protected IXpCruiseOrderService xpCruiseOrderService; protected OrderMissionClient orderMissionClient; protected XpVehicleClient xpVehicleClient; public AbstractJob(){ this.xpOrderService = SpringContextsUtil.getBean(IXpOrderService.class); this.xpPushMessageClient = SpringContextsUtil.getBean(XpPushMessageClient.class); xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/TimeJobType.java
@@ -6,6 +6,7 @@ */ public enum TimeJobType { ORDER_CANCEL("order_cancel","订单取消"), ADD_CRUISE_MISSION("add_cruise_mission","添加巡游任务"), END_TRIP("end_trip","自动结束行程"); private String type; private String desc; xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/AddCruiseMissionJob.java
New file @@ -0,0 +1,43 @@ package com.xiaopeng.order.job.jobs; import com.xiaopeng.api.dto.automaticPilot.PushOrderDto; import com.xiaopeng.api.model.order.XpCruiseOrder; import com.xiaopeng.api.model.order.XpOrder; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.order.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.Objects; /** * 推送定时任务 * @author Administrator * */ @Slf4j public class AddCruiseMissionJob extends AbstractJob { public static final String name = "addCruiseMission_"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long orderId = maps.getLong("id"); try { log.info("开始执行添加任务"); XpCruiseOrder xpCruiseOrder = xpCruiseOrderService.getById(orderId); R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpCruiseOrder.getVehicleId()); if(xpVehicleR.getData().getState()==0){ orderMissionClient.pushOrder(new PushOrderDto(xpCruiseOrder.getVehicleVin(),xpCruiseOrder.getId(),null)); } }catch(Exception e){ e.printStackTrace(); } } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -73,6 +73,7 @@ import com.xiaopeng.order.dto.MileageDto; import com.xiaopeng.order.job.base.QuartzManager; import com.xiaopeng.order.job.base.TimeJobType; import com.xiaopeng.order.job.jobs.AddCruiseMissionJob; import com.xiaopeng.order.job.jobs.EndTripJob; import com.xiaopeng.order.job.jobs.OrderCancelJob; import com.xiaopeng.order.mangodb.model.OrderTrajectory; @@ -104,6 +105,7 @@ import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; @@ -150,6 +152,7 @@ private final XpCruiseOrderMapper xpCruiseOrderMapper; private final XpTaskRuleClient xpTaskRuleClient; private final XpCruisePlanClient xpCruisePlanClient; @Autowired private MongoTemplate mongoTemplate; @@ -1484,8 +1487,23 @@ xpCruiseOrderMapper.insert(xpCruiseOrder); R<XpPoint> xpPointR = xpPointClient.queryById(order.getEndPointId()); XpPoint data = xpPointR.getData(); //下发命令 orderMissionClient.pushOrder(new PushOrderDto(vehicle.getVehicleVin(),xpCruiseOrder.getId(),null)); // 添加自动结束行程定时任务job Map<String, ? extends Object> jobMaps = new ImmutableMap.Builder<String, String>(). put("id", xpCruiseOrder.getId()) .build(); QuartzManager.addJob( AddCruiseMissionJob.class, (AddCruiseMissionJob.name + xpCruiseOrder.getId()).toUpperCase(), TimeJobType.ADD_CRUISE_MISSION, DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(data.getParkingTimeLimit())), jobMaps ); }