# Conflicts:
#	pom.xml
#	yudao-dependencies/pom.xml
#	yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
#	yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/statistics/vo/portrait/CrmStatisticsPortraitReqVO.java
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/statistics/CrmStatisticsPerformanceServiceImpl.java
#	yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java
#	yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java
#	yudao-module-report/yudao-module-report-biz/src/main/java/cn/iocoder/yudao/module/report/framework/jmreport/core/service/JmReportTokenServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
This commit is contained in:
YunaiV
2024-05-04 09:39:07 +08:00
74 changed files with 25495 additions and 29621 deletions

View File

@@ -0,0 +1,5 @@
### 请求 /infra/job/sync 接口 => 成功
POST {{baseUrl}}/infra/job/sync
Content-Type: application/json
tenant-id: {{adminTenentId}}
Authorization: Bearer {{token}}

View File

@@ -90,6 +90,14 @@ public class JobController {
return success(true);
}
@PostMapping("/sync")
@Operation(summary = "同步定时任务")
@PreAuthorize("@ss.hasPermission('infra:job:create')")
public CommonResult<Boolean> syncJob() throws SchedulerException {
jobService.syncJob();
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得定时任务")
@Parameter(name = "id", description = "编号", required = true, example = "1024")

View File

@@ -3,18 +3,22 @@ package cn.iocoder.yudao.module.infra.service.db;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.query.SQLQuery;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -45,20 +49,27 @@ public class DatabaseTableServiceImpl implements DatabaseTableService {
// 获得数据源配置
DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId);
Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId);
DbType dbType = JdbcUtils.getDbType(config.getUrl());
// 使用 MyBatis Plus Generator 解析表结构
DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder(config.getUrl(), config.getUsername(),
config.getPassword()).build();
StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder();
DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig.Builder(config.getUrl(), config.getUsername(),
config.getPassword());
if (Objects.equals(dbType, DbType.SQL_SERVER)) { // 特殊SQLServer jdbc 非标准,参见 https://github.com/baomidou/mybatis-plus/issues/5419
dataSourceConfigBuilder.databaseQueryClass(SQLQuery.class);
}
StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder().enableSkipView(); // 忽略视图,业务上一般用不到
if (StrUtil.isNotEmpty(name)) {
strategyConfig.addInclude(name);
} else {
// 移除工作流和定时任务前缀的表名 // TODO 未来做成可配置
// 移除工作流和定时任务前缀的表名
strategyConfig.addExclude("ACT_[\\S\\s]+|QRTZ_[\\S\\s]+|FLW_[\\S\\s]+");
// 移除 ORACLE 相关的系统表
strategyConfig.addExclude("IMPDP_[\\S\\s]+|ALL_[\\S\\s]+|HS_[\\S\\\\s]+");
strategyConfig.addExclude("[\\S\\s]+\\$[\\S\\s]+|[\\S\\s]+\\$"); // 表里不能有 $,一般有都是系统的表
}
GlobalConfig globalConfig = new GlobalConfig.Builder().dateType(DateType.TIME_PACK).build(); // 只使用 LocalDateTime 类型,不使用 LocalDate
ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, strategyConfig.build(),
ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfigBuilder.build(), strategyConfig.build(),
null, globalConfig, null);
// 按照名字排序
List<TableInfo> tables = builder.getTableInfoList();

View File

@@ -45,6 +45,13 @@ public interface JobService {
*/
void triggerJob(Long id) throws SchedulerException;
/**
* 同步定时任务
*
* 目的:自己存储的 Job 信息,强制同步到 Quartz 中
*/
void syncJob() throws SchedulerException;
/**
* 删除定时任务
*

View File

@@ -11,12 +11,15 @@ import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobSaveReqVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper;
import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.containsAny;
@@ -29,6 +32,7 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
*/
@Service
@Validated
@Slf4j
public class JobServiceImpl implements JobService {
@Resource
@@ -130,6 +134,26 @@ public class JobServiceImpl implements JobService {
schedulerManager.triggerJob(job.getId(), job.getHandlerName(), job.getHandlerParam());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void syncJob() throws SchedulerException {
// 1. 查询 Job 配置
List<JobDO> jobList = jobMapper.selectList();
// 2. 遍历处理
for (JobDO job : jobList) {
// 2.1 先删除,再创建
schedulerManager.deleteJob(job.getHandlerName());
schedulerManager.addJob(job.getId(), job.getHandlerName(), job.getHandlerParam(), job.getCronExpression(),
job.getRetryCount(), job.getRetryInterval());
// 2.2 如果 status 为暂停,则需要暂停
if (Objects.equals(job.getStatus(), JobStatusEnum.STOP.getStatus())) {
schedulerManager.pauseJob(job.getHandlerName());
}
log.info("[syncJob][id({}) handlerName({}) 同步完成]", job.getId(), job.getHandlerName());
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteJob(Long id) throws SchedulerException {