增加服务器管理认证方式,增加测试连接接口
This commit is contained in:
parent
10bfa7bcbd
commit
bd7733d7d7
@ -89,6 +89,18 @@ public class ScheduleJobApiController extends BaseController<ScheduleJob, Schedu
|
|||||||
return Response.success();
|
return Response.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复启用禁用任务
|
||||||
|
*/
|
||||||
|
@Operation(summary = "启用定时任务", description = "恢复被禁用(DISABLED)的定时任务,重新注册调度,状态变为ENABLED")
|
||||||
|
@PostMapping("/{id}/enable")
|
||||||
|
public Response<Void> enableJob(
|
||||||
|
@Parameter(description = "任务ID", required = true) @PathVariable Long id
|
||||||
|
) {
|
||||||
|
scheduleJobService.enableJob(id);
|
||||||
|
return Response.success();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 立即触发任务
|
* 立即触发任务
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -81,7 +81,7 @@ public class ScheduleJob extends Entity<Long> {
|
|||||||
*/
|
*/
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@Column(name = "status", nullable = false, length = 20)
|
@Column(name = "status", nullable = false, length = 20)
|
||||||
private ScheduleJobStatusEnum status = ScheduleJobStatusEnum.ENABLED;
|
private ScheduleJobStatusEnum status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否允许并发执行
|
* 是否允许并发执行
|
||||||
|
|||||||
@ -41,6 +41,12 @@ public interface IScheduleJobService extends IBaseService<ScheduleJob, ScheduleJ
|
|||||||
*/
|
*/
|
||||||
void disableJob(Long jobId);
|
void disableJob(Long jobId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复启用(解除禁用)任务
|
||||||
|
* @param jobId 任务ID
|
||||||
|
*/
|
||||||
|
void enableJob(Long jobId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 立即执行一次任务(仅限ENABLED和PAUSED状态)
|
* 立即执行一次任务(仅限ENABLED和PAUSED状态)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -40,13 +40,13 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时任务Service实现
|
* 定时任务Service实现
|
||||||
*
|
*
|
||||||
* @author qichen
|
* @author qichen
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, ScheduleJobDTO, ScheduleJobQuery, Long>
|
public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, ScheduleJobDTO, ScheduleJobQuery, Long>
|
||||||
implements IScheduleJobService {
|
implements IScheduleJobService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private IScheduleJobRepository jobRepository;
|
private IScheduleJobRepository jobRepository;
|
||||||
@ -80,7 +80,7 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
public ScheduleJobDTO create(ScheduleJobDTO dto) {
|
public ScheduleJobDTO create(ScheduleJobDTO dto) {
|
||||||
// 检查任务名称唯一性
|
// 检查任务名称唯一性
|
||||||
if (jobRepository.existsByJobNameAndDeletedFalse(dto.getJobName())) {
|
if (jobRepository.existsByJobNameAndDeletedFalse(dto.getJobName())) {
|
||||||
throw new BusinessException(ResponseCode.DATA_ALREADY_EXISTS, new Object[]{"任务名称", dto.getJobName()});
|
throw new BusinessException(ResponseCode.DATA_ALREADY_EXISTS, new Object[] {"任务名称", dto.getJobName()});
|
||||||
}
|
}
|
||||||
return super.create(dto);
|
return super.create(dto);
|
||||||
}
|
}
|
||||||
@ -91,34 +91,34 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
// 1. 查询旧数据
|
// 1. 查询旧数据
|
||||||
ScheduleJob oldJob = findEntityById(id);
|
ScheduleJob oldJob = findEntityById(id);
|
||||||
ScheduleJobStatusEnum oldStatus = oldJob.getStatus();
|
ScheduleJobStatusEnum oldStatus = oldJob.getStatus();
|
||||||
|
|
||||||
// 2. 检查是否试图修改 status(强制拦截)
|
// 2. 检查是否试图修改 status(强制拦截)
|
||||||
if (dto.getStatus() != null && dto.getStatus() != oldStatus) {
|
if (dto.getStatus() != null && dto.getStatus() != oldStatus) {
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_STATUS_CANNOT_UPDATE,
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_STATUS_CANNOT_UPDATE,
|
||||||
new Object[]{"请使用 /start、/pause、/resume、/disable 接口管理任务状态"});
|
new Object[] {"请使用 /start、/pause、/resume、/disable 接口管理任务状态"});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 强制保持原状态(防止前端传入)
|
// 3. 强制保持原状态(防止前端传入)
|
||||||
dto.setStatus(oldStatus);
|
dto.setStatus(oldStatus);
|
||||||
|
|
||||||
// 4. 更新数据库
|
// 4. 更新数据库
|
||||||
ScheduleJobDTO updated = super.update(id, dto);
|
ScheduleJobDTO updated = super.update(id, dto);
|
||||||
|
|
||||||
// 5. 只有非 DISABLED 状态才需要重新调度
|
// 5. 只有非 DISABLED 状态才需要重新调度
|
||||||
if (oldStatus != ScheduleJobStatusEnum.DISABLED) {
|
if (oldStatus != ScheduleJobStatusEnum.DISABLED) {
|
||||||
try {
|
try {
|
||||||
JobKey jobKey = getJobKey(id);
|
JobKey jobKey = getJobKey(id);
|
||||||
if (scheduler.checkExists(jobKey)) {
|
if (scheduler.checkExists(jobKey)) {
|
||||||
ScheduleJob job = findEntityById(id);
|
ScheduleJob job = findEntityById(id);
|
||||||
|
|
||||||
// 先删除旧的Job
|
// 先删除旧的Job
|
||||||
scheduler.deleteJob(jobKey);
|
scheduler.deleteJob(jobKey);
|
||||||
|
|
||||||
// 重新创建JobDetail(使用最新参数)
|
// 重新创建JobDetail(使用最新参数)
|
||||||
JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
|
JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
|
||||||
.withIdentity(jobKey)
|
.withIdentity(jobKey)
|
||||||
.withDescription(job.getJobDescription())
|
.withDescription(job.getJobDescription())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 设置最新的JobDataMap
|
// 设置最新的JobDataMap
|
||||||
jobDetail.getJobDataMap().put("jobId", job.getId());
|
jobDetail.getJobDataMap().put("jobId", job.getId());
|
||||||
@ -129,18 +129,18 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
|
|
||||||
// 重新创建Trigger
|
// 重新创建Trigger
|
||||||
Trigger trigger = TriggerBuilder.newTrigger()
|
Trigger trigger = TriggerBuilder.newTrigger()
|
||||||
.withIdentity(getTriggerKey(id))
|
.withIdentity(getTriggerKey(id))
|
||||||
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
|
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 重新调度
|
// 重新调度
|
||||||
scheduler.scheduleJob(jobDetail, trigger);
|
scheduler.scheduleJob(jobDetail, trigger);
|
||||||
|
|
||||||
// 如果原来是 PAUSED,重新调度后也要暂停
|
// 如果原来是 PAUSED,重新调度后也要暂停
|
||||||
if (oldStatus == ScheduleJobStatusEnum.PAUSED) {
|
if (oldStatus == ScheduleJobStatusEnum.PAUSED) {
|
||||||
scheduler.pauseJob(jobKey);
|
scheduler.pauseJob(jobKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("任务配置已更新并重新调度:jobId={}, jobName={}", job.getId(), job.getJobName());
|
log.info("任务配置已更新并重新调度:jobId={}, jobName={}", job.getId(), job.getJobName());
|
||||||
}
|
}
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
@ -150,7 +150,7 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
} else {
|
} else {
|
||||||
log.info("任务配置已更新(DISABLED状态,不调度):jobId={}", id);
|
log.info("任务配置已更新(DISABLED状态,不调度):jobId={}", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,34 +160,35 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
|
|
||||||
// 填充关联信息
|
// 填充关联信息
|
||||||
List<ScheduleJobDTO> content = page.getContent().stream()
|
List<ScheduleJobDTO> content = page.getContent().stream()
|
||||||
.peek(job -> {
|
.peek(job -> {
|
||||||
// 填充分类信息
|
// 填充分类信息
|
||||||
if (job.getCategoryId() != null) {
|
if (job.getCategoryId() != null) {
|
||||||
Optional<ScheduleJobCategory> categoryOptional = categoryRepository.findById(job.getCategoryId());
|
Optional<ScheduleJobCategory> categoryOptional = categoryRepository.findById(job.getCategoryId());
|
||||||
categoryOptional.ifPresent(category -> job.setCategory(categoryConverter.toDto(category)));
|
categoryOptional.ifPresent(category -> job.setCategory(categoryConverter.toDto(category)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 填充表单信息
|
// 填充表单信息
|
||||||
if (job.getFormDefinitionId() != null) {
|
if (job.getFormDefinitionId() != null) {
|
||||||
Optional<FormDefinition> formOptional = formDefinitionRepository.findById(job.getFormDefinitionId());
|
Optional<FormDefinition> formOptional = formDefinitionRepository.findById(job.getFormDefinitionId());
|
||||||
formOptional.ifPresent(form -> job.setFormDefinition(formDefinitionConverter.toDto(form)));
|
formOptional.ifPresent(form -> job.setFormDefinition(formDefinitionConverter.toDto(form)));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return new PageImpl<>(content, page.getPageable(), page.getTotalElements());
|
return new PageImpl<>(content, page.getPageable(), page.getTotalElements());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public void startJob(Long jobId) {
|
public void startJob(Long jobId) {
|
||||||
try {
|
try {
|
||||||
ScheduleJob job = findEntityById(jobId);
|
ScheduleJob job = findEntityById(jobId);
|
||||||
|
|
||||||
// 创建JobDetail
|
// 创建JobDetail
|
||||||
JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
|
JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
|
||||||
.withIdentity(getJobKey(jobId))
|
.withIdentity(getJobKey(jobId))
|
||||||
.withDescription(job.getJobDescription())
|
.withDescription(job.getJobDescription())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 设置JobDataMap
|
// 设置JobDataMap
|
||||||
jobDetail.getJobDataMap().put("jobId", job.getId());
|
jobDetail.getJobDataMap().put("jobId", job.getId());
|
||||||
@ -198,19 +199,19 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
|
|
||||||
// 创建Trigger
|
// 创建Trigger
|
||||||
Trigger trigger = TriggerBuilder.newTrigger()
|
Trigger trigger = TriggerBuilder.newTrigger()
|
||||||
.withIdentity(getTriggerKey(jobId))
|
.withIdentity(getTriggerKey(jobId))
|
||||||
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
|
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 调度任务
|
// 调度任务
|
||||||
scheduler.scheduleJob(jobDetail, trigger);
|
scheduler.scheduleJob(jobDetail, trigger);
|
||||||
|
|
||||||
// 更新任务状态
|
// 更新任务状态
|
||||||
job.setStatus(ScheduleJobStatusEnum.ENABLED);
|
job.setStatus(ScheduleJobStatusEnum.ENABLED);
|
||||||
jobRepository.save(job);
|
jobRepository.save(job);
|
||||||
|
|
||||||
log.info("任务启动成功:jobId={}, jobName={}", jobId, job.getJobName());
|
log.info("任务启动成功:jobId={}, jobName={}", jobId, job.getJobName());
|
||||||
|
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
log.error("启动任务失败:jobId={}", jobId, e);
|
log.error("启动任务失败:jobId={}", jobId, e);
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_START_FAILED);
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_START_FAILED);
|
||||||
@ -218,17 +219,18 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public void pauseJob(Long jobId) {
|
public void pauseJob(Long jobId) {
|
||||||
try {
|
try {
|
||||||
scheduler.pauseJob(getJobKey(jobId));
|
scheduler.pauseJob(getJobKey(jobId));
|
||||||
|
|
||||||
// 更新任务状态
|
// 更新任务状态
|
||||||
ScheduleJob job = findEntityById(jobId);
|
ScheduleJob job = findEntityById(jobId);
|
||||||
job.setStatus(ScheduleJobStatusEnum.PAUSED);
|
job.setStatus(ScheduleJobStatusEnum.PAUSED);
|
||||||
jobRepository.save(job);
|
jobRepository.save(job);
|
||||||
|
|
||||||
log.info("任务暂停成功:jobId={}", jobId);
|
log.info("任务暂停成功:jobId={}", jobId);
|
||||||
|
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
log.error("暂停任务失败:jobId={}", jobId, e);
|
log.error("暂停任务失败:jobId={}", jobId, e);
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_PAUSE_FAILED);
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_PAUSE_FAILED);
|
||||||
@ -236,17 +238,18 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public void resumeJob(Long jobId) {
|
public void resumeJob(Long jobId) {
|
||||||
try {
|
try {
|
||||||
scheduler.resumeJob(getJobKey(jobId));
|
scheduler.resumeJob(getJobKey(jobId));
|
||||||
|
|
||||||
// 更新任务状态
|
// 更新任务状态
|
||||||
ScheduleJob job = findEntityById(jobId);
|
ScheduleJob job = findEntityById(jobId);
|
||||||
job.setStatus(ScheduleJobStatusEnum.ENABLED);
|
job.setStatus(ScheduleJobStatusEnum.ENABLED);
|
||||||
jobRepository.save(job);
|
jobRepository.save(job);
|
||||||
|
|
||||||
log.info("任务恢复成功:jobId={}", jobId);
|
log.info("任务恢复成功:jobId={}", jobId);
|
||||||
|
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
log.error("恢复任务失败:jobId={}", jobId, e);
|
log.error("恢复任务失败:jobId={}", jobId, e);
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_RESUME_FAILED);
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_RESUME_FAILED);
|
||||||
@ -254,15 +257,16 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public void disableJob(Long jobId) {
|
public void disableJob(Long jobId) {
|
||||||
ScheduleJob job = findEntityById(jobId);
|
ScheduleJob job = findEntityById(jobId);
|
||||||
|
|
||||||
// 幂等性检查
|
// 幂等性检查
|
||||||
if (job.getStatus() == ScheduleJobStatusEnum.DISABLED) {
|
if (job.getStatus() == ScheduleJobStatusEnum.DISABLED) {
|
||||||
log.info("任务已经是禁用状态:jobId={}, jobName={}", jobId, job.getJobName());
|
log.info("任务已经是禁用状态:jobId={}, jobName={}", jobId, job.getJobName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 从 Quartz 删除任务
|
// 从 Quartz 删除任务
|
||||||
JobKey jobKey = getJobKey(jobId);
|
JobKey jobKey = getJobKey(jobId);
|
||||||
@ -270,19 +274,53 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
scheduler.deleteJob(jobKey);
|
scheduler.deleteJob(jobKey);
|
||||||
log.info("从Quartz删除任务:jobId={}, jobName={}", jobId, job.getJobName());
|
log.info("从Quartz删除任务:jobId={}, jobName={}", jobId, job.getJobName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新数据库状态
|
// 更新数据库状态
|
||||||
job.setStatus(ScheduleJobStatusEnum.DISABLED);
|
job.setStatus(ScheduleJobStatusEnum.DISABLED);
|
||||||
jobRepository.save(job);
|
jobRepository.save(job);
|
||||||
|
|
||||||
log.info("任务已禁用:jobId={}, jobName={}", jobId, job.getJobName());
|
log.info("任务已禁用:jobId={}, jobName={}", jobId, job.getJobName());
|
||||||
|
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
log.error("禁用任务失败:jobId={}, jobName={}", jobId, job.getJobName(), e);
|
log.error("禁用任务失败:jobId={}, jobName={}", jobId, job.getJobName(), e);
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_DISABLE_FAILED);
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_DISABLE_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void enableJob(Long jobId) {
|
||||||
|
ScheduleJob job = findEntityById(jobId);
|
||||||
|
if (job.getStatus() != ScheduleJobStatusEnum.DISABLED) {
|
||||||
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_STATUS_CANNOT_UPDATE, new Object[] {"仅禁用状态任务可启用"});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 创建并调度新Job
|
||||||
|
JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
|
||||||
|
.withIdentity(getJobKey(jobId))
|
||||||
|
.withDescription(job.getJobDescription())
|
||||||
|
.build();
|
||||||
|
jobDetail.getJobDataMap().put("jobId", job.getId());
|
||||||
|
jobDetail.getJobDataMap().put("jobName", job.getJobName());
|
||||||
|
jobDetail.getJobDataMap().put("beanName", job.getBeanName());
|
||||||
|
jobDetail.getJobDataMap().put("methodName", job.getMethodName());
|
||||||
|
jobDetail.getJobDataMap().put("methodParams", job.getMethodParams());
|
||||||
|
|
||||||
|
Trigger trigger = TriggerBuilder.newTrigger()
|
||||||
|
.withIdentity(getTriggerKey(jobId))
|
||||||
|
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
scheduler.scheduleJob(jobDetail, trigger);
|
||||||
|
job.setStatus(ScheduleJobStatusEnum.ENABLED);
|
||||||
|
jobRepository.save(job);
|
||||||
|
log.info("任务从DISABLED恢复启用成功:jobId={}, jobName={}", jobId, job.getJobName());
|
||||||
|
} catch (SchedulerException e) {
|
||||||
|
log.error("恢复启用任务失败:jobId={}, jobName={}", jobId, job.getJobName(), e);
|
||||||
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_START_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void triggerJob(Long jobId) {
|
public void triggerJob(Long jobId) {
|
||||||
// 检查任务状态
|
// 检查任务状态
|
||||||
@ -291,11 +329,11 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
log.warn("禁用状态的任务不允许触发:jobId={}, jobName={}", jobId, job.getJobName());
|
log.warn("禁用状态的任务不允许触发:jobId={}, jobName={}", jobId, job.getJobName());
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_DISABLED_CANNOT_TRIGGER);
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_DISABLED_CANNOT_TRIGGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
scheduler.triggerJob(getJobKey(jobId));
|
scheduler.triggerJob(getJobKey(jobId));
|
||||||
log.info("立即触发任务:jobId={}, jobName={}", jobId, job.getJobName());
|
log.info("立即触发任务:jobId={}, jobName={}", jobId, job.getJobName());
|
||||||
|
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
log.error("触发任务失败:jobId={}, jobName={}", jobId, job.getJobName(), e);
|
log.error("触发任务失败:jobId={}, jobName={}", jobId, job.getJobName(), e);
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_TRIGGER_FAILED);
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_TRIGGER_FAILED);
|
||||||
@ -307,27 +345,27 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
try {
|
try {
|
||||||
TriggerKey triggerKey = getTriggerKey(jobId);
|
TriggerKey triggerKey = getTriggerKey(jobId);
|
||||||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||||
|
|
||||||
if (trigger == null) {
|
if (trigger == null) {
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_TRIGGER_NOT_FOUND);
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_TRIGGER_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建新的Trigger
|
// 创建新的Trigger
|
||||||
CronTrigger newTrigger = trigger.getTriggerBuilder()
|
CronTrigger newTrigger = trigger.getTriggerBuilder()
|
||||||
.withIdentity(triggerKey)
|
.withIdentity(triggerKey)
|
||||||
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
|
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 重新调度
|
// 重新调度
|
||||||
scheduler.rescheduleJob(triggerKey, newTrigger);
|
scheduler.rescheduleJob(triggerKey, newTrigger);
|
||||||
|
|
||||||
// 更新数据库
|
// 更新数据库
|
||||||
ScheduleJob job = findEntityById(jobId);
|
ScheduleJob job = findEntityById(jobId);
|
||||||
job.setCronExpression(cronExpression);
|
job.setCronExpression(cronExpression);
|
||||||
jobRepository.save(job);
|
jobRepository.save(job);
|
||||||
|
|
||||||
log.info("更新任务Cron表达式成功:jobId={}, cron={}", jobId, cronExpression);
|
log.info("更新任务Cron表达式成功:jobId={}, cron={}", jobId, cronExpression);
|
||||||
|
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
log.error("更新任务Cron表达式失败:jobId={}", jobId, e);
|
log.error("更新任务Cron表达式失败:jobId={}", jobId, e);
|
||||||
throw new BusinessException(ResponseCode.SCHEDULE_JOB_UPDATE_CRON_FAILED);
|
throw new BusinessException(ResponseCode.SCHEDULE_JOB_UPDATE_CRON_FAILED);
|
||||||
@ -337,9 +375,9 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
@Override
|
@Override
|
||||||
public void loadAllEnabledJobs() {
|
public void loadAllEnabledJobs() {
|
||||||
log.info("开始加载所有启用的定时任务...");
|
log.info("开始加载所有启用的定时任务...");
|
||||||
|
|
||||||
List<ScheduleJob> enabledJobs = jobRepository.findByStatusAndDeletedFalse(ScheduleJobStatusEnum.ENABLED);
|
List<ScheduleJob> enabledJobs = jobRepository.findByStatusAndDeletedFalse(ScheduleJobStatusEnum.ENABLED);
|
||||||
|
|
||||||
for (ScheduleJob job : enabledJobs) {
|
for (ScheduleJob job : enabledJobs) {
|
||||||
try {
|
try {
|
||||||
startJob(job.getId());
|
startJob(job.getId());
|
||||||
@ -348,7 +386,7 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
log.error("加载任务失败:jobId={}, jobName={}", job.getId(), job.getJobName(), e);
|
log.error("加载任务失败:jobId={}, jobName={}", job.getId(), job.getJobName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("定时任务加载完成,成功加载 {} 个任务", enabledJobs.size());
|
log.info("定时任务加载完成,成功加载 {} 个任务", enabledJobs.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,63 +397,63 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
|
|||||||
long enabled = jobRepository.countByStatusAndDeletedFalse(ScheduleJobStatusEnum.ENABLED);
|
long enabled = jobRepository.countByStatusAndDeletedFalse(ScheduleJobStatusEnum.ENABLED);
|
||||||
long disabled = jobRepository.countByStatusAndDeletedFalse(ScheduleJobStatusEnum.DISABLED);
|
long disabled = jobRepository.countByStatusAndDeletedFalse(ScheduleJobStatusEnum.DISABLED);
|
||||||
long paused = jobRepository.countByStatusAndDeletedFalse(ScheduleJobStatusEnum.PAUSED);
|
long paused = jobRepository.countByStatusAndDeletedFalse(ScheduleJobStatusEnum.PAUSED);
|
||||||
|
|
||||||
// 2. 获取正在执行的任务(从Redis)
|
// 2. 获取正在执行的任务(从Redis)
|
||||||
List<JobDashboardDTO.RunningJobDTO> runningJobs = new ArrayList<>();
|
List<JobDashboardDTO.RunningJobDTO> runningJobs = new ArrayList<>();
|
||||||
List<ScheduleJob> allJobs = jobRepository.findAll();
|
List<ScheduleJob> allJobs = jobRepository.findAll();
|
||||||
|
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
for (ScheduleJob job : allJobs) {
|
for (ScheduleJob job : allJobs) {
|
||||||
// ✅ 使用 JobStatusRedisService 读取 Hash 类型的状态数据
|
// ✅ 使用 JobStatusRedisService 读取 Hash 类型的状态数据
|
||||||
JobStatusDTO statusDTO = jobStatusRedisService.getJobStatus(job.getId());
|
JobStatusDTO statusDTO = jobStatusRedisService.getJobStatus(job.getId());
|
||||||
|
|
||||||
if (statusDTO != null && "RUNNING".equals(statusDTO.getStatus())) {
|
if (statusDTO != null && "RUNNING".equals(statusDTO.getStatus())) {
|
||||||
JobDashboardDTO.RunningJobDTO runningJob = JobDashboardDTO.RunningJobDTO.builder()
|
JobDashboardDTO.RunningJobDTO runningJob = JobDashboardDTO.RunningJobDTO.builder()
|
||||||
.jobId(job.getId())
|
.jobId(job.getId())
|
||||||
.jobName(job.getJobName())
|
.jobName(job.getJobName())
|
||||||
.startTime(statusDTO.getStartTime() != null ?
|
.startTime(statusDTO.getStartTime() != null ?
|
||||||
statusDTO.getStartTime().format(formatter) : null)
|
statusDTO.getStartTime().format(formatter) : null)
|
||||||
.progress(statusDTO.getProgress())
|
.progress(statusDTO.getProgress())
|
||||||
.message(statusDTO.getMessage())
|
.message(statusDTO.getMessage())
|
||||||
.status(statusDTO.getStatus())
|
.status(statusDTO.getStatus())
|
||||||
.build();
|
.build();
|
||||||
runningJobs.add(runningJob);
|
runningJobs.add(runningJob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 获取最近10条执行日志
|
// 3. 获取最近10条执行日志
|
||||||
PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "executeTime"));
|
PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "executeTime"));
|
||||||
Page<ScheduleJobLog> logPage = jobLogRepository.findAll(pageRequest);
|
Page<ScheduleJobLog> logPage = jobLogRepository.findAll(pageRequest);
|
||||||
List<ScheduleJobLogDTO> recentLogs = logPage.getContent().stream()
|
List<ScheduleJobLogDTO> recentLogs = logPage.getContent().stream()
|
||||||
.map(log -> {
|
.map(log -> {
|
||||||
ScheduleJobLogDTO dto = new ScheduleJobLogDTO();
|
ScheduleJobLogDTO dto = new ScheduleJobLogDTO();
|
||||||
dto.setId(log.getId());
|
dto.setId(log.getId());
|
||||||
dto.setJobId(log.getJobId());
|
dto.setJobId(log.getJobId());
|
||||||
dto.setJobName(log.getJobName());
|
dto.setJobName(log.getJobName());
|
||||||
dto.setExecuteTime(log.getExecuteTime());
|
dto.setExecuteTime(log.getExecuteTime());
|
||||||
dto.setFinishTime(log.getFinishTime());
|
dto.setFinishTime(log.getFinishTime());
|
||||||
dto.setStatus(log.getStatus());
|
dto.setStatus(log.getStatus());
|
||||||
dto.setResultMessage(log.getResultMessage());
|
dto.setResultMessage(log.getResultMessage());
|
||||||
dto.setExceptionInfo(log.getExceptionInfo());
|
dto.setExceptionInfo(log.getExceptionInfo());
|
||||||
return dto;
|
return dto;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// 4. 构建返回结果
|
// 4. 构建返回结果
|
||||||
JobDashboardDTO.JobSummaryDTO summary = JobDashboardDTO.JobSummaryDTO.builder()
|
JobDashboardDTO.JobSummaryDTO summary = JobDashboardDTO.JobSummaryDTO.builder()
|
||||||
.total(total)
|
.total(total)
|
||||||
.enabled(enabled)
|
.enabled(enabled)
|
||||||
.disabled(disabled)
|
.disabled(disabled)
|
||||||
.paused(paused)
|
.paused(paused)
|
||||||
.running((long) runningJobs.size())
|
.running((long) runningJobs.size())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return JobDashboardDTO.builder()
|
return JobDashboardDTO.builder()
|
||||||
.summary(summary)
|
.summary(summary)
|
||||||
.runningJobs(runningJobs)
|
.runningJobs(runningJobs)
|
||||||
.recentLogs(recentLogs)
|
.recentLogs(recentLogs)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user