From f78e1bd0772608c7cd59264ab94f87ef94012c0b Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期五, 21 三月 2025 09:56:15 +0800
Subject: [PATCH] 工作流

---
 src/components/vue-flow/MainCanvas.vue |  135 ++++++++++++++++++++++++++++++++++++++------
 1 files changed, 116 insertions(+), 19 deletions(-)

diff --git a/src/components/vue-flow/MainCanvas.vue b/src/components/vue-flow/MainCanvas.vue
index 7ad78d8..8ee2b13 100644
--- a/src/components/vue-flow/MainCanvas.vue
+++ b/src/components/vue-flow/MainCanvas.vue
@@ -2,17 +2,32 @@
 	<div class="relative h-full w-full" id="main-canvas" @drop="handleOnDrop" @dragover="handleOnDragOver">
 		<VueFlow v-model="elements" :node-types="nodeTypes" :connection-mode="ConnectionMode.Strict">
 			<template #node-start="startNodeProps">
-				<StartNode v-bind="startNodeProps" :isViewMode="isViewMode" />
+				<StartNode
+					ref="nodeRef"
+					v-bind="startNodeProps"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(startNodeProps.id, ref)"
+				/>
 			</template>
 			<template #node-condition="conditionNodeProps">
-				<ConditionNode v-bind="conditionNodeProps" :isViewMode="isViewMode" />
+				<ConditionNode
+					ref="nodeRef"
+					v-bind="conditionNodeProps"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(conditionNodeProps.id, ref)"
+				/>
 			</template>
 			<template #node-output_msg="outputNodeProps">
-				<OutputNode v-bind="outputNodeProps" :isViewMode="isViewMode" />
+				<OutputNode
+					ref="nodeRef"
+					v-bind="outputNodeProps"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(outputNodeProps.id, ref)"
+				/>
 			</template>
 
 			<template #node-end="endNodeProps">
-				<EndNode v-bind="endNodeProps" :isViewMode="isViewMode" />
+				<EndNode ref="nodeRef" v-bind="endNodeProps" :isViewMode="isViewMode" />
 			</template>
 
 			<template #edge-custom="customEdgeProps">
@@ -20,27 +35,65 @@
 			</template>
 
 			<template #node-agent="agentNodeProps">
-				<AgentNode v-bind="agentNodeProps" :agentNames="agentNames" :isViewMode="isViewMode" />
+				<AgentNode
+					ref="nodeRef"
+					v-bind="agentNodeProps"
+					:agentNames="agentNames"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(agentNodeProps.id, ref)"
+				/>
 			</template>
 			<template #node-func="funcNodeProps">
-				<FuncNode v-bind="funcNodeProps" :funcNames="funcNames" :isViewMode="isViewMode" />
+				<FuncNode ref="nodeRef" v-bind="funcNodeProps" :funcNames="funcNames" :isViewMode="isViewMode" />
 			</template>
 
 			<template #node-code="codeNodeProps">
-				<CodeNode v-bind="codeNodeProps" :isViewMode="isViewMode" />
+				<CodeNode
+					ref="nodeRef"
+					v-bind="codeNodeProps"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(codeNodeProps.id, ref)"
+				/>
+			</template>
+			<template #node-python_code="pythonCodeNodeProps">
+				<PythonCodeNode
+					ref="nodeRef"
+					v-bind="pythonCodeNodeProps"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(pythonCodeNodeProps.id, ref)"
+				/>
+			</template>
+			<template #node-n8n="n8nNodeProps">
+				<N8nNode
+					:workflowList="n8nWorkflowList"
+					ref="nodeRef"
+					v-bind="n8nNodeProps"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(n8nNodeProps.id, ref)"
+				/>
 			</template>
 			<template #node-text_resource="textResourceNodeProps">
-				<TextResourceNode v-bind="textResourceNodeProps" :isViewMode="isViewMode" />
+				<TextResourceNode
+					ref="nodeRef"
+					v-bind="textResourceNodeProps"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(textResourceNodeProps.id, ref)"
+				/>
 			</template>
 
 			<template #node-analysis="analysisNodeProps">
-				<AnalysisNode v-bind="analysisNodeProps" :llmInfoList="llmInfoList" :isViewMode="isViewMode" />
+				<AnalysisNode ref="nodeRef" v-bind="analysisNodeProps" :llmInfoList="llmInfoList" :isViewMode="isViewMode" />
 			</template>
 
 			<template #node-LLM="llmNodeProps">
-				<LLMNode v-bind="llmNodeProps" :llmInfoList="llmInfoList" :isViewMode="isViewMode" />
+				<LLMNode
+					v-bind="llmNodeProps"
+					:llmInfoList="llmInfoList"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(llmNodeProps.id, ref)"
+				/>
 			</template>
-			<Controls :showInteractive="false"/>
+			<Controls :showInteractive="false" />
 			<Background />
 			<MiniMap pannable zoomable />
 		</VueFlow>
@@ -52,7 +105,7 @@
 import { Controls } from '@vue-flow/controls';
 import { MiniMap } from '@vue-flow/minimap';
 
-import type { Dimensions, Elements, FlowOptions, FlowProps } from '@vue-flow/core';
+import type { Dimensions, Elements, FlowProps } from '@vue-flow/core';
 import { ConnectionMode, MarkerType, useVueFlow, VueFlow } from '@vue-flow/core';
 import { nextTick, onMounted, ref, watch } from 'vue';
 import { Test_data } from './testData';
@@ -65,16 +118,39 @@
 import FuncNode from './ui/nodes/FuncNode.vue';
 import LLMNode from './ui/nodes/LLMNode.vue';
 import OutputNode from './ui/nodes/OutputNode.vue';
+import PythonCodeNode from './ui/nodes/PythonCodeNode.vue';
 import StartNode from './ui/nodes/StartNode.vue';
 import TextResourceNode from './ui/nodes/TextResourceNode.vue';
 import { NodeType, nodeTypeMap } from './vueFlowEnum';
 import { VueFlowHelper } from './VueFlowHelper';
-
+import N8nNode from './ui/nodes/N8nNode.vue';
+import { GetN8nWorkflowList } from '/@/api/n8n';
 const props = defineProps(['flowJson', 'agentNames', 'funcNames', 'llmInfoList', 'isViewMode']);
+
+const n8nWorkflowList = ref([]);
+const getN8nWorkflowList = async () => {
+	const res = await GetN8nWorkflowList({
+		active: true,
+	});
+	n8nWorkflowList.value = res?.data ?? [];
+};
 
 const nodeTypes = {};
 const elements = ref<Elements>();
-const { findNode, nodes, addNodes, addEdges, project, vueFlowRef, onConnect, setNodes, setEdges, setViewport, fitView,setInteractive } = useVueFlow(
+const {
+	findNode,
+	nodes,
+	addNodes,
+	addEdges,
+	project,
+	vueFlowRef,
+	onConnect,
+	setNodes,
+	setEdges,
+	setViewport,
+	fitView,
+	setInteractive,
+} = useVueFlow(
 	Object.keys(props.flowJson).length > 0
 		? props.flowJson
 		: ({
@@ -88,8 +164,6 @@
 					},
 				],
 				edges: [],
-				
-				
 		  } as FlowProps)
 );
 
@@ -111,12 +185,13 @@
 
 	// addEdges());
 });
-const initFlowStatus = () =>{
+const initFlowStatus = () => {
 	fitView();
 
 	setInteractive(!props.isViewMode);
-}
-onMounted(() => {
+};
+onMounted(async () => {
+	getN8nWorkflowList();
 	setTimeout(() => {
 		initFlowStatus();
 	}, 30);
@@ -174,6 +249,28 @@
 		event.dataTransfer.dropEffect = 'move';
 	}
 }
+
+const nodeRefs = ref(new Map());
+
+const registerNodeRef = (nodeId: string, ref: any) => {
+	nodeRefs.value.set(nodeId, ref);
+};
+
+const validateForm = async () => {
+	const validPromises = [];
+	for (const nodeRef of nodeRefs.value.values()) {
+		if (nodeRef?.validateForm) {
+			validPromises.push(nodeRef.validateForm());
+		}
+	}
+
+	const results = await Promise.all(validPromises);
+	return results;
+};
+
+defineExpose({
+	validateForm,
+});
 </script>
 <style lang="scss">
 @import '@vue-flow/core/dist/style.css';

--
Gitblit v1.9.3