feat: 增加工作流合法性校验功能

This commit is contained in:
2026-03-04 19:56:42 +08:00
parent a79718b03b
commit ae9bb2c53f
12 changed files with 1755 additions and 38 deletions

View File

@@ -4,21 +4,25 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.easyagents.flow.core.chain.*;
import com.easyagents.flow.core.chain.ChainDefinition;
import com.easyagents.flow.core.chain.Parameter;
import com.easyagents.flow.core.chain.runtime.ChainExecutor;
import com.easyagents.flow.core.parser.ChainParser;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tech.easyflow.ai.entity.Workflow;
import tech.easyflow.ai.easyagentsflow.entity.ChainInfo;
import tech.easyflow.ai.easyagentsflow.entity.NodeInfo;
import tech.easyflow.ai.easyagentsflow.entity.WorkflowCheckResult;
import tech.easyflow.ai.easyagentsflow.entity.WorkflowCheckStage;
import tech.easyflow.ai.easyagentsflow.service.CodeEngineCapabilityService;
import tech.easyflow.ai.easyagentsflow.service.TinyFlowService;
import tech.easyflow.ai.easyagentsflow.service.WorkflowCheckService;
import tech.easyflow.ai.entity.Workflow;
import tech.easyflow.ai.service.BotWorkflowService;
import tech.easyflow.ai.service.ModelService;
import tech.easyflow.ai.service.WorkflowService;
import tech.easyflow.ai.easyagentsflow.entity.ChainInfo;
import tech.easyflow.ai.easyagentsflow.entity.NodeInfo;
import tech.easyflow.ai.easyagentsflow.service.TinyFlowService;
import tech.easyflow.common.constant.Constants;
import tech.easyflow.common.domain.Result;
import tech.easyflow.common.entity.LoginAccount;
@@ -33,7 +37,10 @@ import java.io.InputStream;
import java.io.Serializable;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 控制层。
@@ -58,6 +65,8 @@ public class WorkflowController extends BaseCurdController<WorkflowService, Work
private TinyFlowService tinyFlowService;
@Resource
private CodeEngineCapabilityService codeEngineCapabilityService;
@Resource
private WorkflowCheckService workflowCheckService;
public WorkflowController(WorkflowService service, ModelService modelService) {
super(service);
@@ -96,6 +105,7 @@ public class WorkflowController extends BaseCurdController<WorkflowService, Work
if (workflow == null) {
throw new RuntimeException("工作流不存在");
}
workflowCheckService.checkOrThrow(workflow.getContent(), WorkflowCheckStage.PRE_EXECUTE, workflow.getId());
if (StpUtil.isLogin()) {
variables.put(Constants.LOGIN_USER_KEY, SaTokenUtil.getLoginAccount());
}
@@ -130,6 +140,7 @@ public class WorkflowController extends BaseCurdController<WorkflowService, Work
InputStream is = jsonFile.getInputStream();
String content = IoUtil.read(is, StandardCharsets.UTF_8);
workflow.setContent(content);
workflowCheckService.checkOrThrow(content, WorkflowCheckStage.SAVE, workflow.getId());
save(workflow);
return Result.ok();
}
@@ -149,6 +160,7 @@ public class WorkflowController extends BaseCurdController<WorkflowService, Work
if (workflow == null) {
return Result.fail(1, "can not find the workflow by id: " + id);
}
workflowCheckService.checkOrThrow(workflow.getContent(), WorkflowCheckStage.PRE_EXECUTE, workflow.getId());
ChainDefinition definition = chainParser.parse(workflow.getContent());
if (definition == null) {
@@ -169,6 +181,23 @@ public class WorkflowController extends BaseCurdController<WorkflowService, Work
return Result.ok(codeEngineCapabilityService.listSupportedCodeEngines());
}
@PostMapping("/check")
@SaCheckPermission("/api/v1/workflow/save")
public Result<WorkflowCheckResult> check(@JsonBody("id") BigInteger id,
@JsonBody("content") String content,
@JsonBody(value = "stage", required = true) String stage) {
WorkflowCheckStage checkStage = WorkflowCheckStage.from(stage);
WorkflowCheckResult checkResult;
if (StringUtils.hasLength(content)) {
checkResult = workflowCheckService.checkContent(content, checkStage, id);
} else if (id != null) {
checkResult = workflowCheckService.checkWorkflow(id, checkStage);
} else {
throw new BusinessException("id 与 content 不能同时为空");
}
return Result.ok(checkResult);
}
@Override
public Result<Workflow> detail(String id) {
Workflow workflow = service.getDetail(id);
@@ -189,6 +218,9 @@ public class WorkflowController extends BaseCurdController<WorkflowService, Work
@Override
protected Result onSaveOrUpdateBefore(Workflow entity, boolean isSave) {
if (StringUtils.hasLength(entity.getContent())) {
workflowCheckService.checkOrThrow(entity.getContent(), WorkflowCheckStage.SAVE, entity.getId());
}
String alias = entity.getAlias();
if (StringUtils.hasLength(alias)) {

View File

@@ -8,11 +8,13 @@ import com.easyagents.flow.core.parser.ChainParser;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotBlank;
import org.springframework.web.bind.annotation.*;
import tech.easyflow.ai.entity.Workflow;
import tech.easyflow.ai.service.WorkflowService;
import tech.easyflow.ai.easyagentsflow.entity.ChainInfo;
import tech.easyflow.ai.easyagentsflow.entity.NodeInfo;
import tech.easyflow.ai.easyagentsflow.entity.WorkflowCheckStage;
import tech.easyflow.ai.easyagentsflow.service.TinyFlowService;
import tech.easyflow.ai.easyagentsflow.service.WorkflowCheckService;
import tech.easyflow.ai.entity.Workflow;
import tech.easyflow.ai.service.WorkflowService;
import tech.easyflow.common.domain.Result;
import tech.easyflow.common.web.jsonbody.JsonBody;
@@ -36,6 +38,8 @@ public class PublicWorkflowController {
private ChainParser chainParser;
@Resource
private TinyFlowService tinyFlowService;
@Resource
private WorkflowCheckService workflowCheckService;
/**
* 通过id或别名获取工作流详情
@@ -83,6 +87,7 @@ public class PublicWorkflowController {
if (workflow == null) {
throw new RuntimeException("工作流不存在");
}
workflowCheckService.checkOrThrow(workflow.getContent(), WorkflowCheckStage.PRE_EXECUTE, workflow.getId());
String executeId = chainExecutor.executeAsync(id.toString(), variables);
return Result.ok(executeId);
}
@@ -116,6 +121,7 @@ public class PublicWorkflowController {
if (workflow == null) {
return Result.fail(1, "can not find the workflow by id: " + id);
}
workflowCheckService.checkOrThrow(workflow.getContent(), WorkflowCheckStage.PRE_EXECUTE, workflow.getId());
ChainDefinition definition = chainParser.parse(workflow.getContent());
if (definition == null) {

View File

@@ -2,15 +2,18 @@ package tech.easyflow.usercenter.controller.ai;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.easyagents.flow.core.chain.*;
import com.easyagents.flow.core.chain.ChainDefinition;
import com.easyagents.flow.core.chain.Parameter;
import com.easyagents.flow.core.chain.runtime.ChainExecutor;
import com.easyagents.flow.core.parser.ChainParser;
import org.springframework.web.bind.annotation.*;
import tech.easyflow.ai.entity.Workflow;
import tech.easyflow.ai.service.WorkflowService;
import tech.easyflow.ai.easyagentsflow.entity.ChainInfo;
import tech.easyflow.ai.easyagentsflow.entity.NodeInfo;
import tech.easyflow.ai.easyagentsflow.entity.WorkflowCheckStage;
import tech.easyflow.ai.easyagentsflow.service.TinyFlowService;
import tech.easyflow.ai.easyagentsflow.service.WorkflowCheckService;
import tech.easyflow.ai.entity.Workflow;
import tech.easyflow.ai.service.WorkflowService;
import tech.easyflow.common.annotation.UsePermission;
import tech.easyflow.common.constant.Constants;
import tech.easyflow.common.domain.Result;
@@ -21,7 +24,10 @@ import tech.easyflow.common.web.jsonbody.JsonBody;
import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 工作流
@@ -37,6 +43,8 @@ public class UcWorkflowController extends BaseCurdController<WorkflowService, Wo
private ChainParser chainParser;
@Resource
private TinyFlowService tinyFlowService;
@Resource
private WorkflowCheckService workflowCheckService;
public UcWorkflowController(WorkflowService service) {
super(service);
@@ -74,6 +82,7 @@ public class UcWorkflowController extends BaseCurdController<WorkflowService, Wo
if (workflow == null) {
throw new RuntimeException("工作流不存在");
}
workflowCheckService.checkOrThrow(workflow.getContent(), WorkflowCheckStage.PRE_EXECUTE, workflow.getId());
if (StpUtil.isLogin()) {
variables.put(Constants.LOGIN_USER_KEY, SaTokenUtil.getLoginAccount());
}
@@ -113,6 +122,7 @@ public class UcWorkflowController extends BaseCurdController<WorkflowService, Wo
if (workflow == null) {
return Result.fail(1, "can not find the workflow by id: " + id);
}
workflowCheckService.checkOrThrow(workflow.getContent(), WorkflowCheckStage.PRE_EXECUTE, workflow.getId());
ChainDefinition definition = chainParser.parse(workflow.getContent());
if (definition == null) {