From 60b521a2bd689271bb9e3a108e26c5c73e09e4f1 Mon Sep 17 00:00:00 2001 From: lihongjie0209 Date: Fri, 17 Nov 2023 10:31:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/lihongjie/coal/CoalApplication.java | 6 +- .../java/cn/lihongjie/coal/common/Ctx.java | 9 + .../cronJob/controller/CronJobController.java | 77 ++++++ .../coal/cronJob/dto/CreateCronJobDto.java | 21 ++ .../coal/cronJob/dto/CronJobDto.java | 25 ++ .../coal/cronJob/dto/RunOnceRequest.java | 13 + .../coal/cronJob/dto/UpdateCronJobDto.java | 21 ++ .../coal/cronJob/entity/CronJobEntity.java | 32 +++ .../coal/cronJob/mapper/CronJobMapper.java | 19 ++ .../cronJob/repository/CronJobRepository.java | 10 + .../coal/cronJob/service/CronJobService.java | 224 ++++++++++++++++++ .../coal/cronJob/service/CronScriptJob.java | 80 +++++++ .../controller/CronJobLogController.java | 60 +++++ .../cronJobLog/dto/CreateCronJobLogDto.java | 28 +++ .../coal/cronJobLog/dto/CronJobLogDto.java | 29 +++ .../cronJobLog/dto/UpdateCronJobLogDto.java | 28 +++ .../cronJobLog/entity/CronJobLogEntity.java | 48 ++++ .../cronJobLog/mapper/CronJobLogMapper.java | 19 ++ .../repository/CronJobLogRepository.java | 10 + .../cronJobLog/service/CronJobLogService.java | 75 ++++++ src/main/resources/config/dictionary.json | 14 ++ 21 files changed, 847 insertions(+), 1 deletion(-) create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/controller/CronJobController.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/dto/CreateCronJobDto.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/dto/CronJobDto.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/dto/RunOnceRequest.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/dto/UpdateCronJobDto.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/entity/CronJobEntity.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/mapper/CronJobMapper.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/repository/CronJobRepository.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/service/CronJobService.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJob/service/CronScriptJob.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJobLog/controller/CronJobLogController.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJobLog/dto/CreateCronJobLogDto.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJobLog/dto/CronJobLogDto.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJobLog/dto/UpdateCronJobLogDto.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJobLog/entity/CronJobLogEntity.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJobLog/mapper/CronJobLogMapper.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJobLog/repository/CronJobLogRepository.java create mode 100644 src/main/java/cn/lihongjie/coal/cronJobLog/service/CronJobLogService.java diff --git a/src/main/java/cn/lihongjie/coal/CoalApplication.java b/src/main/java/cn/lihongjie/coal/CoalApplication.java index 4ccde5ed..68b3de4c 100644 --- a/src/main/java/cn/lihongjie/coal/CoalApplication.java +++ b/src/main/java/cn/lihongjie/coal/CoalApplication.java @@ -1,7 +1,10 @@ package cn.lihongjie.coal; +import cn.lihongjie.coal.common.Ctx; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication @@ -9,6 +12,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; public class CoalApplication { public static void main(String[] args) { - SpringApplication.run(CoalApplication.class, args); + ConfigurableApplicationContext ctx = SpringApplication.run(CoalApplication.class, args); + Ctx.setContext(ctx); } } diff --git a/src/main/java/cn/lihongjie/coal/common/Ctx.java b/src/main/java/cn/lihongjie/coal/common/Ctx.java index 1c9b58ec..64fc4ef2 100644 --- a/src/main/java/cn/lihongjie/coal/common/Ctx.java +++ b/src/main/java/cn/lihongjie/coal/common/Ctx.java @@ -3,13 +3,18 @@ package cn.lihongjie.coal.common; import cn.lihongjie.coal.session.SessionService; import cn.lihongjie.coal.user.dto.UserDto; +import lombok.Getter; import lombok.experimental.UtilityClass; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.security.core.context.SecurityContextHolder; @UtilityClass public class Ctx { + @Getter + private static ConfigurableApplicationContext context; + public static String getUserId() { return getAuthentication().getUser().getId(); } @@ -41,4 +46,8 @@ public class Ctx { public static UserDto currentUser() { return getAuthentication().getUser(); } + + public static void setContext(ConfigurableApplicationContext context) { + Ctx.context = context; + } } diff --git a/src/main/java/cn/lihongjie/coal/cronJob/controller/CronJobController.java b/src/main/java/cn/lihongjie/coal/cronJob/controller/CronJobController.java new file mode 100644 index 00000000..e13d1082 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/controller/CronJobController.java @@ -0,0 +1,77 @@ +package cn.lihongjie.coal.cronJob.controller; + +import cn.lihongjie.coal.annotation.SysLog; +import cn.lihongjie.coal.base.dto.CommonQuery; +import cn.lihongjie.coal.base.dto.IdRequest; +import cn.lihongjie.coal.cronJob.dto.CreateCronJobDto; +import cn.lihongjie.coal.cronJob.dto.CronJobDto; +import cn.lihongjie.coal.cronJob.dto.RunOnceRequest; +import cn.lihongjie.coal.cronJob.dto.UpdateCronJobDto; +import cn.lihongjie.coal.cronJob.service.CronJobService; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/cronJob") +@SysLog( + module = "定时任务" +) +@Slf4j +public class CronJobController { + @Autowired + private CronJobService service; + + @PostMapping("/create") + public CronJobDto create(@RequestBody CreateCronJobDto request) { + return this.service.create(request) + ; + } + + @PostMapping("/update") + public CronJobDto update(@RequestBody UpdateCronJobDto request) { + return this.service.update(request) + ; + } + + @PostMapping("/delete") + public Object delete(@RequestBody IdRequest request) { + this.service.delete(request); + return true + ; + } + + @PostMapping("/runOnce") + public Object runOnce(@RequestBody RunOnceRequest request) { + this.service.runOnce(request); + return true + ; + } + + + @PostMapping("/switchStatus") + public Object switchStatus(@RequestBody IdRequest request) { + this.service.switchStatus(request); + return true + ; + } + @PostMapping("/getById") + public CronJobDto getById(@RequestBody IdRequest request) { + return this.service.getById(request.getId()) + ; + } + + @PostMapping("/list") + public Page list(@RequestBody CommonQuery request) { + return this.service.list(request) + ; + } + + +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/dto/CreateCronJobDto.java b/src/main/java/cn/lihongjie/coal/cronJob/dto/CreateCronJobDto.java new file mode 100644 index 00000000..469d412a --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/dto/CreateCronJobDto.java @@ -0,0 +1,21 @@ +package cn.lihongjie.coal.cronJob.dto; + +import cn.lihongjie.coal.base.dto.CommonDto; + +import lombok.Data; + +import org.hibernate.annotations.Comment; + +@Data +public class CreateCronJobDto extends CommonDto { + private String script; + + @Comment("cron表达式") + private String cron; + + @Comment("quartz job id") + private String quartzJobId; + + @Comment("quartz trigger id") + private String quartzTriggerId; +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/dto/CronJobDto.java b/src/main/java/cn/lihongjie/coal/cronJob/dto/CronJobDto.java new file mode 100644 index 00000000..60a419b9 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/dto/CronJobDto.java @@ -0,0 +1,25 @@ +package cn.lihongjie.coal.cronJob.dto; + +import cn.lihongjie.coal.base.dto.CommonDto; +import cn.lihongjie.coal.script.entity.ScriptEntity; + +import jakarta.persistence.ManyToOne; + +import lombok.Data; + +import org.hibernate.annotations.Comment; + +@Data +public class CronJobDto extends CommonDto { + @ManyToOne + private ScriptEntity script; + + @Comment("cron表达式") + private String cron; + + @Comment("quartz job id") + private String quartzJobId; + + @Comment("quartz trigger id") + private String quartzTriggerId; +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/dto/RunOnceRequest.java b/src/main/java/cn/lihongjie/coal/cronJob/dto/RunOnceRequest.java new file mode 100644 index 00000000..1626e3c1 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/dto/RunOnceRequest.java @@ -0,0 +1,13 @@ +package cn.lihongjie.coal.cronJob.dto; + +import lombok.Data; + +import java.util.*; + +@Data +public class RunOnceRequest { + + private String id; + + private String params; +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/dto/UpdateCronJobDto.java b/src/main/java/cn/lihongjie/coal/cronJob/dto/UpdateCronJobDto.java new file mode 100644 index 00000000..d0717410 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/dto/UpdateCronJobDto.java @@ -0,0 +1,21 @@ +package cn.lihongjie.coal.cronJob.dto; + +import cn.lihongjie.coal.base.dto.CommonDto; + +import lombok.Data; + +import org.hibernate.annotations.Comment; + +@Data +public class UpdateCronJobDto extends CommonDto { + private String script; + + @Comment("cron表达式") + private String cron; + + @Comment("quartz job id") + private String quartzJobId; + + @Comment("quartz trigger id") + private String quartzTriggerId; +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/entity/CronJobEntity.java b/src/main/java/cn/lihongjie/coal/cronJob/entity/CronJobEntity.java new file mode 100644 index 00000000..8578abd0 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/entity/CronJobEntity.java @@ -0,0 +1,32 @@ +package cn.lihongjie.coal.cronJob.entity; + +import cn.lihongjie.coal.base.entity.CommonEntity; +import cn.lihongjie.coal.script.entity.ScriptEntity; + +import jakarta.persistence.Entity; +import jakarta.persistence.ManyToOne; + +import lombok.Data; + +import org.hibernate.annotations.Comment; + +@Data +@Entity +public class CronJobEntity extends CommonEntity { + + @ManyToOne + private ScriptEntity script; + + @Comment("cron表达式") + private String cron; + + @Comment("quartz job id") + private String quartzJobId; + + @Comment("quartz trigger id") + private String quartzTriggerId; + + + + +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/mapper/CronJobMapper.java b/src/main/java/cn/lihongjie/coal/cronJob/mapper/CronJobMapper.java new file mode 100644 index 00000000..1f2bdfab --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/mapper/CronJobMapper.java @@ -0,0 +1,19 @@ +package cn.lihongjie.coal.cronJob.mapper; + +import cn.lihongjie.coal.base.mapper.BaseMapper; +import cn.lihongjie.coal.base.mapper.CommonMapper; +import cn.lihongjie.coal.cronJob.dto.CreateCronJobDto; +import cn.lihongjie.coal.cronJob.dto.CronJobDto; +import cn.lihongjie.coal.cronJob.dto.UpdateCronJobDto; +import cn.lihongjie.coal.cronJob.entity.CronJobEntity; + +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; + +@Mapper( + componentModel = org.mapstruct.MappingConstants.ComponentModel.SPRING, + uses = {CommonMapper.class}, + mappingControl = DeepClone.class +) +public interface CronJobMapper extends BaseMapper { +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/repository/CronJobRepository.java b/src/main/java/cn/lihongjie/coal/cronJob/repository/CronJobRepository.java new file mode 100644 index 00000000..3c5be268 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/repository/CronJobRepository.java @@ -0,0 +1,10 @@ +package cn.lihongjie.coal.cronJob.repository; + +import cn.lihongjie.coal.base.dao.BaseRepository; +import cn.lihongjie.coal.cronJob.entity.CronJobEntity; + +import org.springframework.stereotype.Repository; + +@Repository +public interface CronJobRepository extends BaseRepository { +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/service/CronJobService.java b/src/main/java/cn/lihongjie/coal/cronJob/service/CronJobService.java new file mode 100644 index 00000000..cad29517 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/service/CronJobService.java @@ -0,0 +1,224 @@ +package cn.lihongjie.coal.cronJob.service; + +import static java.util.Collections.singletonList; + +import cn.lihongjie.coal.base.dto.CommonQuery; +import cn.lihongjie.coal.base.dto.IdRequest; +import cn.lihongjie.coal.base.service.BaseService; +import cn.lihongjie.coal.cronJob.dto.CreateCronJobDto; +import cn.lihongjie.coal.cronJob.dto.CronJobDto; +import cn.lihongjie.coal.cronJob.dto.RunOnceRequest; +import cn.lihongjie.coal.cronJob.dto.UpdateCronJobDto; +import cn.lihongjie.coal.cronJob.entity.CronJobEntity; +import cn.lihongjie.coal.cronJob.mapper.CronJobMapper; +import cn.lihongjie.coal.cronJob.repository.CronJobRepository; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import org.apache.commons.lang3.StringUtils; +import org.quartz.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.convert.ConversionService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +@Service +@Slf4j +@Transactional +public class CronJobService extends BaseService { + @Autowired private CronJobRepository repository; + + @Autowired private Scheduler scheduler; + + @Autowired private CronJobMapper mapper; + + @Autowired private ConversionService conversionService; + + @SneakyThrows + public CronJobDto create(CreateCronJobDto request) { + CronJobEntity entity = mapper.toEntity(request); + + this.repository.save(entity); + + entity.setQuartzJobId(UUID.randomUUID().toString()); + entity.setQuartzTriggerId(UUID.randomUUID().toString()); + JobDetail jobDetail = + JobBuilder.newJob(CronScriptJob.class) + .withIdentity(entity.getQuartzJobId()) + .usingJobData("id", entity.getId()) + .storeDurably() + .build(); + + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(entity.getCron()); + // 创建任务触发器 + Trigger trigger = + TriggerBuilder.newTrigger() + .forJob(jobDetail) + .withIdentity(entity.getQuartzTriggerId()) + .withSchedule(scheduleBuilder) + .build(); + // 手动将触发器与任务绑定到调度器内 + scheduler.scheduleJob(jobDetail, trigger); + + if (entity.getStatus() == 0){ + scheduler.pauseTrigger(TriggerKey.triggerKey(entity.getQuartzTriggerId())); + }else { + scheduler.resumeTrigger(TriggerKey.triggerKey(entity.getQuartzTriggerId())); + + } + + this.repository.save(entity); + return getById(entity.getId()); + } + + @SneakyThrows + public CronJobDto update(UpdateCronJobDto request) { + CronJobEntity entity = this.repository.get(request.getId()); + String oldCron = entity.getCron(); + this.mapper.updateEntity(entity, request); + + + if (StringUtils.isEmpty(entity.getQuartzJobId())) { + entity.setQuartzJobId(UUID.randomUUID().toString()); + } + if (StringUtils.isEmpty(entity.getQuartzTriggerId())) { + entity.setQuartzTriggerId(UUID.randomUUID().toString()); + } + + Trigger trigger = scheduler.getTrigger(TriggerKey.triggerKey(entity.getQuartzTriggerId())); + + JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(entity.getQuartzTriggerId())); + + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(entity.getCron()); + boolean newJob = false; + if (jobDetail == null) { + + jobDetail = + JobBuilder.newJob(CronScriptJob.class) + .withIdentity(entity.getQuartzJobId()) + .usingJobData("id", entity.getId()) + .storeDurably() + .build(); + newJob = true; + } + + if (trigger == null) { + trigger = + TriggerBuilder.newTrigger() + .forJob(jobDetail) + .withIdentity(entity.getQuartzTriggerId()) + .withSchedule(scheduleBuilder) + .build(); + scheduler.scheduleJob(jobDetail, trigger); + } else if (!StringUtils.equals(request.getCron(), oldCron)) { + + trigger = + TriggerBuilder.newTrigger() + .forJob(jobDetail) + .withIdentity(entity.getQuartzTriggerId()) + .withSchedule(scheduleBuilder) + .build(); + if (newJob) { + scheduler.scheduleJob(jobDetail, trigger); + } else { + + scheduler.rescheduleJob(trigger.getKey(), trigger); + } + }else { + + + + } + + if (entity.getStatus() == 0){ + scheduler.pauseTrigger(TriggerKey.triggerKey(entity.getQuartzTriggerId())); + }else { + scheduler.resumeTrigger(TriggerKey.triggerKey(entity.getQuartzTriggerId())); + + } + + this.repository.save(entity); + + return getById(entity.getId()); + } + + @SneakyThrows + public void switchStatus(IdRequest request){ + + List all = this.repository.findAllById(request.getIds()); + + + for (CronJobEntity job : all) { + + if (job.getStatus() == 0){ + scheduler.resumeTrigger(TriggerKey.triggerKey(job.getQuartzTriggerId())); + job.setStatus(1); + + }else{ + + scheduler.pauseTrigger(TriggerKey.triggerKey(job.getQuartzTriggerId())); + job.setStatus(1); + } + + } + + this.repository.saveAll(all); + } + + + @SneakyThrows + public void runOnce(RunOnceRequest request){ + + List all = this.repository.findAllById(singletonList(request.getId())); + + for (CronJobEntity job : all) { + + HashMap map = new HashMap<>(); + map.put("id", job.getId()); + map.put("params", request.getParams()); + scheduler.triggerJob(JobKey.jobKey(job.getQuartzJobId()), new JobDataMap(map)); + } + + } + + @SneakyThrows + public void delete(IdRequest request) { + + List all = this.repository.findAllById(request.getIds()); + + + for (CronJobEntity job : all) { + + scheduler.unscheduleJob(TriggerKey.triggerKey(job.getQuartzTriggerId())); + scheduler.deleteJob(JobKey.jobKey(job.getQuartzJobId())); + } + + this.repository.deleteAllById(request.getIds()); + } + + public CronJobDto getById(String id) { + CronJobEntity entity = repository.get(id); + + return mapper.toDto(entity); + } + + public Page list(CommonQuery query) { + Page page = + repository.findAll( + query.specification(conversionService), + PageRequest.of( + query.getPageNo(), + query.getPageSize(), + Sort.by(query.getOrders()))); + + return page.map(this.mapper::toDto); + } +} diff --git a/src/main/java/cn/lihongjie/coal/cronJob/service/CronScriptJob.java b/src/main/java/cn/lihongjie/coal/cronJob/service/CronScriptJob.java new file mode 100644 index 00000000..4558166a --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJob/service/CronScriptJob.java @@ -0,0 +1,80 @@ +package cn.lihongjie.coal.cronJob.service; + +import cn.lihongjie.coal.common.Ctx; +import cn.lihongjie.coal.cronJob.dto.CronJobDto; +import cn.lihongjie.coal.cronJob.entity.CronJobEntity; +import cn.lihongjie.coal.cronJobLog.entity.CronJobLogEntity; +import cn.lihongjie.coal.cronJobLog.service.CronJobLogService; +import cn.lihongjie.coal.script.dto.ScriptExecResultDto; +import cn.lihongjie.coal.script.service.ScriptService; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.context.ConfigurableApplicationContext; + +import java.time.LocalDateTime; +import java.util.*; + +@Slf4j +public class CronScriptJob implements Job { + @SneakyThrows + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + + LocalDateTime start = LocalDateTime.now(); + + ConfigurableApplicationContext applicationContext = Ctx.getContext(); + + ScriptService scriptService = applicationContext.getBean(ScriptService.class); + + CronJobService cronJobService = applicationContext.getBean(CronJobService.class); + ObjectMapper objectMapper = applicationContext.getBean(ObjectMapper.class); + CronJobLogService cronJobLogService = applicationContext.getBean(CronJobLogService.class); + + Object cronJobId = context.getMergedJobDataMap().get("id"); + String params = ObjectUtils.defaultIfNull(context.getMergedJobDataMap().get("params"), "{}") + ""; + + CronJobDto cronJobDto = cronJobService.getById(cronJobId + ""); + + ScriptExecResultDto resultDto = new ScriptExecResultDto(); + resultDto.setParams(objectMapper.readTree(params)); + resultDto.setId(cronJobDto.getScript().getId()); + Exception ex = null; + try { + + scriptService.exec(resultDto); + } catch (Exception e) { + log.warn("执行定时任务失败 {} {} {} {}",cronJobDto.getId(), cronJobDto.getName(), cronJobDto.getCron(), cronJobDto.getScript().getName(), e); + + ex = e; + } + + + LocalDateTime end = LocalDateTime.now(); + + + CronJobLogEntity jobLog = new CronJobLogEntity(); + CronJobEntity entity = new CronJobEntity(); + entity.setId(cronJobDto.getId()); + + jobLog.setCronJob(entity); + + jobLog.setParams(params); + jobLog.setStartTime(start); + jobLog.setExecStatus(ex !=null || resultDto.getStackTrace() != null ? "1" : "0"); + + jobLog.setEndTime(end); + jobLog.setStackTrace(ex == null ? resultDto.getStackTrace() : ExceptionUtils.getStackTrace(ex)); + jobLog.setLogs(String.join("\n", resultDto.getLogs()).substring(0, 1024)); + + cronJobLogService.save(jobLog); + } +} diff --git a/src/main/java/cn/lihongjie/coal/cronJobLog/controller/CronJobLogController.java b/src/main/java/cn/lihongjie/coal/cronJobLog/controller/CronJobLogController.java new file mode 100644 index 00000000..f0af9548 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJobLog/controller/CronJobLogController.java @@ -0,0 +1,60 @@ +package cn.lihongjie.coal.cronJobLog.controller; + +import cn.lihongjie.coal.annotation.SysLog; +import cn.lihongjie.coal.base.dto.CommonQuery; +import cn.lihongjie.coal.base.dto.IdRequest; +import cn.lihongjie.coal.cronJobLog.dto.CreateCronJobLogDto; +import cn.lihongjie.coal.cronJobLog.dto.CronJobLogDto; +import cn.lihongjie.coal.cronJobLog.dto.UpdateCronJobLogDto; +import cn.lihongjie.coal.cronJobLog.service.CronJobLogService; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/cronJobLog") +@SysLog( + module = "定时任务日志" +) +@Slf4j +public class CronJobLogController { + @Autowired + private CronJobLogService service; + + @PostMapping("/create") + public CronJobLogDto create(@RequestBody CreateCronJobLogDto request) { + return this.service.create(request) + ; + } + + @PostMapping("/update") + public CronJobLogDto update(@RequestBody UpdateCronJobLogDto request) { + return this.service.update(request) + ; + } + + @PostMapping("/delete") + public Object delete(@RequestBody IdRequest request) { + this.service.delete(request); + return true + ; + } + + @PostMapping("/getById") + public CronJobLogDto getById(@RequestBody IdRequest request) { + return this.service.getById(request.getId()) + ; + } + + @PostMapping("/list") + public Page list(@RequestBody CommonQuery request) { + return this.service.list(request) + ; + } +} diff --git a/src/main/java/cn/lihongjie/coal/cronJobLog/dto/CreateCronJobLogDto.java b/src/main/java/cn/lihongjie/coal/cronJobLog/dto/CreateCronJobLogDto.java new file mode 100644 index 00000000..834c20f8 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJobLog/dto/CreateCronJobLogDto.java @@ -0,0 +1,28 @@ +package cn.lihongjie.coal.cronJobLog.dto; + +import cn.lihongjie.coal.base.dto.CommonDto; + +import lombok.Data; + +import org.hibernate.annotations.Formula; + +import java.time.LocalDateTime; + +@Data +public class CreateCronJobLogDto extends CommonDto { + private String cronJob; + + private String params; + + + private String stackTrace; + + + private LocalDateTime startTime; + private LocalDateTime endTime; + + @Formula("(EXTRACT(EPOCH FROM (endTime - startTime)) * 1000)") + private long time; + + private String logs; +} diff --git a/src/main/java/cn/lihongjie/coal/cronJobLog/dto/CronJobLogDto.java b/src/main/java/cn/lihongjie/coal/cronJobLog/dto/CronJobLogDto.java new file mode 100644 index 00000000..0a217299 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJobLog/dto/CronJobLogDto.java @@ -0,0 +1,29 @@ +package cn.lihongjie.coal.cronJobLog.dto; + +import cn.lihongjie.coal.base.dto.CommonDto; +import cn.lihongjie.coal.cronJob.dto.CronJobDto; + +import lombok.Data; + +import org.hibernate.annotations.Formula; + +import java.time.LocalDateTime; + +@Data +public class CronJobLogDto extends CommonDto { + private CronJobDto cronJob; + + private String params; + + + private String stackTrace; + + + private LocalDateTime startTime; + private LocalDateTime endTime; + + @Formula("(EXTRACT(EPOCH FROM (endTime - startTime)) * 1000)") + private long time; + + private String logs; +} diff --git a/src/main/java/cn/lihongjie/coal/cronJobLog/dto/UpdateCronJobLogDto.java b/src/main/java/cn/lihongjie/coal/cronJobLog/dto/UpdateCronJobLogDto.java new file mode 100644 index 00000000..104dd5ff --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJobLog/dto/UpdateCronJobLogDto.java @@ -0,0 +1,28 @@ +package cn.lihongjie.coal.cronJobLog.dto; + +import cn.lihongjie.coal.base.dto.CommonDto; + +import lombok.Data; + +import org.hibernate.annotations.Formula; + +import java.time.LocalDateTime; + +@Data +public class UpdateCronJobLogDto extends CommonDto { + private String cronJob; + + private String params; + + + private String stackTrace; + + + private LocalDateTime startTime; + private LocalDateTime endTime; + + @Formula("(EXTRACT(EPOCH FROM (endTime - startTime)) * 1000)") + private long time; + + private String logs; +} diff --git a/src/main/java/cn/lihongjie/coal/cronJobLog/entity/CronJobLogEntity.java b/src/main/java/cn/lihongjie/coal/cronJobLog/entity/CronJobLogEntity.java new file mode 100644 index 00000000..067f33d3 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJobLog/entity/CronJobLogEntity.java @@ -0,0 +1,48 @@ +package cn.lihongjie.coal.cronJobLog.entity; + +import cn.lihongjie.coal.base.entity.CommonEntity; + +import jakarta.persistence.Entity; +import jakarta.persistence.ManyToOne; + +import lombok.Data; + +import org.hibernate.annotations.Comment; +import org.hibernate.annotations.Formula; + +import java.time.LocalDateTime; + +@Data +@Entity +public class CronJobLogEntity extends CommonEntity { + @ManyToOne + private cn.lihongjie.coal.cronJob.entity.CronJobEntity cronJob; + + private String params; + + + private String stackTrace; + + private LocalDateTime startTime; + private LocalDateTime endTime; + + @Formula("(EXTRACT(EPOCH FROM (endTime - startTime)) * 1000)") + private long time; + + private String logs; + + @Comment("执行状态") + private String execStatus; + + + @Formula( + "(select i.name\n" + + "from t_dictionary d,\n" + + " t_dictionary_item i\n" + + "where d.id = i.dictionary_id\n" + + " and d.code = 'cronJob.execStatus'\n" + + " and i.code = exec_status)") + private String execStatusName; + + +} diff --git a/src/main/java/cn/lihongjie/coal/cronJobLog/mapper/CronJobLogMapper.java b/src/main/java/cn/lihongjie/coal/cronJobLog/mapper/CronJobLogMapper.java new file mode 100644 index 00000000..e5f0f9fb --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJobLog/mapper/CronJobLogMapper.java @@ -0,0 +1,19 @@ +package cn.lihongjie.coal.cronJobLog.mapper; + +import cn.lihongjie.coal.base.mapper.BaseMapper; +import cn.lihongjie.coal.base.mapper.CommonMapper; +import cn.lihongjie.coal.cronJobLog.dto.CreateCronJobLogDto; +import cn.lihongjie.coal.cronJobLog.dto.CronJobLogDto; +import cn.lihongjie.coal.cronJobLog.dto.UpdateCronJobLogDto; +import cn.lihongjie.coal.cronJobLog.entity.CronJobLogEntity; + +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; + +@Mapper( + componentModel = org.mapstruct.MappingConstants.ComponentModel.SPRING, + uses = {CommonMapper.class}, + mappingControl = DeepClone.class +) +public interface CronJobLogMapper extends BaseMapper { +} diff --git a/src/main/java/cn/lihongjie/coal/cronJobLog/repository/CronJobLogRepository.java b/src/main/java/cn/lihongjie/coal/cronJobLog/repository/CronJobLogRepository.java new file mode 100644 index 00000000..1aa8c1c8 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJobLog/repository/CronJobLogRepository.java @@ -0,0 +1,10 @@ +package cn.lihongjie.coal.cronJobLog.repository; + +import cn.lihongjie.coal.base.dao.BaseRepository; +import cn.lihongjie.coal.cronJobLog.entity.CronJobLogEntity; + +import org.springframework.stereotype.Repository; + +@Repository +public interface CronJobLogRepository extends BaseRepository { +} diff --git a/src/main/java/cn/lihongjie/coal/cronJobLog/service/CronJobLogService.java b/src/main/java/cn/lihongjie/coal/cronJobLog/service/CronJobLogService.java new file mode 100644 index 00000000..8db02349 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/cronJobLog/service/CronJobLogService.java @@ -0,0 +1,75 @@ +package cn.lihongjie.coal.cronJobLog.service; + +import cn.lihongjie.coal.base.dto.CommonQuery; +import cn.lihongjie.coal.base.dto.IdRequest; +import cn.lihongjie.coal.base.service.BaseService; +import cn.lihongjie.coal.cronJobLog.dto.CreateCronJobLogDto; +import cn.lihongjie.coal.cronJobLog.dto.CronJobLogDto; +import cn.lihongjie.coal.cronJobLog.dto.UpdateCronJobLogDto; +import cn.lihongjie.coal.cronJobLog.entity.CronJobLogEntity; +import cn.lihongjie.coal.cronJobLog.mapper.CronJobLogMapper; +import cn.lihongjie.coal.cronJobLog.repository.CronJobLogRepository; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.convert.ConversionService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Slf4j +@Transactional +public class CronJobLogService extends BaseService { + @Autowired + private CronJobLogRepository repository; + + @Autowired + private CronJobLogMapper mapper; + + @Autowired + private ConversionService conversionService; + + public CronJobLogDto create(CreateCronJobLogDto request) { + CronJobLogEntity entity = mapper.toEntity(request); + + + this.repository.save(entity); + return getById(entity.getId()) + ; + } + + public CronJobLogDto update(UpdateCronJobLogDto request) { + CronJobLogEntity entity = this.repository.get(request.getId()); + this.mapper.updateEntity(entity, request); + + this.repository.save(entity); + + return getById(entity.getId()) + ; + } + + public void delete(IdRequest request) { + this.repository.deleteAllById(request.getIds()) + ; + } + + public CronJobLogDto getById(String id) { + CronJobLogEntity entity = repository.get(id); + + + return mapper.toDto(entity) + ; + } + + public Page list(CommonQuery query) { + Page page = repository.findAll(query.specification(conversionService), PageRequest.of(query.getPageNo(), query.getPageSize(), Sort.by(query.getOrders()))); + + + return page.map(this.mapper::toDto) + ; + } +} diff --git a/src/main/resources/config/dictionary.json b/src/main/resources/config/dictionary.json index 8f5addc4..49708207 100644 --- a/src/main/resources/config/dictionary.json +++ b/src/main/resources/config/dictionary.json @@ -1675,6 +1675,20 @@ } ] }, + { + "code": "cronJob.execStatus", + "name": "定时任务执行状态", + "item": [ + { + "code": "0", + "name": "成功" + }, + { + "code": "1", + "name": "失败" + } + ] + }, { "code": "permission.type", "name": "权限类型",