From 5f318c2942506b99d9badafdd2cf8c0532299f72 Mon Sep 17 00:00:00 2001 From: odboy Date: Wed, 4 Dec 2024 01:22:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=98=89=E5=89=B2quartz=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E4=BB=BB=E5=8A=A1=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - kenaito-system/pom.xml | 6 - .../modules/quartz/context/JobRunner.java | 34 ---- .../modules/quartz/context/QuartzConfig.java | 35 ---- .../modules/quartz/domain/QuartzJob.java | 91 --------- .../modules/quartz/domain/QuartzLog.java | 53 ----- .../quartz/mapper/QuartzJobMapper.java | 24 --- .../quartz/mapper/QuartzLogMapper.java | 20 -- .../quartz/rest/QuartzJobController.java | 132 ------------- .../quartz/service/QuartzJobService.java | 114 ----------- .../service/impl/QuartzJobServiceImpl.java | 184 ------------------ .../odboy/modules/quartz/task/TestTask.java | 28 --- .../modules/quartz/util/ExecutionJob.java | 123 ------------ .../modules/quartz/util/QuartzManage.java | 162 --------------- .../modules/quartz/util/QuartzRunnable.java | 43 ---- .../mapper/{system => }/DeptMapper.xml | 0 .../mapper/{system => }/DictDetailMapper.xml | 0 .../mapper/{system => }/DictMapper.xml | 0 .../mapper/{system => }/JobMapper.xml | 0 .../mapper/{system => }/MenuMapper.xml | 0 .../mapper/{system => }/RoleDeptMapper.xml | 0 .../mapper/{system => }/RoleMapper.xml | 0 .../mapper/{system => }/RoleMenuMapper.xml | 0 .../mapper/{system => }/UserJobMapper.xml | 0 .../mapper/{system => }/UserMapper.xml | 0 .../mapper/{system => }/UserRoleMapper.xml | 0 .../mapper/quartz/QuartzJobMapper.xml | 32 --- .../mapper/quartz/QuartzLogMapper.xml | 20 -- .../resources/template/TaskAlarmTemplate.ftl | 69 ------- 29 files changed, 1171 deletions(-) delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/context/JobRunner.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/context/QuartzConfig.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/domain/QuartzJob.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/domain/QuartzLog.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/mapper/QuartzJobMapper.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/mapper/QuartzLogMapper.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/rest/QuartzJobController.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/service/QuartzJobService.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/service/impl/QuartzJobServiceImpl.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/task/TestTask.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/util/ExecutionJob.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/util/QuartzManage.java delete mode 100644 kenaito-system/src/main/java/cn/odboy/modules/quartz/util/QuartzRunnable.java rename kenaito-system/src/main/resources/mapper/{system => }/DeptMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/DictDetailMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/DictMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/JobMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/MenuMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/RoleDeptMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/RoleMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/RoleMenuMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/UserJobMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/UserMapper.xml (100%) rename kenaito-system/src/main/resources/mapper/{system => }/UserRoleMapper.xml (100%) delete mode 100644 kenaito-system/src/main/resources/mapper/quartz/QuartzJobMapper.xml delete mode 100644 kenaito-system/src/main/resources/mapper/quartz/QuartzLogMapper.xml delete mode 100644 kenaito-system/src/main/resources/template/TaskAlarmTemplate.ftl diff --git a/README.md b/README.md index 9a2553e..fa1f2f6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ - 岗位管理:配置各个部门的职位 - 字典管理:可维护常用一些固定的数据,如:状态,性别等 - SQL监控:采用druid 监控数据库访问性能,默认用户名admin,密码123456 -- 定时任务:整合Quartz做定时任务,加入任务日志,任务运行情况一目了然 - 邮件工具:配合富文本,发送html格式的邮件 - 服务监控:监控服务器的负载情况 diff --git a/kenaito-system/pom.xml b/kenaito-system/pom.xml index 20529e1..994bfe6 100644 --- a/kenaito-system/pom.xml +++ b/kenaito-system/pom.xml @@ -49,12 +49,6 @@ ${jjwt.version} - - - org.quartz-scheduler - quartz - - ch.ethz.ganymed diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/context/JobRunner.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/context/JobRunner.java deleted file mode 100644 index 501f8ff..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/context/JobRunner.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.odboy.modules.quartz.context; - -import cn.odboy.modules.quartz.domain.QuartzJob; -import cn.odboy.modules.quartz.mapper.QuartzJobMapper; -import cn.odboy.modules.quartz.util.QuartzManage; -import lombok.RequiredArgsConstructor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.ApplicationArguments; -import org.springframework.boot.ApplicationRunner; -import org.springframework.stereotype.Component; - -import java.util.List; - - -@Component -@RequiredArgsConstructor -public class JobRunner implements ApplicationRunner { - private static final Logger log = LoggerFactory.getLogger(JobRunner.class); - private final QuartzJobMapper quartzJobMapper; - private final QuartzManage quartzManage; - - /** - * 项目启动时重新激活启用的定时任务 - * - * @param applicationArguments / - */ - @Override - public void run(ApplicationArguments applicationArguments) { - List quartzJobs = quartzJobMapper.findByIsPauseIsFalse(); - quartzJobs.forEach(quartzManage::addJob); - log.info("Timing task injection complete"); - } -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/context/QuartzConfig.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/context/QuartzConfig.java deleted file mode 100644 index 42d0782..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/context/QuartzConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.odboy.modules.quartz.context; - -import org.quartz.spi.TriggerFiredBundle; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.quartz.AdaptableJobFactory; -import org.springframework.stereotype.Component; - -/** - * 定时任务配置 - */ -@Configuration -public class QuartzConfig { - - /** - * 解决Job中注入Spring Bean为null的问题 - */ - @Component("quartzJobFactory") - public static class QuartzJobFactory extends AdaptableJobFactory { - - private final AutowireCapableBeanFactory capableBeanFactory; - - public QuartzJobFactory(AutowireCapableBeanFactory capableBeanFactory) { - this.capableBeanFactory = capableBeanFactory; - } - - @Override - protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { - //调用父类的方法,把Job注入到spring中 - Object jobInstance = super.createJobInstance(bundle); - capableBeanFactory.autowireBean(jobInstance); - return jobInstance; - } - } -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/domain/QuartzJob.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/domain/QuartzJob.java deleted file mode 100644 index abcef21..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/domain/QuartzJob.java +++ /dev/null @@ -1,91 +0,0 @@ -package cn.odboy.modules.quartz.domain; - -import cn.odboy.base.MyEntity; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.Getter; -import lombok.Setter; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import java.sql.Timestamp; -import java.util.List; - -@Getter -@Setter -@TableName("system_quartz_job") -public class QuartzJob extends MyEntity { - public static final String JOB_KEY = "QUARTZ_JOB_KEY"; - - @TableId(value = "id", type = IdType.AUTO) - @NotNull(groups = {Update.class}) - private Long id; - /** - * 所属模块 - */ - private String moduleName; - /** - * 用于子任务唯一标识 - */ - @TableField(exist = false) - private String uuid; - /** - * 定时器名称 - */ - private String jobName; - /** - * Bean名称 - */ - @NotBlank - private String beanName; - /** - * 方法名称 - */ - @NotBlank - private String methodName; - /** - * 参数 - */ - private String params; - /** - * cron表达式 - */ - @NotBlank - private String cronExpression; - /** - * 状态,暂时或启动 - */ - private Boolean isPause = false; - /** - * 负责人 - */ - private String personInCharge; - /** - * 报警邮箱 - */ - private String email; - /** - * 子任务 - */ - private String subTask; - /** - * 失败后暂停 - */ - private Boolean pauseAfterFailure; - /** - * 备注 - */ - @NotBlank - private String description; - - @Data - public static class QueryArgs { - private String jobName; - private String moduleName; - private Boolean isSuccess; - private List createTime; - } -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/domain/QuartzLog.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/domain/QuartzLog.java deleted file mode 100644 index 0393c2c..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/domain/QuartzLog.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.odboy.modules.quartz.domain; - -import cn.odboy.base.MyObject; -import com.baomidou.mybatisplus.annotation.*; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.sql.Timestamp; - -@Data -@EqualsAndHashCode(callSuper = false) -@TableName("system_quartz_log") -public class QuartzLog extends MyObject { - @TableId(value = "id", type = IdType.AUTO) - private Long id; - /** - * 任务名称 - */ - private String jobName; - /** - * bean名称 - */ - private String beanName; - /** - * 方法名称 - */ - private String methodName; - /** - * 参数 - */ - private String params; - /** - * cron表达式 - */ - private String cronExpression; - /** - * 状态 - */ - private Boolean isSuccess; - /** - * 异常详情 - */ - private String exceptionDetail; - /** - * 执行耗时 - */ - private Long time; - /** - * 创建时间 - */ - @TableField(fill = FieldFill.INSERT) - private Timestamp createTime; -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/mapper/QuartzJobMapper.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/mapper/QuartzJobMapper.java deleted file mode 100644 index 6776ee7..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/mapper/QuartzJobMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.odboy.modules.quartz.mapper; - -import cn.odboy.base.model.SelectOption; -import cn.odboy.modules.quartz.domain.QuartzJob; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -import java.util.List; - - -@Mapper -public interface QuartzJobMapper extends BaseMapper { - - IPage findAll(@Param("criteria") QuartzJob.QueryArgs criteria, Page page); - - List findAll(@Param("criteria") QuartzJob.QueryArgs criteria); - - List findByIsPauseIsFalse(); - - List findQuartzJobModuleOptions(); -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/mapper/QuartzLogMapper.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/mapper/QuartzLogMapper.java deleted file mode 100644 index 476b4a0..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/mapper/QuartzLogMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.odboy.modules.quartz.mapper; - -import cn.odboy.modules.quartz.domain.QuartzJob; -import cn.odboy.modules.quartz.domain.QuartzLog; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -import java.util.List; - - -@Mapper -public interface QuartzLogMapper extends BaseMapper { - - IPage findAll(@Param("criteria") QuartzJob.QueryArgs criteria, Page page); - - List findAll(@Param("criteria") QuartzJob.QueryArgs criteria); -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/rest/QuartzJobController.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/rest/QuartzJobController.java deleted file mode 100644 index 6216768..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/rest/QuartzJobController.java +++ /dev/null @@ -1,132 +0,0 @@ -package cn.odboy.modules.quartz.rest; - -import cn.odboy.infra.context.SpringContextHolder; -import cn.odboy.infra.exception.BadRequestException; -import cn.odboy.modules.quartz.domain.QuartzJob; -import cn.odboy.modules.quartz.service.QuartzJobService; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Set; - -/** - * 系统:定时任务管理 - * @author odboy - * @date 2024-12-03 - */ -@Slf4j -@RestController -@RequiredArgsConstructor -@RequestMapping("/api/jobs") -public class QuartzJobController { - private final QuartzJobService quartzJobService; - - /** - * 查询定时任务 - */ - @GetMapping - @PreAuthorize("@el.check('timing:list')") - public ResponseEntity queryQuartzJob(QuartzJob.QueryArgs criteria, Page page) { - return new ResponseEntity<>(quartzJobService.queryAll(criteria, page), HttpStatus.OK); - } - /** - * 导出任务数据 - */ - @GetMapping(value = "/download") - @PreAuthorize("@el.check('timing:list')") - public void exportQuartzJob(HttpServletResponse response, QuartzJob.QueryArgs criteria) throws IOException { - quartzJobService.download(quartzJobService.queryAll(criteria), response); - } - /** - * 导出日志数据 - */ - @GetMapping(value = "/logs/download") - @PreAuthorize("@el.check('timing:list')") - public void exportQuartzJobLog(HttpServletResponse response, QuartzJob.QueryArgs criteria) throws IOException { - quartzJobService.downloadLog(quartzJobService.queryAllLog(criteria), response); - } - /** - * 查询任务执行日志 - */ - @GetMapping(value = "/logs") - @PreAuthorize("@el.check('timing:list')") - public ResponseEntity queryQuartzJobLog(QuartzJob.QueryArgs criteria, Page page) { - return new ResponseEntity<>(quartzJobService.queryAllLog(criteria, page), HttpStatus.OK); - } - /** - * 查询任务模块类型 - */ - @GetMapping(value = "/modules") - @PreAuthorize("@el.check('timing:list')") - public ResponseEntity queryQuartzJobModules() { - return new ResponseEntity<>(quartzJobService.queryQuartzJobModules(), HttpStatus.OK); - } - /** - * 新增定时任务 - */ - @PostMapping - @PreAuthorize("@el.check('timing:add')") - public ResponseEntity createQuartzJob(@Validated @RequestBody QuartzJob resources) { - if (resources.getId() != null) { - throw new BadRequestException("A new " + QuartzJob.class.getSimpleName() + " cannot already have an ID"); - } - // 验证Bean是不是合法的,合法的定时任务 Bean 需要用 @Service 定义 - checkBean(resources.getBeanName()); - quartzJobService.create(resources); - return new ResponseEntity<>(HttpStatus.CREATED); - } - /** - * 修改定时任务 - */ - @PutMapping - @PreAuthorize("@el.check('timing:edit')") - public ResponseEntity updateQuartzJob(@Validated(QuartzJob.Update.class) @RequestBody QuartzJob resources) { - // 验证Bean是不是合法的,合法的定时任务 Bean 需要用 @Service 定义 - checkBean(resources.getBeanName()); - quartzJobService.update(resources); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - /** - * 更改定时任务状态 - */ - @PutMapping(value = "/{id}") - @PreAuthorize("@el.check('timing:edit')") - public ResponseEntity updateQuartzJobStatus(@PathVariable Long id) { - quartzJobService.updateIsPause(quartzJobService.getById(id)); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - /** - * 执行定时任务 - */ - @PutMapping(value = "/exec/{id}") - @PreAuthorize("@el.check('timing:edit')") - public ResponseEntity executionQuartzJob(@PathVariable Long id) { - quartzJobService.execution(quartzJobService.getById(id)); - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - /** - * 删除定时任务 - */ - @DeleteMapping - @PreAuthorize("@el.check('timing:del')") - public ResponseEntity deleteQuartzJob(@RequestBody Set ids) { - quartzJobService.delete(ids); - return new ResponseEntity<>(HttpStatus.OK); - } - - private void checkBean(String beanName) { - // 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类 - // 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。 - if (!SpringContextHolder.getAllServiceBeanName().contains(beanName)) { - throw new BadRequestException("非法的 Bean,请重新输入!"); - } - } -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/service/QuartzJobService.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/service/QuartzJobService.java deleted file mode 100644 index 0be97a6..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/service/QuartzJobService.java +++ /dev/null @@ -1,114 +0,0 @@ -package cn.odboy.modules.quartz.service; - -import cn.odboy.base.model.SelectOption; -import cn.odboy.infra.response.PageResult; -import cn.odboy.modules.quartz.domain.QuartzJob; -import cn.odboy.modules.quartz.domain.QuartzLog; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.extension.service.IService; - -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.List; -import java.util.Set; - - -public interface QuartzJobService extends IService { - - /** - * 分页查询 - * - * @param criteria 条件 - * @param page 分页参数 - * @return / - */ - PageResult queryAll(QuartzJob.QueryArgs criteria, Page page); - - /** - * 查询全部 - * - * @param criteria 条件 - * @return / - */ - List queryAll(QuartzJob.QueryArgs criteria); - - /** - * 分页查询日志 - * - * @param criteria 条件 - * @param page 分页参数 - * @return / - */ - PageResult queryAllLog(QuartzJob.QueryArgs criteria, Page page); - - /** - * 查询全部 - * - * @param criteria 条件 - * @return / - */ - List queryAllLog(QuartzJob.QueryArgs criteria); - - /** - * 创建 - * - * @param resources / - */ - void create(QuartzJob resources); - - /** - * 编辑 - * - * @param resources / - */ - void update(QuartzJob resources); - - /** - * 删除任务 - * - * @param ids / - */ - void delete(Set ids); - - /** - * 更改定时任务状态 - * - * @param quartzJob / - */ - void updateIsPause(QuartzJob quartzJob); - - /** - * 立即执行定时任务 - * - * @param quartzJob / - */ - void execution(QuartzJob quartzJob); - - /** - * 导出定时任务 - * - * @param queryAll 待导出的数据 - * @param response / - * @throws IOException / - */ - void download(List queryAll, HttpServletResponse response) throws IOException; - - /** - * 导出定时任务日志 - * - * @param queryAllLog 待导出的数据 - * @param response / - * @throws IOException / - */ - void downloadLog(List queryAllLog, HttpServletResponse response) throws IOException; - - /** - * 执行子任务 - * - * @param tasks / - * @throws InterruptedException / - */ - void executionSubJob(String[] tasks) throws InterruptedException; - - List queryQuartzJobModules(); -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/service/impl/QuartzJobServiceImpl.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/service/impl/QuartzJobServiceImpl.java deleted file mode 100644 index fd4cc65..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/service/impl/QuartzJobServiceImpl.java +++ /dev/null @@ -1,184 +0,0 @@ -package cn.odboy.modules.quartz.service.impl; - -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.StrUtil; -import cn.odboy.base.model.SelectOption; -import cn.odboy.infra.exception.BadRequestException; -import cn.odboy.infra.redis.RedisUtil; -import cn.odboy.infra.response.PageResult; -import cn.odboy.infra.response.PageUtil; -import cn.odboy.modules.quartz.domain.QuartzJob; -import cn.odboy.modules.quartz.domain.QuartzLog; -import cn.odboy.modules.quartz.mapper.QuartzJobMapper; -import cn.odboy.modules.quartz.mapper.QuartzLogMapper; -import cn.odboy.modules.quartz.service.QuartzJobService; -import cn.odboy.modules.quartz.util.QuartzManage; -import cn.odboy.util.MyFileUtil; -import cn.odboy.util.StringUtil; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import lombok.RequiredArgsConstructor; -import org.quartz.CronExpression; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.*; - - -@RequiredArgsConstructor -@Service(value = "quartzJobService") -public class QuartzJobServiceImpl extends ServiceImpl implements QuartzJobService { - - private final QuartzJobMapper quartzJobMapper; - private final QuartzLogMapper quartzLogMapper; - private final QuartzManage quartzManage; - private final RedisUtil redisUtil; - - @Override - public PageResult queryAll(QuartzJob.QueryArgs criteria, Page page) { - return PageUtil.toPage(quartzJobMapper.findAll(criteria, page)); - } - - @Override - public PageResult queryAllLog(QuartzJob.QueryArgs criteria, Page page) { - return PageUtil.toPage(quartzLogMapper.findAll(criteria, page)); - } - - @Override - public List queryAll(QuartzJob.QueryArgs criteria) { - return quartzJobMapper.findAll(criteria); - } - - @Override - public List queryAllLog(QuartzJob.QueryArgs criteria) { - return quartzLogMapper.findAll(criteria); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void create(QuartzJob resources) { - if (!CronExpression.isValidExpression(resources.getCronExpression())) { - throw new BadRequestException("cron表达式格式错误"); - } - save(resources); - quartzManage.addJob(resources); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void update(QuartzJob resources) { - if (!CronExpression.isValidExpression(resources.getCronExpression())) { - throw new BadRequestException("cron表达式格式错误"); - } - if (StringUtil.isNotBlank(resources.getSubTask())) { - List tasks = Arrays.asList(resources.getSubTask().split("[,,]")); - if (tasks.contains(resources.getId().toString())) { - throw new BadRequestException("子任务中不能添加当前任务ID"); - } - } - saveOrUpdate(resources); - quartzManage.updateJobCron(resources); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateIsPause(QuartzJob quartzJob) { - if (quartzJob.getIsPause()) { - quartzManage.resumeJob(quartzJob); - quartzJob.setIsPause(false); - } else { - quartzManage.pauseJob(quartzJob); - quartzJob.setIsPause(true); - } - saveOrUpdate(quartzJob); - } - - @Override - public void execution(QuartzJob quartzJob) { - quartzManage.runJobNow(quartzJob); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void delete(Set ids) { - for (Long id : ids) { - QuartzJob quartzJob = getById(id); - quartzManage.deleteJob(quartzJob); - removeById(quartzJob); - } - } - - @Async - @Override - @Transactional(rollbackFor = Exception.class) - public void executionSubJob(String[] tasks) throws InterruptedException { - for (String id : tasks) { - if (StrUtil.isBlank(id)) { - // 如果是手动清除子任务id,会出现id为空字符串的问题 - continue; - } - QuartzJob quartzJob = getById(Long.parseLong(id)); - // 执行任务 - String uuid = IdUtil.simpleUUID(); - quartzJob.setUuid(uuid); - // 执行任务 - execution(quartzJob); - // 获取执行状态,如果执行失败则停止后面的子任务执行 - Boolean result = (Boolean) redisUtil.get(uuid); - while (result == null) { - // 休眠5秒,再次获取子任务执行情况 - Thread.sleep(5000); - result = (Boolean) redisUtil.get(uuid); - } - if (!result) { - redisUtil.del(uuid); - break; - } - } - } - - @Override - public List queryQuartzJobModules() { - return baseMapper.findQuartzJobModuleOptions(); - } - - @Override - public void download(List quartzJobs, HttpServletResponse response) throws IOException { - List> list = new ArrayList<>(); - for (QuartzJob quartzJob : quartzJobs) { - Map map = new LinkedHashMap<>(); - map.put("任务名称", quartzJob.getJobName()); - map.put("Bean名称", quartzJob.getBeanName()); - map.put("执行方法", quartzJob.getMethodName()); - map.put("参数", quartzJob.getParams()); - map.put("表达式", quartzJob.getCronExpression()); - map.put("状态", quartzJob.getIsPause() ? "暂停中" : "运行中"); - map.put("描述", quartzJob.getDescription()); - map.put("创建日期", quartzJob.getCreateTime()); - list.add(map); - } - MyFileUtil.downloadExcel(list, response); - } - - @Override - public void downloadLog(List queryAllLog, HttpServletResponse response) throws IOException { - List> list = new ArrayList<>(); - for (QuartzLog quartzLog : queryAllLog) { - Map map = new LinkedHashMap<>(); - map.put("任务名称", quartzLog.getJobName()); - map.put("Bean名称", quartzLog.getBeanName()); - map.put("执行方法", quartzLog.getMethodName()); - map.put("参数", quartzLog.getParams()); - map.put("表达式", quartzLog.getCronExpression()); - map.put("异常详情", quartzLog.getExceptionDetail()); - map.put("耗时/毫秒", quartzLog.getTime()); - map.put("状态", quartzLog.getIsSuccess() ? "成功" : "失败"); - map.put("创建日期", quartzLog.getCreateTime()); - list.add(map); - } - MyFileUtil.downloadExcel(list, response); - } -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/task/TestTask.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/task/TestTask.java deleted file mode 100644 index a53be46..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/task/TestTask.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.odboy.modules.quartz.task; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -/** - * 测试用 - */ -@Slf4j -@Service -public class TestTask { - - public void run() { - log.info("run 执行成功"); - } - - public void run1(String str) { - log.info("run1 执行成功,参数为: {}", str); - } - - public void run2() { - log.info("run2 执行成功"); - } - - public void run3() { - log.info("run3 执行成功"); - } -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/ExecutionJob.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/ExecutionJob.java deleted file mode 100644 index 20f71c8..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/ExecutionJob.java +++ /dev/null @@ -1,123 +0,0 @@ -package cn.odboy.modules.quartz.util; - -import cn.hutool.extra.template.Template; -import cn.hutool.extra.template.TemplateConfig; -import cn.hutool.extra.template.TemplateEngine; -import cn.hutool.extra.template.TemplateUtil; -import cn.odboy.constant.EmailTypeEnum; -import cn.odboy.domain.EmailLog; -import cn.odboy.infra.context.SpringContextHolder; -import cn.odboy.infra.redis.RedisUtil; -import cn.odboy.modules.quartz.domain.QuartzJob; -import cn.odboy.modules.quartz.domain.QuartzLog; -import cn.odboy.modules.quartz.mapper.QuartzLogMapper; -import cn.odboy.modules.quartz.service.QuartzJobService; -import cn.odboy.service.EmailService; -import cn.odboy.util.StringUtil; -import cn.odboy.util.ThrowableUtil; -import org.quartz.JobExecutionContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.scheduling.quartz.QuartzJobBean; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Future; - -/** - * 参考人人开源,... - */ -@Async -public class ExecutionJob extends QuartzJobBean { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - /** - * 此处仅供参考,可根据任务执行情况自定义线程池参数 - */ - private final ThreadPoolTaskExecutor executor = SpringContextHolder.getBean("elAsync"); - - @Override - public void executeInternal(JobExecutionContext context) { - // 获取任务 - QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY); - // 获取spring bean - QuartzLogMapper quartzLogMapper = SpringContextHolder.getBean(QuartzLogMapper.class); - QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class); - RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class); - - String uuid = quartzJob.getUuid(); - - QuartzLog log = new QuartzLog(); - log.setJobName(quartzJob.getJobName()); - log.setBeanName(quartzJob.getBeanName()); - log.setMethodName(quartzJob.getMethodName()); - log.setParams(quartzJob.getParams()); - long startTime = System.currentTimeMillis(); - log.setCronExpression(quartzJob.getCronExpression()); - try { - // 执行任务 - QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(), quartzJob.getParams()); - Future future = executor.submit(task); - future.get(); - long times = System.currentTimeMillis() - startTime; - log.setTime(times); - if (StringUtil.isNotBlank(uuid)) { - redisUtil.set(uuid, true); - } - // 任务状态 - log.setIsSuccess(true); - logger.info("任务执行成功,任务名称:" + quartzJob.getJobName() + ", 执行时间:" + times + "毫秒"); - // 判断是否存在子任务 - if (StringUtil.isNotBlank(quartzJob.getSubTask())) { - String[] tasks = quartzJob.getSubTask().split("[,,]"); - // 执行子任务 - quartzJobService.executionSubJob(tasks); - } - } catch (Exception e) { - if (StringUtil.isNotBlank(uuid)) { - redisUtil.set(uuid, false); - } - logger.error("任务执行失败,任务名称:" + quartzJob.getJobName()); - long times = System.currentTimeMillis() - startTime; - log.setTime(times); - // 任务状态 0:成功 1:失败 - log.setIsSuccess(false); - log.setExceptionDetail(ThrowableUtil.getStackTrace(e)); - // 任务如果失败了则暂停 - if (quartzJob.getPauseAfterFailure() != null && quartzJob.getPauseAfterFailure()) { - quartzJob.setIsPause(false); - //更新状态 - quartzJobService.updateIsPause(quartzJob); - } - if (quartzJob.getEmail() != null) { - EmailService emailService = SpringContextHolder.getBean(EmailService.class); - // 邮箱报警 - if (StringUtil.isNoneBlank(quartzJob.getEmail())) { - EmailLog.SendContent emailVo = renderTaskAlarm(quartzJob, ThrowableUtil.getStackTrace(e)); - emailService.send(EmailTypeEnum.TASK_ALARM, emailVo); - } - } - } finally { - quartzLogMapper.insert(log); - } - } - - private EmailLog.SendContent renderTaskAlarm(QuartzJob quartzJob, String msg) { - EmailLog.SendContent emailVo = new EmailLog.SendContent(); - emailVo.setSubject("定时任务【" + quartzJob.getJobName() + "】执行失败,请尽快处理!"); - Map data = new HashMap<>(16); - data.put("task", quartzJob); - data.put("msg", msg); - TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH)); - Template template = engine.getTemplate("TaskAlarmTemplate.ftl"); - emailVo.setContent(template.render(data)); - List emails = Arrays.asList(quartzJob.getEmail().split("[,,]")); - emailVo.setTos(emails); - return emailVo; - } -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/QuartzManage.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/QuartzManage.java deleted file mode 100644 index 01dbacf..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/QuartzManage.java +++ /dev/null @@ -1,162 +0,0 @@ -package cn.odboy.modules.quartz.util; - -import cn.odboy.infra.exception.BadRequestException; -import cn.odboy.modules.quartz.domain.QuartzJob; -import lombok.extern.slf4j.Slf4j; -import org.quartz.*; -import org.quartz.impl.triggers.CronTriggerImpl; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; -import java.util.Date; - -import static org.quartz.TriggerBuilder.newTrigger; - - -@Slf4j -@Component -public class QuartzManage { - - private static final String JOB_NAME = "TASK_"; - - @Resource - private Scheduler scheduler; - - public void addJob(QuartzJob quartzJob) { - try { - // 构建job信息 - JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class). - withIdentity(JOB_NAME + quartzJob.getId()).build(); - - //通过触发器名和cron 表达式创建 Trigger - Trigger cronTrigger = newTrigger() - .withIdentity(JOB_NAME + quartzJob.getId()) - .startNow() - .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression())) - .build(); - - cronTrigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob); - - //重置启动时间 - ((CronTriggerImpl) cronTrigger).setStartTime(new Date()); - - //执行定时任务 - scheduler.scheduleJob(jobDetail, cronTrigger); - - // 暂停任务 - if (quartzJob.getIsPause()) { - pauseJob(quartzJob); - } - } catch (Exception e) { - log.error("创建定时任务失败", e); - throw new BadRequestException("创建定时任务失败"); - } - } - - /** - * 更新job cron表达式 - * - * @param quartzJob / - */ - public void updateJobCron(QuartzJob quartzJob) { - try { - TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); - CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); - // 如果不存在则创建一个定时任务 - if (trigger == null) { - addJob(quartzJob); - trigger = (CronTrigger) scheduler.getTrigger(triggerKey); - } - CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()); - trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); - //重置启动时间 - ((CronTriggerImpl) trigger).setStartTime(new Date()); - trigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob); - - scheduler.rescheduleJob(triggerKey, trigger); - // 暂停任务 - if (quartzJob.getIsPause()) { - pauseJob(quartzJob); - } - } catch (Exception e) { - log.error("更新定时任务失败", e); - throw new BadRequestException("更新定时任务失败"); - } - - } - - /** - * 删除一个job - * - * @param quartzJob / - */ - public void deleteJob(QuartzJob quartzJob) { - try { - JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); - scheduler.pauseJob(jobKey); - scheduler.deleteJob(jobKey); - } catch (Exception e) { - log.error("删除定时任务失败", e); - throw new BadRequestException("删除定时任务失败"); - } - } - - /** - * 恢复一个job - * - * @param quartzJob / - */ - public void resumeJob(QuartzJob quartzJob) { - try { - TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); - CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); - // 如果不存在则创建一个定时任务 - if (trigger == null) { - addJob(quartzJob); - } - JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); - scheduler.resumeJob(jobKey); - } catch (Exception e) { - log.error("恢复定时任务失败", e); - throw new BadRequestException("恢复定时任务失败"); - } - } - - /** - * 立即执行job - * - * @param quartzJob / - */ - public void runJobNow(QuartzJob quartzJob) { - try { - TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); - CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); - // 如果不存在则创建一个定时任务 - if (trigger == null) { - addJob(quartzJob); - } - JobDataMap dataMap = new JobDataMap(); - dataMap.put(QuartzJob.JOB_KEY, quartzJob); - JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); - scheduler.triggerJob(jobKey, dataMap); - } catch (Exception e) { - log.error("定时任务执行失败", e); - throw new BadRequestException("定时任务执行失败"); - } - } - - /** - * 暂停一个job - * - * @param quartzJob / - */ - public void pauseJob(QuartzJob quartzJob) { - try { - JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); - scheduler.pauseJob(jobKey); - } catch (Exception e) { - log.error("定时任务暂停失败", e); - throw new BadRequestException("定时任务暂停失败"); - } - } -} diff --git a/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/QuartzRunnable.java b/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/QuartzRunnable.java deleted file mode 100644 index 0415105..0000000 --- a/kenaito-system/src/main/java/cn/odboy/modules/quartz/util/QuartzRunnable.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.odboy.modules.quartz.util; - -import cn.odboy.infra.context.SpringContextHolder; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.util.ReflectionUtils; - -import java.lang.reflect.Method; -import java.util.concurrent.Callable; - -/** - * 执行定时任务 - */ -@Slf4j -public class QuartzRunnable implements Callable { - - private final Object target; - private final Method method; - private final String params; - - QuartzRunnable(String beanName, String methodName, String params) - throws NoSuchMethodException, SecurityException { - this.target = SpringContextHolder.getBean(beanName); - this.params = params; - if (StringUtils.isNotBlank(params)) { - this.method = target.getClass().getDeclaredMethod(methodName, String.class); - } else { - this.method = target.getClass().getDeclaredMethod(methodName); - } - } - - @Override - @SuppressWarnings("all") - public Object call() throws Exception { - ReflectionUtils.makeAccessible(method); - if (StringUtils.isNotBlank(params)) { - method.invoke(target, params); - } else { - method.invoke(target); - } - return null; - } -} diff --git a/kenaito-system/src/main/resources/mapper/system/DeptMapper.xml b/kenaito-system/src/main/resources/mapper/DeptMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/DeptMapper.xml rename to kenaito-system/src/main/resources/mapper/DeptMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/DictDetailMapper.xml b/kenaito-system/src/main/resources/mapper/DictDetailMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/DictDetailMapper.xml rename to kenaito-system/src/main/resources/mapper/DictDetailMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/DictMapper.xml b/kenaito-system/src/main/resources/mapper/DictMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/DictMapper.xml rename to kenaito-system/src/main/resources/mapper/DictMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/JobMapper.xml b/kenaito-system/src/main/resources/mapper/JobMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/JobMapper.xml rename to kenaito-system/src/main/resources/mapper/JobMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/MenuMapper.xml b/kenaito-system/src/main/resources/mapper/MenuMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/MenuMapper.xml rename to kenaito-system/src/main/resources/mapper/MenuMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/RoleDeptMapper.xml b/kenaito-system/src/main/resources/mapper/RoleDeptMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/RoleDeptMapper.xml rename to kenaito-system/src/main/resources/mapper/RoleDeptMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/RoleMapper.xml b/kenaito-system/src/main/resources/mapper/RoleMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/RoleMapper.xml rename to kenaito-system/src/main/resources/mapper/RoleMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/RoleMenuMapper.xml b/kenaito-system/src/main/resources/mapper/RoleMenuMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/RoleMenuMapper.xml rename to kenaito-system/src/main/resources/mapper/RoleMenuMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/UserJobMapper.xml b/kenaito-system/src/main/resources/mapper/UserJobMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/UserJobMapper.xml rename to kenaito-system/src/main/resources/mapper/UserJobMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/UserMapper.xml b/kenaito-system/src/main/resources/mapper/UserMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/UserMapper.xml rename to kenaito-system/src/main/resources/mapper/UserMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/system/UserRoleMapper.xml b/kenaito-system/src/main/resources/mapper/UserRoleMapper.xml similarity index 100% rename from kenaito-system/src/main/resources/mapper/system/UserRoleMapper.xml rename to kenaito-system/src/main/resources/mapper/UserRoleMapper.xml diff --git a/kenaito-system/src/main/resources/mapper/quartz/QuartzJobMapper.xml b/kenaito-system/src/main/resources/mapper/quartz/QuartzJobMapper.xml deleted file mode 100644 index 4bc4843..0000000 --- a/kenaito-system/src/main/resources/mapper/quartz/QuartzJobMapper.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - diff --git a/kenaito-system/src/main/resources/mapper/quartz/QuartzLogMapper.xml b/kenaito-system/src/main/resources/mapper/quartz/QuartzLogMapper.xml deleted file mode 100644 index 75d0371..0000000 --- a/kenaito-system/src/main/resources/mapper/quartz/QuartzLogMapper.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - diff --git a/kenaito-system/src/main/resources/template/TaskAlarmTemplate.ftl b/kenaito-system/src/main/resources/template/TaskAlarmTemplate.ftl deleted file mode 100644 index 5c559c3..0000000 --- a/kenaito-system/src/main/resources/template/TaskAlarmTemplate.ftl +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - -
-
-

任务信息:

- - - - - - - - - - - - - - - - - -
任务名称Bean名称执行方法参数内容Cron表达式描述内容
${task.jobName}${task.beanName}${task.methodName}${(task.params)!""}${task.cronExpression}${(task.description)!""}
-
-
-

异常信息:

-
-                ${msg}
-            
-
-
-
-
- Copyright ©${.now?string("yyyy")} Kenaito快速开发框架 All Rights Reserved. -
- -
- - -