“mitao”
2026-03-15 62f5e3dc1501bc9bf60467c31a2353a997a7cce6
bugfix
7个文件已添加
4个文件已修改
391 ■■■■■ 已修改文件
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/base/AbstractJob.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/base/QuartzManager.java 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/base/TimeJobType.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/exceptions/TimeException.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/jobs/ElectronicEffectJob.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/jobs/OrderCancelJob.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/job/utils/SpringContextsUtil.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/AccidentTaskTimeoutCheckScheduleTask.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/AccidentTaskWillTimeoutScheduleTask.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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());