增加服务器管理认证方式,增加测试连接接口

This commit is contained in:
dengqichen 2025-10-30 17:07:31 +08:00
parent 10bfa7bcbd
commit bd7733d7d7
4 changed files with 160 additions and 104 deletions

View File

@ -89,6 +89,18 @@ public class ScheduleJobApiController extends BaseController<ScheduleJob, Schedu
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();
}
/**
* 立即触发任务
*/

View File

@ -81,7 +81,7 @@ public class ScheduleJob extends Entity<Long> {
*/
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false, length = 20)
private ScheduleJobStatusEnum status = ScheduleJobStatusEnum.ENABLED;
private ScheduleJobStatusEnum status;
/**
* 是否允许并发执行

View File

@ -41,6 +41,12 @@ public interface IScheduleJobService extends IBaseService<ScheduleJob, ScheduleJ
*/
void disableJob(Long jobId);
/**
* 恢复启用解除禁用任务
* @param jobId 任务ID
*/
void enableJob(Long jobId);
/**
* 立即执行一次任务仅限ENABLED和PAUSED状态
*

View File

@ -46,7 +46,7 @@ import java.util.stream.Collectors;
@Slf4j
@Service
public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, ScheduleJobDTO, ScheduleJobQuery, Long>
implements IScheduleJobService {
implements IScheduleJobService {
@Resource
private IScheduleJobRepository jobRepository;
@ -80,7 +80,7 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
public ScheduleJobDTO create(ScheduleJobDTO dto) {
// 检查任务名称唯一性
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);
}
@ -95,7 +95,7 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
// 2. 检查是否试图修改 status强制拦截
if (dto.getStatus() != null && dto.getStatus() != oldStatus) {
throw new BusinessException(ResponseCode.SCHEDULE_JOB_STATUS_CANNOT_UPDATE,
new Object[]{"请使用 /start、/pause、/resume、/disable 接口管理任务状态"});
new Object[] {"请使用 /start、/pause、/resume、/disable 接口管理任务状态"});
}
// 3. 强制保持原状态防止前端传入
@ -116,9 +116,9 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
// 重新创建JobDetail使用最新参数
JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
.withIdentity(jobKey)
.withDescription(job.getJobDescription())
.build();
.withIdentity(jobKey)
.withDescription(job.getJobDescription())
.build();
// 设置最新的JobDataMap
jobDetail.getJobDataMap().put("jobId", job.getId());
@ -129,9 +129,9 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
// 重新创建Trigger
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(getTriggerKey(id))
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
.build();
.withIdentity(getTriggerKey(id))
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
.build();
// 重新调度
scheduler.scheduleJob(jobDetail, trigger);
@ -160,34 +160,35 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
// 填充关联信息
List<ScheduleJobDTO> content = page.getContent().stream()
.peek(job -> {
// 填充分类信息
if (job.getCategoryId() != null) {
Optional<ScheduleJobCategory> categoryOptional = categoryRepository.findById(job.getCategoryId());
categoryOptional.ifPresent(category -> job.setCategory(categoryConverter.toDto(category)));
}
.peek(job -> {
// 填充分类信息
if (job.getCategoryId() != null) {
Optional<ScheduleJobCategory> categoryOptional = categoryRepository.findById(job.getCategoryId());
categoryOptional.ifPresent(category -> job.setCategory(categoryConverter.toDto(category)));
}
// 填充表单信息
if (job.getFormDefinitionId() != null) {
Optional<FormDefinition> formOptional = formDefinitionRepository.findById(job.getFormDefinitionId());
formOptional.ifPresent(form -> job.setFormDefinition(formDefinitionConverter.toDto(form)));
}
})
.collect(Collectors.toList());
// 填充表单信息
if (job.getFormDefinitionId() != null) {
Optional<FormDefinition> formOptional = formDefinitionRepository.findById(job.getFormDefinitionId());
formOptional.ifPresent(form -> job.setFormDefinition(formDefinitionConverter.toDto(form)));
}
})
.collect(Collectors.toList());
return new PageImpl<>(content, page.getPageable(), page.getTotalElements());
}
@Override
@Transactional
public void startJob(Long jobId) {
try {
ScheduleJob job = findEntityById(jobId);
// 创建JobDetail
JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
.withIdentity(getJobKey(jobId))
.withDescription(job.getJobDescription())
.build();
.withIdentity(getJobKey(jobId))
.withDescription(job.getJobDescription())
.build();
// 设置JobDataMap
jobDetail.getJobDataMap().put("jobId", job.getId());
@ -198,9 +199,9 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
// 创建Trigger
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(getTriggerKey(jobId))
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
.build();
.withIdentity(getTriggerKey(jobId))
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
.build();
// 调度任务
scheduler.scheduleJob(jobDetail, trigger);
@ -218,6 +219,7 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
}
@Override
@Transactional
public void pauseJob(Long jobId) {
try {
scheduler.pauseJob(getJobKey(jobId));
@ -236,6 +238,7 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
}
@Override
@Transactional
public void resumeJob(Long jobId) {
try {
scheduler.resumeJob(getJobKey(jobId));
@ -254,6 +257,7 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
}
@Override
@Transactional
public void disableJob(Long jobId) {
ScheduleJob job = findEntityById(jobId);
@ -283,6 +287,40 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
}
}
@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
public void triggerJob(Long jobId) {
// 检查任务状态
@ -314,9 +352,9 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
// 创建新的Trigger
CronTrigger newTrigger = trigger.getTriggerBuilder()
.withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
.build();
.withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
.build();
// 重新调度
scheduler.rescheduleJob(triggerKey, newTrigger);
@ -372,14 +410,14 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
if (statusDTO != null && "RUNNING".equals(statusDTO.getStatus())) {
JobDashboardDTO.RunningJobDTO runningJob = JobDashboardDTO.RunningJobDTO.builder()
.jobId(job.getId())
.jobName(job.getJobName())
.startTime(statusDTO.getStartTime() != null ?
statusDTO.getStartTime().format(formatter) : null)
.progress(statusDTO.getProgress())
.message(statusDTO.getMessage())
.status(statusDTO.getStatus())
.build();
.jobId(job.getId())
.jobName(job.getJobName())
.startTime(statusDTO.getStartTime() != null ?
statusDTO.getStartTime().format(formatter) : null)
.progress(statusDTO.getProgress())
.message(statusDTO.getMessage())
.status(statusDTO.getStatus())
.build();
runningJobs.add(runningJob);
}
}
@ -388,34 +426,34 @@ public class ScheduleJobServiceImpl extends BaseServiceImpl<ScheduleJob, Schedul
PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "executeTime"));
Page<ScheduleJobLog> logPage = jobLogRepository.findAll(pageRequest);
List<ScheduleJobLogDTO> recentLogs = logPage.getContent().stream()
.map(log -> {
ScheduleJobLogDTO dto = new ScheduleJobLogDTO();
dto.setId(log.getId());
dto.setJobId(log.getJobId());
dto.setJobName(log.getJobName());
dto.setExecuteTime(log.getExecuteTime());
dto.setFinishTime(log.getFinishTime());
dto.setStatus(log.getStatus());
dto.setResultMessage(log.getResultMessage());
dto.setExceptionInfo(log.getExceptionInfo());
return dto;
})
.collect(Collectors.toList());
.map(log -> {
ScheduleJobLogDTO dto = new ScheduleJobLogDTO();
dto.setId(log.getId());
dto.setJobId(log.getJobId());
dto.setJobName(log.getJobName());
dto.setExecuteTime(log.getExecuteTime());
dto.setFinishTime(log.getFinishTime());
dto.setStatus(log.getStatus());
dto.setResultMessage(log.getResultMessage());
dto.setExceptionInfo(log.getExceptionInfo());
return dto;
})
.collect(Collectors.toList());
// 4. 构建返回结果
JobDashboardDTO.JobSummaryDTO summary = JobDashboardDTO.JobSummaryDTO.builder()
.total(total)
.enabled(enabled)
.disabled(disabled)
.paused(paused)
.running((long) runningJobs.size())
.build();
.total(total)
.enabled(enabled)
.disabled(disabled)
.paused(paused)
.running((long) runningJobs.size())
.build();
return JobDashboardDTO.builder()
.summary(summary)
.runningJobs(runningJobs)
.recentLogs(recentLogs)
.build();
.summary(summary)
.runningJobs(runningJobs)
.recentLogs(recentLogs)
.build();
}
/**