| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- package net.yyc.quartz.service.impl;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import net.yyc.quartz.entity.JobBriefing;
- import net.yyc.quartz.entity.SysJob;
- import net.yyc.quartz.mapper.JobBriefingMapper;
- import net.yyc.quartz.service.JobBriefingService;
- import net.yyc.quartz.service.SysJobService;
- import org.springframework.stereotype.Service;
- import java.time.LocalDate;
- import java.time.LocalDateTime;
- import java.time.LocalTime;
- import java.util.*;
- import java.util.stream.Collectors;
- /**
- * 每日简报服务实现
- */
- @Slf4j
- @Service
- @RequiredArgsConstructor
- public class JobBriefingServiceImpl implements JobBriefingService {
- private final JobBriefingMapper jobBriefingMapper;
- private final SysJobService sysJobService;
- @Override
- public JobBriefing generateBriefing(LocalDate date) {
- LocalDateTime startTime = date.atStartOfDay();
- LocalDateTime endTime = date.atTime(LocalTime.MAX);
- // 1. 获取昨日执行的任务列表
- List<Integer> executedJobIds = jobBriefingMapper.selectExecutedJobIds(startTime, endTime);
- // 2. 获取当前运行中的任务
- List<SysJob> runningJobs = sysJobService.list(null);
- if (runningJobs == null) {
- runningJobs = Collections.emptyList();
- }
- List<SysJob> runningJobList = runningJobs.stream()
- .filter(job -> "2".equals(job.getJobStatus()))
- .collect(Collectors.toList());
- // 3. 计算任务列表并集(昨日执行 + 当前运行中)
- Set<Integer> allJobIds = new HashSet<>();
- allJobIds.addAll(executedJobIds);
- runningJobList.forEach(job -> allJobIds.add(job.getJobId()));
- // 4. 获取任务ID到任务的映射
- Map<Integer, SysJob> jobMap = new HashMap<>();
- for (SysJob job : runningJobList) {
- jobMap.put(job.getJobId(), job);
- }
- // 5. 查询昨日执行统计
- List<Map<String, Object>> statSummary = jobBriefingMapper.selectJobStatSummary(startTime, endTime);
- Map<Integer, Map<String, Object>> statMap = new HashMap<>();
- for (Map<String, Object> stat : statSummary) {
- Integer jobId = ((Number) stat.get("job_id")).intValue();
- statMap.put(jobId, stat);
- }
- // 6. 构建任务统计列表
- List<JobBriefing.JobStatInfo> jobStats = new ArrayList<>();
- for (Integer jobId : allJobIds) {
- SysJob sysJob = jobMap.get(jobId);
- Map<String, Object> stat = statMap.get(jobId);
- String jobName = sysJob != null ? sysJob.getJobName() : String.valueOf(stat != null ? stat.get("job_name") : "未知");
- String jobGroup = sysJob != null ? sysJob.getJobGroup() : String.valueOf(stat != null ? stat.get("job_group") : "未知");
- int execCount = 0, successCount = 0, failCount = 0;
- long avgExecuteTime = 0;
- String lastExecuteTime = null;
- String lastExecStatus = null;
- String exceptionInfo = null;
- if (stat != null) {
- execCount = ((Number) stat.get("execCount")).intValue();
- successCount = ((Number) stat.get("successCount")).intValue();
- failCount = ((Number) stat.get("failCount")).intValue();
- Object avgObj = stat.get("avgExecuteTime");
- if (avgObj != null) {
- avgExecuteTime = ((Number) avgObj).longValue();
- }
- lastExecuteTime = stat.get("lastExecuteTime") != null
- ? String.valueOf(stat.get("lastExecuteTime")) : null;
- }
- // 查询最新执行记录
- if (endTime != null) {
- Map<String, Object> lastLog = jobBriefingMapper.selectLastExecLog(jobId, LocalDateTime.now());
- if (lastLog != null) {
- lastExecStatus = "1".equals(String.valueOf(lastLog.get("job_log_status"))) ? "失败" : "成功";
- Object exInfo = lastLog.get("exception_info");
- if (exInfo != null && !"null".equals(String.valueOf(exInfo))) {
- exceptionInfo = String.valueOf(exInfo);
- if (exceptionInfo.length() > 200) {
- exceptionInfo = exceptionInfo.substring(0, 200) + "...";
- }
- }
- }
- }
- double successRate = execCount > 0 ? (double) successCount / execCount * 100 : 0;
- jobStats.add(JobBriefing.JobStatInfo.builder()
- .jobId(jobId)
- .jobName(jobName)
- .jobGroup(jobGroup)
- .execCount(execCount)
- .successCount(successCount)
- .failCount(failCount)
- .successRate(Math.round(successRate * 100) / 100.0)
- .avgExecuteTime(avgExecuteTime)
- .lastExecuteTime(lastExecuteTime)
- .lastExecStatus(lastExecStatus)
- .exceptionInfo(exceptionInfo)
- .build());
- }
- // 按任务名称排序
- jobStats.sort(Comparator.comparing(JobBriefing.JobStatInfo::getJobName));
- // 7. 检测错过执行的任务
- List<JobBriefing.MissedJobInfo> missedJobs = detectMissedJobs(date, startTime, endTime, executedJobIds, runningJobList);
- return JobBriefing.builder()
- .reportDate(date)
- .jobStats(jobStats)
- .missedJobs(missedJobs)
- .generatedAt(LocalDateTime.now())
- .build();
- }
- @Override
- public JobBriefing generateYesterdayBriefing() {
- return generateBriefing(LocalDate.now().minusDays(1));
- }
- /**
- * 检测错过执行的任务
- * 条件:任务状态=RUNNING(2) 且 next_time已过 且 昨日无执行记录
- */
- private List<JobBriefing.MissedJobInfo> detectMissedJobs(LocalDate date,
- LocalDateTime startTime,
- LocalDateTime endTime,
- List<Integer> executedJobIds,
- List<SysJob> runningJobList) {
- List<JobBriefing.MissedJobInfo> missed = new ArrayList<>();
- Set<Integer> executedSet = new HashSet<>(executedJobIds);
- LocalDateTime now = LocalDateTime.now();
- for (SysJob job : runningJobList) {
- // 跳过已删除的任务
- if ("4".equals(job.getJobStatus())) {
- continue;
- }
- // 检查昨日是否有执行记录
- if (executedSet.contains(job.getJobId())) {
- continue;
- }
- // 检查 next_time 是否已过
- if (job.getNextTime() != null && job.getNextTime().isBefore(now)) {
- missed.add(JobBriefing.MissedJobInfo.builder()
- .jobName(job.getJobName())
- .jobGroup(job.getJobGroup())
- .nextExecuteTime(job.getNextTime() != null ? job.getNextTime().toString() : null)
- .remark("下次执行时间已过,请检查任务调度")
- .build());
- }
- }
- return missed;
- }
- }
|