feat: 完善循环输出扁平聚合

- 校验并恢复循环输出的聚合策略

- 将最终类型并入参数值并优化同排开关交互
This commit is contained in:
2026-07-31 14:45:26 +08:00
parent 0754ad0792
commit fb08424cef
14 changed files with 504 additions and 59 deletions

View File

@@ -7,6 +7,7 @@ import {
buildLoopReferenceParameters,
buildLoopScopeParameters,
isArrayDataType,
projectParameterDataType,
} from '../../utils/loopScope';
const fillRefNodeIds = (
@@ -25,9 +26,9 @@ const fillRefNodeIds = (
const getChildren = (
params: any,
parentId: string,
nodeIsChildren: boolean,
nodeType: string,
parentPathLabel = '',
ancestorCollectionDepth = 0,
parentIsCollection = false,
) => {
if (!params || params.length === 0) return [];
@@ -43,25 +44,29 @@ const getChildren = (
: parentIsCollection
? `${parentPathLabel}.[].${normalizedChildLabel}`
: `${parentPathLabel}.${normalizedChildLabel}`;
const dataType = nodeIsChildren
? `Array<${param.dataType || 'String'}>`
: param.dataType || 'String';
const dataType = projectParameterDataType(
param,
ancestorCollectionDepth,
);
const nextCollectionDepth =
ancestorCollectionDepth + (isCollection ? 1 : 0);
return {
label: pathLabel,
dataType: dataType,
dataType,
value: parentId + '.' + param.name,
selectable: true,
nodeType: nodeType,
displayLabel: pathLabel,
pathLabel,
itemTypeLabel: parentIsCollection ? '数组项字段' : undefined,
itemTypeLabel:
ancestorCollectionDepth > 0 ? '数组项字段' : undefined,
isCollection,
children: getChildren(
param.children,
parentId + '.' + param.name,
nodeIsChildren,
nodeType,
pathLabel,
nextCollectionDepth,
isCollection,
),
};
@@ -70,7 +75,6 @@ const getChildren = (
const nodeToOptions = (
node: Node,
nodeIsChildren: boolean,
currentNode: Node,
nodes: Node[],
) => {
@@ -94,13 +98,10 @@ const nodeToOptions = (
const children = [];
if (parameters)
for (const parameter of parameters) {
const dataType = nodeIsChildren
? `Array<${parameter.dataType || 'String'}>`
: parameter.dataType || 'String';
const label = getStartNodeParameterLabel(parameter);
children.push({
label,
dataType: dataType,
dataType: projectParameterDataType(parameter),
value: node.id + '.' + parameter.name,
selectable: true,
nodeType: nodeType,
@@ -132,7 +133,6 @@ const nodeToOptions = (
children: getChildren(
referenceParameters,
node.id,
false,
nodeType,
),
};
@@ -145,7 +145,7 @@ const nodeToOptions = (
value: node.id,
selectable: false,
nodeType: nodeType,
children: getChildren(outputDefs, node.id, nodeIsChildren, nodeType),
children: getChildren(outputDefs, node.id, nodeType),
};
}
}
@@ -153,6 +153,7 @@ const nodeToOptions = (
export const useRefOptions: any = (
useChildrenOnly: boolean | (() => boolean) = false,
currentRef: string | (() => string) = '',
) => {
const currentNodeId = getCurrentNodeId();
const currentNode = useNodesData(currentNodeId);
@@ -161,11 +162,16 @@ export const useRefOptions: any = (
typeof useChildrenOnly === 'function'
? useChildrenOnly()
: useChildrenOnly;
const getCurrentRef = () =>
typeof currentRef === 'function' ? currentRef() : currentRef;
let selectItems = $derived.by(() => {
const resultOptions = [];
if (!currentNode.current) {
return [];
return {
items: [],
selected: undefined,
};
}
//通过 nodeLookup.get 才会得到有 parentId 的 node
@@ -173,11 +179,9 @@ export const useRefOptions: any = (
if (isChildrenOnly()) {
for (const node of nodes) {
const nodeIsChildren = node.parentId === currentNode.current.id;
if (nodeIsChildren) {
if (node.parentId === currentNode.current.id) {
const nodeOptions = nodeToOptions(
node,
nodeIsChildren,
cNode,
nodes,
);
@@ -193,10 +197,8 @@ export const useRefOptions: any = (
node.type === 'loopNode' &&
buildLoopScopeParameters(node, cNode, nodes).length > 0;
if (refNodeIds.includes(node.id) || isScopedLoop) {
const nodeIsChildren = node.parentId === currentNode.current.id;
const nodeOptions = nodeToOptions(
node,
nodeIsChildren,
cNode,
nodes,
);
@@ -205,12 +207,30 @@ export const useRefOptions: any = (
}
}
return resultOptions;
const items = resultOptions;
const stack = [...items];
let selected;
const currentValue = getCurrentRef();
// 单次深度优先扫描定位当前引用,避免为每个参数额外构建全量索引。
while (stack.length > 0) {
const item = stack.pop();
if (item?.value === currentValue) {
selected = item;
break;
}
if (item?.children?.length) {
stack.push(...item.children);
}
}
return { items, selected };
});
return {
get current() {
return selectItems;
return selectItems.items;
},
get selected() {
return selectItems.selected;
},
};
};