|
|
@@ -184,111 +184,157 @@ export function workflowToBlueprint(workflow) {
|
|
|
return { nodes, connections };
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 分析流程节点中的变量引用,确定每个变量是作为输入还是输出使用
|
|
|
+ * @param {Array} processNodes - 流程节点数组
|
|
|
+ * @returns {Map} 变量引用映射 Map<varName, {asInput: boolean, asOutput: boolean}>
|
|
|
+ */
|
|
|
+export function analyzeVariableReferences(processNodes) {
|
|
|
+ const varReferences = new Map();
|
|
|
+
|
|
|
+ // 辅助函数:提取变量名
|
|
|
+ const extractVarName = (value) => {
|
|
|
+ if (typeof value === 'string') {
|
|
|
+ // 去掉引号和大括号
|
|
|
+ const cleaned = value.replace(/^["']|["']$/g, '').replace(/^{|}$/g, '');
|
|
|
+ return cleaned || null;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 遍历所有流程节点
|
|
|
+ processNodes.forEach(processNode => {
|
|
|
+ if (processNode.type === 'begin' || !processNode.data) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分析输入变量引用(inVars)
|
|
|
+ if (processNode.data.inVars && Array.isArray(processNode.data.inVars)) {
|
|
|
+ processNode.data.inVars.forEach(value => {
|
|
|
+ const varName = extractVarName(value);
|
|
|
+ if (varName) {
|
|
|
+ if (!varReferences.has(varName)) {
|
|
|
+ varReferences.set(varName, { asInput: false, asOutput: false });
|
|
|
+ }
|
|
|
+ varReferences.get(varName).asInput = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分析输出变量引用(outVars)
|
|
|
+ if (processNode.data.outVars && Array.isArray(processNode.data.outVars)) {
|
|
|
+ processNode.data.outVars.forEach(value => {
|
|
|
+ const varName = extractVarName(value);
|
|
|
+ if (varName) {
|
|
|
+ if (!varReferences.has(varName)) {
|
|
|
+ varReferences.set(varName, { asInput: false, asOutput: false });
|
|
|
+ }
|
|
|
+ varReferences.get(varName).asOutput = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return varReferences;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* 根据 inVars 和 outVars 中的变量引用创建变量节点与流程节点的连接
|
|
|
* @param {Array} processNodes - 流程节点数组
|
|
|
- * @param {Array} variableNodes - 变量节点数组
|
|
|
+ * @param {Array} variableNodes - 变量节点数组(包含 Get 和 Set 节点)
|
|
|
* @param {Object} workflow - 工作流对象(包含 variables)
|
|
|
* @returns {Array} 连接数组
|
|
|
*/
|
|
|
export function createVariableConnections(processNodes, variableNodes, workflow) {
|
|
|
const connections = [];
|
|
|
- const variableNodeMap = new Map();
|
|
|
|
|
|
- // 创建变量节点映射(变量名 -> 变量节点)
|
|
|
+ // 创建变量节点映射(按变量名和模式分类)
|
|
|
+ // getNodes: Map<varName, varNode> - Get 节点(用于输入)
|
|
|
+ // setNodes: Map<varName, varNode> - Set 节点(用于输出)
|
|
|
+ const getNodes = new Map();
|
|
|
+ const setNodes = new Map();
|
|
|
+
|
|
|
variableNodes.forEach(varNode => {
|
|
|
const varName = varNode.varName || varNode.label;
|
|
|
- if (varName) {
|
|
|
- variableNodeMap.set(varName, varNode);
|
|
|
+ if (!varName) return;
|
|
|
+
|
|
|
+ if (varNode.varMode === 'set') {
|
|
|
+ setNodes.set(varName, varNode);
|
|
|
+ } else {
|
|
|
+ // 默认为 get 模式
|
|
|
+ getNodes.set(varName, varNode);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ // 辅助函数:提取变量名
|
|
|
+ const extractVarName = (value) => {
|
|
|
+ if (typeof value === 'string') {
|
|
|
+ const cleaned = value.replace(/^["']|["']$/g, '').replace(/^{|}$/g, '');
|
|
|
+ return cleaned || null;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ };
|
|
|
+
|
|
|
// 遍历所有流程节点
|
|
|
processNodes.forEach(processNode => {
|
|
|
if (processNode.type === 'begin' || !processNode.data) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 处理输入变量连接(从变量节点到流程节点)
|
|
|
+ // 处理输入变量连接(从 Get 变量节点到流程节点)
|
|
|
if (processNode.data.inVars && Array.isArray(processNode.data.inVars)) {
|
|
|
const inVars = processNode.data.inVars;
|
|
|
const dataInputPorts = processNode.inputs?.filter(input => input.type === 'data') || [];
|
|
|
|
|
|
inVars.forEach((value, index) => {
|
|
|
- if (index >= dataInputPorts.length) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (index >= dataInputPorts.length) return;
|
|
|
|
|
|
const inputPort = dataInputPorts[index];
|
|
|
- if (!inputPort) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (!inputPort) return;
|
|
|
|
|
|
- // 检查值是否是变量引用(格式:"{varName}" 或 varName)
|
|
|
- let varName = null;
|
|
|
- if (typeof value === 'string') {
|
|
|
- // 去掉引号和大括号
|
|
|
- const cleaned = value.replace(/^["']|["']$/g, '').replace(/^{|}$/g, '');
|
|
|
- if (cleaned && variableNodeMap.has(cleaned)) {
|
|
|
- varName = cleaned;
|
|
|
- }
|
|
|
- }
|
|
|
+ const varName = extractVarName(value);
|
|
|
+ if (!varName) return;
|
|
|
|
|
|
- // 如果找到变量引用,创建从变量节点到流程节点的连接
|
|
|
- if (varName) {
|
|
|
- const varNode = variableNodeMap.get(varName);
|
|
|
- if (varNode && varNode.outputs && varNode.outputs.length > 0) {
|
|
|
- const varOutputPort = varNode.outputs[0]; // 变量节点只有一个输出端口
|
|
|
- connections.push({
|
|
|
- id: `conn_var_in_${processNode.id}_${inputPort.id}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
|
- source: varNode.id,
|
|
|
- target: processNode.id,
|
|
|
- sourcePort: varOutputPort.id,
|
|
|
- targetPort: inputPort.id
|
|
|
- });
|
|
|
- }
|
|
|
+ // 从 Get 节点连接到流程节点的输入端口
|
|
|
+ const getNode = getNodes.get(varName);
|
|
|
+ if (getNode && getNode.outputs && getNode.outputs.length > 0) {
|
|
|
+ const varOutputPort = getNode.outputs[0];
|
|
|
+ connections.push({
|
|
|
+ id: `conn_var_in_${processNode.id}_${inputPort.id}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
|
+ source: getNode.id,
|
|
|
+ target: processNode.id,
|
|
|
+ sourcePort: varOutputPort.id,
|
|
|
+ targetPort: inputPort.id
|
|
|
+ });
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- // 处理输出变量连接(从流程节点到变量节点)
|
|
|
+ // 处理输出变量连接(从流程节点到 Set 变量节点)
|
|
|
if (processNode.data.outVars && Array.isArray(processNode.data.outVars)) {
|
|
|
const outVars = processNode.data.outVars;
|
|
|
const dataOutputPorts = processNode.outputs?.filter(output => output.type === 'data') || [];
|
|
|
|
|
|
outVars.forEach((value, index) => {
|
|
|
- if (index >= dataOutputPorts.length) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (index >= dataOutputPorts.length) return;
|
|
|
|
|
|
const outputPort = dataOutputPorts[index];
|
|
|
- if (!outputPort) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (!outputPort) return;
|
|
|
|
|
|
- // 检查值是否是变量引用(格式:"{varName}" 或 varName)
|
|
|
- let varName = null;
|
|
|
- if (typeof value === 'string') {
|
|
|
- // 去掉引号和大括号
|
|
|
- const cleaned = value.replace(/^["']|["']$/g, '').replace(/^{|}$/g, '');
|
|
|
- if (cleaned && variableNodeMap.has(cleaned)) {
|
|
|
- varName = cleaned;
|
|
|
- }
|
|
|
- }
|
|
|
+ const varName = extractVarName(value);
|
|
|
+ if (!varName) return;
|
|
|
|
|
|
- // 如果找到变量引用,创建从流程节点到变量节点的连接
|
|
|
- if (varName) {
|
|
|
- const varNode = variableNodeMap.get(varName);
|
|
|
- if (varNode && varNode.inputs && varNode.inputs.length > 0) {
|
|
|
- const varInputPort = varNode.inputs[0]; // 变量节点只有一个输入端口
|
|
|
- connections.push({
|
|
|
- id: `conn_var_out_${processNode.id}_${outputPort.id}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
|
- source: processNode.id,
|
|
|
- target: varNode.id,
|
|
|
- sourcePort: outputPort.id,
|
|
|
- targetPort: varInputPort.id
|
|
|
- });
|
|
|
- }
|
|
|
+ // 从流程节点的输出端口连接到 Set 节点
|
|
|
+ const setNode = setNodes.get(varName);
|
|
|
+ if (setNode && setNode.inputs && setNode.inputs.length > 0) {
|
|
|
+ const varInputPort = setNode.inputs[0];
|
|
|
+ connections.push({
|
|
|
+ id: `conn_var_out_${processNode.id}_${outputPort.id}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
|
+ source: processNode.id,
|
|
|
+ target: setNode.id,
|
|
|
+ sourcePort: outputPort.id,
|
|
|
+ targetPort: varInputPort.id
|
|
|
+ });
|
|
|
}
|
|
|
});
|
|
|
}
|