优化流程实例启动后,需要情况原本的节点输出文件夹,避免历史结果污染最新流程计算

This commit is contained in:
2025-12-05 15:15:37 +08:00
parent cfd084c14e
commit 8c61f1929a
2 changed files with 19 additions and 11 deletions

View File

@@ -14,6 +14,7 @@ import com.sdm.flowable.service.IAsyncTaskRecordService;
import com.sdm.flowable.service.IProcessNodeParamService;
import com.sdm.flowable.util.FlowNodeIdUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
@@ -75,7 +76,7 @@ public class UniversalDelegate implements JavaDelegate {
throw new RuntimeException("当前节点未查询到输入文件夹");
}
String objectKey = fileBaseInfoResp.getData().getObjectKey();
createLocalDir(objectKey);
prepareLocalDir(objectKey);
// 检查是否有扩展元素配置
if (execution.getCurrentFlowElement().getExtensionElements() != null &&
@@ -115,24 +116,31 @@ public class UniversalDelegate implements JavaDelegate {
}
/**
* 基于objectkey创建本地文件夹
* @param objectKey minio的文件对象路径
* 准备本地目录:如果目录已存在,则清空其内容;否则创建新目录。
* 流程实例启动后,需要在本地准备一个目录,用于存储节点计算结果。
* 如果同一个流程二次启动,每个节点会使用同一个文件夹,二次启动的时候,
* 如果清空,上一次流程实例运行结果相关文件也会在这个文件夹中,影响这次运行流程的结果文件
*
* @param objectKey MinIO 的对象路径,将作为本地目录路径的一部分
*/
private void createLocalDir(String objectKey) {
private void prepareLocalDir(String objectKey) {
String simulationBaseDir = FlowableConfig.FLOWABLE_SIMULATION_BASEDIR;
// 构建本地基础路径(直接使用 simulationBaseDir + objectKey
Path localBaseDir = Paths.get(simulationBaseDir).toAbsolutePath().normalize();
Path fullLocalBase = localBaseDir.resolve(objectKey).normalize();
Path fullLocalPath = localBaseDir.resolve(objectKey).normalize();
// 安全校验:确保 fullLocalBase 确实在 basePath 下
if (!fullLocalBase.startsWith(localBaseDir)) {
// 安全校验:防止路径穿越
if (!fullLocalPath.startsWith(localBaseDir)) {
throw new RuntimeException("非法文件夹路径,可能包含路径穿越: " + objectKey);
}
try {
Files.createDirectories(fullLocalBase);
if (Files.exists(fullLocalPath)) {
//直接删除整个目录
FileUtils.deleteDirectory(fullLocalPath.toFile());
}
Files.createDirectories(fullLocalPath);
} catch (Exception e) {
throw new RuntimeException("无法创建本地目录: " + fullLocalBase, e);
throw new RuntimeException("无法准备本地目录: " + fullLocalPath, e);
}
}

View File

@@ -46,7 +46,7 @@ public class ProcessNodeParamServiceImpl extends ServiceImpl<ProcessNodeParamMap
throw new RuntimeException("参数序列化失败", e);
}
// 存在则更新,不存在则插入
ProcessNodeParam existing = this.lambdaQuery().eq(ProcessNodeParam::getProcessDefinitionId, processDefinitionId).eq(ProcessNodeParam::getNodeId, nodeId).one();
ProcessNodeParam existing = this.lambdaQuery().eq(ProcessNodeParam::getRunId, runId).eq(ProcessNodeParam::getProcessDefinitionId, processDefinitionId).eq(ProcessNodeParam::getNodeId, nodeId).one();
if (existing != null) {
param.setId(existing.getId());
this.updateById(param);