CMVR-BID/src/utils/flow.js
2026-04-16 09:32:52 +08:00

370 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export const getInput = (nodeId, isStrict = true) => {
const data = lf.getGraphData();
// let flag = false
// if (isStrict) {
// data.edges.forEach(item => {
// if (item.targetNodeId === nodeId) {
// flag = true
// }
// });
// } else {
// flag = true
// }
// if (flag) {
const arr = []
const filterNodes = ['sleep', 'stopLoop', 'subEnd', 'subStart', 'branch', 'end']
data.nodes.forEach(item => {
if (item.id === nodeId) {
return
}
if (filterNodes.includes(item.type)) {
return
}
const obj = {
value: item.id,
label: item.properties.name,
children: [{
value: 'input',
label: '输入',
type: 'input',
children: []
}, {
value: 'output',
label: '输出',
type: 'output',
children: []
}]
}
if (item.properties.inputParams) {
transformTree(item.properties.inputParams, obj.children[0].children, 'input')
}
if (item.properties.nodeParams) {
transformTree(item.properties.nodeParams, obj.children[0].children, 'input')
}
if (item.properties.outputParams) {
transformTree(item.properties.outputParams, obj.children[1].children, 'output')
}
arr.push(obj)
})
return arr
// }
// return flag
}
const transformTree = (arr, parent = [], type) => {
arr.forEach(item => {
const currentNode = {
value: item.name,
label: item.name,
type,
children: []
};
parent.push(currentNode);
if (item.children?.length > 0) {
transformTree(item.children, currentNode.children, type);
} else {
delete currentNode.children
}
});
return parent;
};
export const getStartNodeFormData = () => {
const flowData = lf.getGraphData();
const startNode = flowData.nodes.find(item => item.type === 'start')
const data = addValueProperty(startNode.properties?.inputParams || [])
return data
}
export const addValueProperty = (data, schemeId = '') => {
// 处理单个对象或对象数组
const processItem = (item, index, path) => {
// 根据类型设置默认值
item.value = item.name === 'schemeId' ? schemeId : item.type.includes('array') ? '[0]' : item.type === 'number' ? 0 : item.type === 'boolean' ? false : '';
item.propPath = `${path}.${index}.`
// if (item.type.includes('array') && !item.type.includes('object')) {
// const type = item.type.match(/<([^>]+)>/)[1]
// item.children = [{ name: 'Array Item', type, value: '', propPath: item.propPath + '.0'}]
// }
// 递归处理子项
if (item.children && item.children.length > 0) {
item.children = item.children.map((cItem, cIndex) => {
return processItem(cItem, cIndex , item.propPath + 'children')
});
}
return item;
};
// 如果传入的是数组,处理每个元素;否则处理单个对象
return Array.isArray(data) ? data.map((item, index) => processItem(item, index, '')) : processItem(data, 0, '')
}
export const recursiveFilter = (data, id, type = ['loop', 'customGroup'], result = []) => {
data.forEach((item) => {
if (type.includes(item.type) && item.children && item.children.includes(id)) {
result.push(item)
recursiveFilter(data, item.id, type, result)
}
});
return result
}
export const formatTableData = (arr, data = {}) => {
arr.forEach(item => {
data[item.name] = item.value
if (item?.children && item.children.length > 0) {
data[item.name] = {}
formatTableData(item.children, data[item.name])
}
})
return data
}
export const addNewEdge = (nodeId) => {
const { edges } = lf.getGraphData();
const ttt = edges.slice(); // 浅拷贝(比 JSON 深拷贝高效 10x+)
const edgesToDelete = ttt.filter(_edge =>
_edge.sourceNodeId === nodeId || _edge.targetNodeId === nodeId
);
edgesToDelete.forEach(edge => lf.deleteEdge(edge.id));
if (window.addNewEdgeTimer) {
clearTimeout(window.addNewEdgeTimer); // 清理上一次未执行的定时器
}
window.addNewEdgeTimer = setTimeout(() => {
edgesToDelete.forEach(item => {
lf.addEdge({
type: "bezier",
sourceNodeId: item.sourceNodeId,
targetNodeId: item.targetNodeId,
sourceAnchorId: item.sourceAnchorId,
targetAnchorId: item.targetAnchorId
});
})
delete window.addNewEdgeTimer;
}, 50)
}
export const newEdge = (nodeId) => {
const { edges } = lf.getGraphData();
const arr = JSON.parse(JSON.stringify(edges))
arr.forEach(_edge => {
const { sourceNodeId, targetNodeId, sourceAnchorId, targetAnchorId } = _edge
if (sourceNodeId === nodeId || targetNodeId === nodeId) {
lf.deleteEdge(_edge.id);
lf.addEdge({
type: "bezier",
sourceNodeId: sourceNodeId,
targetNodeId: targetNodeId,
sourceAnchorId: sourceAnchorId,
targetAnchorId: targetAnchorId
});
}
})
}
export const initNodeZoom = (modelId, nodeZoom, className, init=false) => {
const nodes = document.getElementsByClassName(modelId)
if (nodes.length > 0) {
const node = nodes[0]
const parent = node.closest(className);
if (nodeZoom) {
parent.style.width = '680px'
} else {
parent.style.width = '380px'
}
if (!init) {
addNewEdge(modelId)
}
}
}
export const getInputNumber = (nodeId) => {
const data = lf.getGraphData();
let flag = false
data.edges.forEach(item => {
if (item.targetNodeId === nodeId) {
flag = true
}
});
if (flag) {
const arr = []
data.nodes.forEach(item => {
if (item.properties.inputParams) {
item.properties.inputParams.forEach(item => {
if (item.type === 'number') {
arr.push(item)
}
})
}
})
return arr
}
return flag
}
export const removeSwitchEdge = (nodeId, sourceAnchorId) => {
const { edges } = lf.getGraphData();
const edge = edges.find(item => {
return item.sourceNodeId === nodeId && item.sourceAnchorId === sourceAnchorId
})
if (edge) {
lf.deleteEdge(edge.id);
}
}
export const convertToTree = (data) => {
// 创建 id 到节点的映射
const nodeMap = new Map();
data.forEach(node => {
nodeMap.set(node.id, { ...node, name: node.properties.name || '' }); // 浅拷贝节点
});
// 标记非根节点(被其他节点引用的节点)
const nonRootIds = new Set();
data.forEach(node => {
if (node.children) {
node.children.forEach(childId => {
nonRootIds.add(childId);
});
}
});
// 构建树形结构
const result = [];
data.forEach(node => {
// 只处理根节点(未被引用的节点)
if (!nonRootIds.has(node.id)) {
const rootNode = nodeMap.get(node.id);
// 递归处理子节点
const processNode = (currentNode) => {
if (currentNode.children) {
currentNode.children = currentNode.children.map(childId => {
const childNode = nodeMap.get(childId);
processNode(childNode); // 递归处理子节点
return childNode;
});
}
return currentNode;
};
result.push(processNode(rootNode));
}
});
return result;
}
export const filterEmptyName = (obj) => {
// 1. 如果是数组,遍历每一项递归处理
if (Array.isArray(obj)) {
return obj
.map(item => filterEmptyName(item)) // 先递归处理子项
.filter(item => item !== null); // 过滤掉被剔除的空项
}
// 2. 如果是对象,先检查 name 是否为空,为空直接返回 null(剔除)
if (typeof obj === 'object' && obj !== null) {
// 核心:name 为空字符串 → 直接剔除这个对象
if (obj.name === '') {
return null;
}
// 创建新对象,保留原有属性
const newObj = { ...obj };
// 如果有 children,递归过滤子节点
if (newObj.children && Array.isArray(newObj.children)) {
newObj.children = filterEmptyName(newObj.children);
}
return newObj;
}
// 基础类型直接返回
return obj;
}
/**
* 将原始表单配置数组 转换为 目标对象格式
* @param {Array} source - 原始数据数组
* @returns {Object} 转换后的目标格式对象
*/
export const transformHttpNodeData = (source) => {
// 初始化结果对象
const result = {};
// 遍历每一个顶级节点
source.forEach(item => {
const { name, children } = item;
if (!name) return; // 过滤无name的无效节点
// 处理普通节点(config/headers/params):直接取 children 数组
if (name !== 'body') {
result[name] = children || [];
return;
}
// 专门处理 body 节点(特殊结构)
if (name === 'body') {
const bodyObj = {
type: '',
json: '',
formData: []
};
// 遍历body的子项,赋值到对应字段
children?.forEach(child => {
const childName = child.name;
if (childName === 'bodyType') {
bodyObj.type = child.input;
}
if (childName === 'json') {
bodyObj.json = child.input;
}
if (childName === 'formData') {
bodyObj.formData = child.children || [];
}
});
result.body = bodyObj;
}
});
return result;
}
export const transformSdAgentNodeData = (source) => {
// 初始化结果对象
const result = {};
// 遍历每一个顶级节点
source.forEach(item => {
const { name, children } = item;
if (!name) return; // 过滤无name的无效节点
// 处理普通节点(config/headers/params):直接取 children 数组
if (name !== 'invokeTts') {
result[name] = children || [];
return;
}
// 专门处理 tts 节点(特殊结构)
if (name === 'invokeTts') {
result.invokeTts = item.input;
}
});
return result;
}