fix: 防止定时任务引用失效工作流
- 保存任务时校验工作流权限与必填参数 - 删除工作流前检查并重新确认定时任务引用
This commit is contained in:
@@ -2,18 +2,29 @@ package tech.easyflow.admin.controller.job;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.easyagents.flow.core.chain.Parameter;
|
||||
import org.quartz.CronExpression;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import tech.easyflow.ai.easyagentsflow.service.WorkflowRunningParameterResolver;
|
||||
import tech.easyflow.ai.entity.Workflow;
|
||||
import tech.easyflow.ai.service.WorkflowService;
|
||||
import tech.easyflow.common.constant.enums.EnumJobType;
|
||||
import tech.easyflow.common.domain.Result;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.satoken.util.SaTokenUtil;
|
||||
import tech.easyflow.common.web.controller.BaseCurdController;
|
||||
import tech.easyflow.common.web.exceptions.BusinessException;
|
||||
import tech.easyflow.job.entity.SysJob;
|
||||
import tech.easyflow.job.job.JobConstant;
|
||||
import tech.easyflow.job.service.SysJobService;
|
||||
import tech.easyflow.job.support.SysJobWorkflowReferenceSupport;
|
||||
import tech.easyflow.log.annotation.LogRecord;
|
||||
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.system.enums.CategoryResourceType;
|
||||
import tech.easyflow.system.enums.ResourceAction;
|
||||
import tech.easyflow.system.service.ResourceAccessService;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
@@ -21,6 +32,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 系统任务表 控制层。
|
||||
@@ -31,8 +43,32 @@ import java.util.List;
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/sysJob")
|
||||
public class SysJobController extends BaseCurdController<SysJobService, SysJob> {
|
||||
public SysJobController(SysJobService service) {
|
||||
|
||||
/** 工作流服务。 */
|
||||
private final WorkflowService workflowService;
|
||||
|
||||
/** 资源访问控制服务。 */
|
||||
private final ResourceAccessService resourceAccessService;
|
||||
|
||||
/** 工作流运行参数解析器。 */
|
||||
private final WorkflowRunningParameterResolver workflowRunningParameterResolver;
|
||||
|
||||
/**
|
||||
* 创建定时任务控制器。
|
||||
*
|
||||
* @param service 定时任务服务
|
||||
* @param workflowService 工作流服务
|
||||
* @param resourceAccessService 资源访问控制服务
|
||||
* @param workflowRunningParameterResolver 工作流运行参数解析器
|
||||
*/
|
||||
public SysJobController(SysJobService service,
|
||||
WorkflowService workflowService,
|
||||
ResourceAccessService resourceAccessService,
|
||||
WorkflowRunningParameterResolver workflowRunningParameterResolver) {
|
||||
super(service);
|
||||
this.workflowService = workflowService;
|
||||
this.resourceAccessService = resourceAccessService;
|
||||
this.workflowRunningParameterResolver = workflowRunningParameterResolver;
|
||||
}
|
||||
|
||||
@GetMapping("/start")
|
||||
@@ -73,9 +109,94 @@ public class SysJobController extends BaseCurdController<SysJobService, SysJob>
|
||||
entity.setModified(new Date());
|
||||
entity.setModifiedBy(loginUser.getId());
|
||||
}
|
||||
validateWorkflowReference(entity);
|
||||
return super.onSaveOrUpdateBefore(entity, isSave);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验工作流类型任务引用的工作流可被当前用户运行。
|
||||
*
|
||||
* @param entity 待保存的定时任务
|
||||
* @throws BusinessException 工作流不存在、参数非法或无运行权限时抛出
|
||||
*/
|
||||
private void validateWorkflowReference(SysJob entity) {
|
||||
if (entity == null
|
||||
|| !Integer.valueOf(EnumJobType.TINY_FLOW.getCode()).equals(entity.getJobType())) {
|
||||
return;
|
||||
}
|
||||
BigInteger workflowId = SysJobWorkflowReferenceSupport.requireWorkflowId(entity);
|
||||
Workflow workflow = workflowService.getById(workflowId);
|
||||
if (workflow == null) {
|
||||
throw new BusinessException("工作流不存在,请重新选择");
|
||||
}
|
||||
resourceAccessService.assertAccess(
|
||||
CategoryResourceType.WORKFLOW,
|
||||
workflow,
|
||||
ResourceAction.USE,
|
||||
"无权限运行所选工作流"
|
||||
);
|
||||
validateRequiredWorkflowParams(entity, workflow);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验定时任务已填写工作流的全部必填运行参数。
|
||||
*
|
||||
* @param entity 待保存定时任务
|
||||
* @param workflow 关联工作流
|
||||
* @throws BusinessException 工作流参数配置无效或必填值缺失时抛出
|
||||
*/
|
||||
private void validateRequiredWorkflowParams(SysJob entity, Workflow workflow) {
|
||||
List<Parameter> parameters =
|
||||
workflowRunningParameterResolver.resolveStartParameters(workflow.getContent());
|
||||
if (parameters == null) {
|
||||
throw new BusinessException("工作流参数配置无效,请检查工作流后重试");
|
||||
}
|
||||
Map<String, Object> jobParams = entity.getJobParams();
|
||||
Object rawWorkflowParams = jobParams == null
|
||||
? null
|
||||
: jobParams.get(JobConstant.WORKFLOW_PARAMS_KEY);
|
||||
Map<?, ?> workflowParams = rawWorkflowParams instanceof Map<?, ?> map
|
||||
? map
|
||||
: Map.of();
|
||||
for (Parameter parameter : parameters) {
|
||||
if (parameter == null || !parameter.isRequired()) {
|
||||
continue;
|
||||
}
|
||||
String name = parameter.getName();
|
||||
if (!StringUtils.hasText(name)) {
|
||||
throw new BusinessException("工作流存在无效必填参数配置,请检查工作流后重试");
|
||||
}
|
||||
if (!hasRequiredValue(workflowParams.get(name))) {
|
||||
String label = StringUtils.hasText(parameter.getFormLabel())
|
||||
? parameter.getFormLabel()
|
||||
: name;
|
||||
throw new BusinessException("工作流必填参数“" + label + "”不能为空");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断必填参数值是否有效。
|
||||
*
|
||||
* @param value 参数值
|
||||
* @return 非空时为 true
|
||||
*/
|
||||
private boolean hasRequiredValue(Object value) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
if (value instanceof CharSequence sequence) {
|
||||
return StringUtils.hasText(sequence);
|
||||
}
|
||||
if (value instanceof Collection<?> collection) {
|
||||
return !collection.isEmpty();
|
||||
}
|
||||
if (value instanceof Map<?, ?> map) {
|
||||
return !map.isEmpty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result onRemoveBefore(Collection<Serializable> ids) {
|
||||
service.deleteJob(ids);
|
||||
|
||||
Reference in New Issue
Block a user