xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/base/AbstractJob.java
New file @@ -0,0 +1,24 @@ package com.xiaopeng.maintenance.job.base; import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient; import com.xiaopeng.maintenance.job.utils.SpringContextsUtil; 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 XpPushMessageClient xpPushMessageClient; public AbstractJob(){ this.xpPushMessageClient = SpringContextsUtil.getBean(XpPushMessageClient.class); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/base/QuartzManager.java
New file @@ -0,0 +1,134 @@ package com.xiaopeng.maintenance.job.base; 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(); SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() .withRepeatCount(0) .withMisfireHandlingInstructionFireNow(); SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() .withIdentity(TRIGGER_NAME_PREFIX + jobName, jobType.getType()) .startAt(date) .withSchedule(scheduleBuilder) .build(); removeJob(jobName, jobType); sched.scheduleJob(job, trigger); if (!sched.isShutdown()) { sched.start(); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) * @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) { throw new RuntimeException(e); } } /** * 移除一个任务 * * @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-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/base/TimeJobType.java
New file @@ -0,0 +1,33 @@ package com.xiaopeng.maintenance.job.base; /** * @Description 按时间点发布的任务类型 * @date 2025年2月17日 下午7:22:28 */ public enum TimeJobType { ELECTRONIC_EFFECT("electronic_effect","电子围栏生效"), ELECTRONIC_FAILURE("electronic_failure","电子围栏失效"), ACCIDENT_WILL_TIMEOUT("accident_will_timeout", "事故即将超时"), ACCIDENT_TIMEOUT("accident_timeout", "事故超时"); 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-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/exceptions/TimeException.java
New file @@ -0,0 +1,37 @@ package com.xiaopeng.maintenance.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-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/jobs/ElectronicEffectJob.java
New file @@ -0,0 +1,33 @@ package com.xiaopeng.maintenance.job.jobs; import com.xiaopeng.api.model.operation.XpElectronicFence; import com.xiaopeng.api.model.operation.XpElectronicFenceArea; import com.xiaopeng.maintenance.job.base.AbstractJob; import lombok.extern.slf4j.Slf4j; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import java.util.List; /** * 直播推送定时任务 * @author Administrator * */ @Slf4j public class ElectronicEffectJob extends AbstractJob { public static final String effect = "electronicEffect_"; public static final String failure = "electronicFailure_"; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap maps = context.getMergedJobDataMap(); Long electronicId = maps.getLong("id"); Long type = maps.getLong("type"); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/jobs/OrderCancelJob.java
New file @@ -0,0 +1,61 @@ package com.xiaopeng.maintenance.job.jobs;//package com.xiaopeng.operation.job.jobs; // //import com.alibaba.fastjson2.JSONObject; //import com.xiaopeng.api.dto.pushMessage.SendMessageDTO; //import com.xiaopeng.api.model.order.XpOrder; //import com.xiaopeng.common.core.enums.OrderStatusEnum; //import com.xiaopeng.common.core.enums.PushMessageTypeEnum; //import com.xiaopeng.operation.job.base.AbstractJob; //import lombok.extern.slf4j.Slf4j; //import org.quartz.JobDataMap; //import org.quartz.JobExecutionContext; //import org.quartz.JobExecutionException; // //import java.util.Date; //import java.util.HashMap; //import java.util.Map; //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)){ // xpOrder.setStatus(OrderStatusEnum.CANCELED.getCode()); // xpOrderService.updateById(xpOrder); // log.info("订单取消状态修改完成"); // // 消息推送 // Map<String, Object> params = new HashMap<>(); // Map<String, Object> content = new HashMap<>(); // content.put("orderId",xpOrder.getId()); // content.put("status",OrderStatusEnum.CANCELED.getCode()); // params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc()); // params.put("content", JSONObject.toJSONString(content)); // params.put("timestamp", new Date().getTime()+""); // String message = JSONObject.toJSONString(params); // SendMessageDTO sendMessageDTO = new SendMessageDTO(); // sendMessageDTO.setMessage(message); // sendMessageDTO.setAppUserId(String.valueOf(xpOrder.getAppUserId())); // xpPushMessageClient.sendStatus(sendMessageDTO); // log.info("订单取消消息推送完毕"); // } // }catch(Exception e){ // e.printStackTrace(); // } // } // //} xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/utils/SpringContextsUtil.java
New file @@ -0,0 +1,37 @@ package com.xiaopeng.maintenance.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-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/AccidentTaskTimeoutCheckScheduleTask.java
@@ -15,7 +15,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.time.LocalDateTime; @@ -35,7 +34,7 @@ * @author mitao * @since 2026-03-14 */ @Component @Deprecated public class AccidentTaskTimeoutCheckScheduleTask { private static final Logger log = LoggerFactory.getLogger(AccidentTaskTimeoutCheckScheduleTask.class); xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/AccidentTaskWillTimeoutScheduleTask.java
@@ -17,7 +17,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.time.Duration; @@ -38,7 +37,7 @@ * @author mitao * @since 2026-03-14 */ @Component @Deprecated public class AccidentTaskWillTimeoutScheduleTask { private static final Logger log = LoggerFactory.getLogger(AccidentTaskWillTimeoutScheduleTask.class); @@ -234,4 +233,3 @@ return vehicle == null ? "" : StringUtils.defaultString(vehicle.getPlateNumber()); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java
@@ -33,7 +33,7 @@ PageInfo<TaskPageListVO> pageList(TaskPageListQuery query); void saveVehicleAccident(SaveVehicleAccidentDto dto, XpOperationsUser xpOperationsUser); XpTask saveVehicleAccident(SaveVehicleAccidentDto dto, XpOperationsUser xpOperationsUser); R<TaskAccidentDetailVO> vehicleAccidentDetail(Long id); xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -190,7 +190,7 @@ @Override @Transactional @ShardingSphereTransactionType(TransactionType.BASE) public void saveVehicleAccident(SaveVehicleAccidentDto dto, XpOperationsUser xpOperationsUser) { public XpTask saveVehicleAccident(SaveVehicleAccidentDto dto, XpOperationsUser xpOperationsUser) { XpTask xpTask = new XpTask(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); @@ -254,10 +254,19 @@ xpTask.setExpiredNoticeSent(0); xpTask.setWillTimeoutNoticeSent(0); this.save(xpTask); if (xpTask.getId() == null && StringUtils.isNotBlank(xpTask.getTaskCode())) { XpTask savedTask = this.getOne(new LambdaQueryWrapper<XpTask>() .eq(XpTask::getTaskCode, xpTask.getTaskCode()) .last("limit 1")); if (savedTask != null && savedTask.getId() != null) { xpTask.setId(savedTask.getId()); } } // 异步发送消息通知 String plateNumber = Objects.nonNull(vehicle) ? vehicle.getPlateNumber() : ""; sendAccidentNotificationAsync(xpTask, plateNumber, taskRule.getProcessingTimeLimit()); return xpTask; } /** @@ -1182,6 +1191,11 @@ @Override public R assigneeTask(Long id, Long handlerUserId, Long assigneeUserId) { XpTask task = this.getById(id); // 查询规则 任务结束时间从任务分配时开始计算 XpTaskRule taskRule = xpTaskRuleMapper.selectOne(null); if (taskRule != null) { task.setEndTime(LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit())); } task.setAssigneeTime(LocalDateTime.now()); task.setHandleUserId(handlerUserId.toString()); task.setVehicleId(null); @@ -1202,14 +1216,7 @@ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); task.setTaskCode(code); // 查询规则 XpTaskRule taskRule = xpTaskRuleMapper.selectOne(null); if (taskRule != null) { task.setEndTime(LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit())); } task.setTaskCategory(2); // todo 临时处理 task.setHandleUserId("1"); task.setTaskTypeId(dto.getTaskTypeId()); task.setTaskUrgencyLevel(dto.getTaskUrgencyLevel()); task.setTaskDescription(dto.getTaskDescription());