feat: 完善循环输出扁平聚合
- 校验并恢复循环输出的聚合策略 - 将最终类型并入参数值并优化同排开关交互
This commit is contained in:
@@ -241,7 +241,9 @@ public class WorkflowExecutionAuditConsumer implements MQConsumerHandler {
|
||||
"iterationCount"))
|
||||
.intValue(),
|
||||
String.valueOf(
|
||||
map.get("outputName")));
|
||||
map.get("outputName")),
|
||||
Boolean.TRUE.equals(
|
||||
map.get("flattenAggregation")));
|
||||
}
|
||||
Map<Object, Object> restored =
|
||||
new LinkedHashMap<>();
|
||||
|
||||
@@ -248,6 +248,7 @@ public class WorkflowCheckService {
|
||||
for (NodeView node : nodes) {
|
||||
checkConfiguredLoopCount(node, issues, issueKeys);
|
||||
checkExplicitLoopInputs(node, issues, issueKeys);
|
||||
checkLoopOutputAggregations(node, issues, issueKeys);
|
||||
if (StringUtils.hasText(node.parentId)) {
|
||||
NodeView parent = nodeMap.get(node.parentId);
|
||||
if (parent != null && !TYPE_LOOP.equals(parent.type)) {
|
||||
@@ -605,6 +606,51 @@ public class WorkflowCheckService {
|
||||
true, 0, "Array<", 0, "Array<".length()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验循环输出的扁平聚合只作用于数组引用。
|
||||
*
|
||||
* @param node 循环节点
|
||||
* @param issues 问题列表
|
||||
* @param issueKeys 问题去重键
|
||||
*/
|
||||
private void checkLoopOutputAggregations(
|
||||
NodeView node,
|
||||
List<WorkflowCheckIssue> issues,
|
||||
Set<String> issueKeys) {
|
||||
if (!TYPE_LOOP.equals(node.type) || node.data == null) {
|
||||
return;
|
||||
}
|
||||
JSONArray outputDefs = node.data.getJSONArray("outputDefs");
|
||||
if (outputDefs == null || outputDefs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < outputDefs.size(); index++) {
|
||||
JSONObject outputDef = outputDefs.getJSONObject(index);
|
||||
if (outputDef == null
|
||||
|| !outputDef.getBooleanValue("flattenAggregation")) {
|
||||
continue;
|
||||
}
|
||||
String refType = trimToNull(outputDef.getString("refType"));
|
||||
String ref = trimToNull(outputDef.getString("ref"));
|
||||
String dataType = trimToNull(outputDef.getString("dataType"));
|
||||
if ("ref".equals(refType)
|
||||
&& StringUtils.hasText(ref)
|
||||
&& isArrayDataType(dataType)) {
|
||||
continue;
|
||||
}
|
||||
String outputName = trimToNull(outputDef.getString("name"));
|
||||
addIssue(
|
||||
issues,
|
||||
issueKeys,
|
||||
"LOOP_OUTPUT_FLATTEN_TYPE_INVALID",
|
||||
"循环输出参数[" + safe(outputName)
|
||||
+ "]启用扁平聚合时必须引用数组变量",
|
||||
node.id,
|
||||
null,
|
||||
node.name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验 index 和 loopItem 仅在所属循环体内引用。
|
||||
*
|
||||
|
||||
@@ -627,11 +627,11 @@ public class WorkflowExecutionAuditConsumerTest {
|
||||
loopRepository.append(
|
||||
resultId,
|
||||
0,
|
||||
Map.of("answer", "first"));
|
||||
Map.of("answer", List.of("first", "second")));
|
||||
loopRepository.append(
|
||||
resultId,
|
||||
1,
|
||||
Map.of("answer", "second"));
|
||||
Map.of("answer", List.of("third")));
|
||||
WorkflowExecutionAuditConsumer consumer =
|
||||
new WorkflowExecutionAuditConsumer(
|
||||
resultService,
|
||||
@@ -650,7 +650,8 @@ public class WorkflowExecutionAuditConsumerTest {
|
||||
new LoopResultReference(
|
||||
resultId,
|
||||
2,
|
||||
"answer"));
|
||||
"answer",
|
||||
true));
|
||||
WorkflowExecStep incomingStep =
|
||||
new WorkflowExecStep();
|
||||
incomingStep.setExecKey("step-loop");
|
||||
@@ -700,10 +701,10 @@ public class WorkflowExecutionAuditConsumerTest {
|
||||
resultCaptor.getValue().getOutput(),
|
||||
Map.class);
|
||||
Assert.assertEquals(
|
||||
List.of("first", "second"),
|
||||
List.of("first", "second", "third"),
|
||||
stepOutput.get("answers"));
|
||||
Assert.assertEquals(
|
||||
List.of("first", "second"),
|
||||
List.of("first", "second", "third"),
|
||||
resultOutput.get("answers"));
|
||||
}
|
||||
|
||||
|
||||
@@ -221,6 +221,55 @@ public class WorkflowCheckServiceTest {
|
||||
assertHasCode(result, "EXPLICIT_LOOP_ITEMS_TYPE_INVALID");
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证循环数组输出允许启用扁平聚合。
|
||||
*/
|
||||
@Test
|
||||
public void testSaveShouldPassArrayLoopOutputFlattenAggregation() throws Exception {
|
||||
WorkflowCheckService service = newService(new HashMap<>());
|
||||
JSONObject loopData = loopData(
|
||||
fixedParameter("count", "2", "Number"), null);
|
||||
JSONObject output = refParameter(
|
||||
"res",
|
||||
"knowledge.documents.content",
|
||||
"Array<String>");
|
||||
output.put("flattenAggregation", true);
|
||||
loopData.put("outputDefs", array(output));
|
||||
String content = workflowJson(
|
||||
array(node("loop-1", "loopNode", null, loopData)),
|
||||
new JSONArray());
|
||||
|
||||
WorkflowCheckResult result = service.checkContent(
|
||||
content, WorkflowCheckStage.SAVE, null);
|
||||
|
||||
Assert.assertTrue(result.isPassed());
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证循环标量输出不能启用扁平聚合。
|
||||
*/
|
||||
@Test
|
||||
public void testSaveShouldBlockScalarLoopOutputFlattenAggregation() throws Exception {
|
||||
WorkflowCheckService service = newService(new HashMap<>());
|
||||
JSONObject loopData = loopData(
|
||||
fixedParameter("count", "2", "Number"), null);
|
||||
JSONObject output = refParameter(
|
||||
"res",
|
||||
"child.output",
|
||||
"String");
|
||||
output.put("flattenAggregation", true);
|
||||
loopData.put("outputDefs", array(output));
|
||||
String content = workflowJson(
|
||||
array(node("loop-1", "loopNode", null, loopData)),
|
||||
new JSONArray());
|
||||
|
||||
WorkflowCheckResult result = service.checkContent(
|
||||
content, WorkflowCheckStage.SAVE, null);
|
||||
|
||||
Assert.assertFalse(result.isPassed());
|
||||
assertHasCode(result, "LOOP_OUTPUT_FLATTEN_TYPE_INVALID");
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证新旧循环输入不能同时提交。
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user