From 67e50265b5cdae1c28f39b924ccb277857f4acea Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期二, 18 二月 2025 14:08:36 +0800
Subject: [PATCH] 一些必填

---
 src/components/vue-flow/MainCanvas.vue |  213 ++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 153 insertions(+), 60 deletions(-)

diff --git a/src/components/vue-flow/MainCanvas.vue b/src/components/vue-flow/MainCanvas.vue
index 44075f5..64db7c1 100644
--- a/src/components/vue-flow/MainCanvas.vue
+++ b/src/components/vue-flow/MainCanvas.vue
@@ -1,15 +1,56 @@
 <template>
 	<div class="relative h-full w-full" id="main-canvas" @drop="handleOnDrop" @dragover="handleOnDragOver">
-		<VueFlow v-model="elements" :node-types="nodeTypes" :connection-mode="ConnectionMode.Loose">
+		<VueFlow v-model="elements" :node-types="nodeTypes" :connection-mode="ConnectionMode.Strict">
+			<template #node-start="startNodeProps">
+				<StartNode ref="nodeRef" v-bind="startNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(startNodeProps.id, ref)" />
+			</template>
+			<template #node-condition="conditionNodeProps">
+				<ConditionNode ref="nodeRef" v-bind="conditionNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(conditionNodeProps.id, ref)" />
+			</template>
+			<template #node-output_msg="outputNodeProps">
+				<OutputNode ref="nodeRef" v-bind="outputNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(outputNodeProps.id, ref)" />
+			</template>
+
+			<template #node-end="endNodeProps">
+				<EndNode ref="nodeRef" v-bind="endNodeProps" :isViewMode="isViewMode" />
+			</template>
+
 			<template #edge-custom="customEdgeProps">
-				<CustomEdge v-bind="customEdgeProps" />
+				<CustomEdge v-bind="customEdgeProps" :isViewMode="isViewMode" />
 			</template>
 
 			<template #node-agent="agentNodeProps">
-				<AgentNode v-bind="agentNodeProps" :agentNames="agentNames"/>
+				<AgentNode ref="nodeRef" v-bind="agentNodeProps" :agentNames="agentNames" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(agentNodeProps.id, ref)" />
 			</template>
-			<Controls />
+			<template #node-func="funcNodeProps">
+				<FuncNode ref="nodeRef" v-bind="funcNodeProps" :funcNames="funcNames" :isViewMode="isViewMode" />
+			</template>
+
+			<template #node-code="codeNodeProps">
+				<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-text_resource="textResourceNodeProps">
+				<TextResourceNode ref="nodeRef" v-bind="textResourceNodeProps" :isViewMode="isViewMode" @register="(ref) => registerNodeRef(textResourceNodeProps.id, ref)" />
+			</template>
+
+			<template #node-analysis="analysisNodeProps">
+				<AnalysisNode ref="nodeRef" v-bind="analysisNodeProps" :llmInfoList="llmInfoList" :isViewMode="isViewMode" />
+			</template>
+
+			<template #node-LLM="llmNodeProps">
+				<LLMNode
+					v-bind="llmNodeProps"
+					:llmInfoList="llmInfoList"
+					:isViewMode="isViewMode"
+					@register="(ref) => registerNodeRef(llmNodeProps.id, ref)"
+				/>
+			</template>
+			<Controls :showInteractive="false" />
 			<Background />
+			<MiniMap pannable zoomable />
 		</VueFlow>
 	</div>
 </template>
@@ -17,69 +58,88 @@
 <script setup lang="ts">
 import { Background } from '@vue-flow/background';
 import { Controls } from '@vue-flow/controls';
-import { Dimensions, Elements, useVueFlow, VueFlow, ConnectionMode, MarkerType } from '@vue-flow/core';
-import { markRaw, nextTick, ref, watch } from 'vue';
+import { MiniMap } from '@vue-flow/minimap';
+
+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';
-import StartNode from './ui/nodes/StartNode.vue';
-import EndNode from './ui/nodes/EndNode.vue';
-import { VueFlowHelper } from './VueFlowHelper';
-import { NodeType, nodeTypeMap } from './vueFlowEnum';
+import CustomEdge from './ui/edges/CustomEdge.vue';
+import AgentNode from './ui/nodes/AgentNode.vue';
+import AnalysisNode from './ui/nodes/AnalysisNode.vue';
+import CodeNode from './ui/nodes/CodeNode.vue';
 import ConditionNode from './ui/nodes/ConditionNode.vue';
+import EndNode from './ui/nodes/EndNode.vue';
+import FuncNode from './ui/nodes/FuncNode.vue';
 import LLMNode from './ui/nodes/LLMNode.vue';
 import OutputNode from './ui/nodes/OutputNode.vue';
-import AgentNode from './ui/nodes/AgentNode.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 CustomEdge from './ui/edges/CustomEdge.vue';
+const props = defineProps(['flowJson', 'agentNames', 'funcNames', 'llmInfoList', 'isViewMode']);
 
-const props = defineProps(['flowJson','agentNames']);
-
-
-const nodeTypes = {
-	start: markRaw(StartNode),
-	end: markRaw(EndNode),
-	condition: markRaw(ConditionNode),
-	LLM: markRaw(LLMNode),
-	// output:markRaw(OutputNode),
-	agent: markRaw(AgentNode),
-	[NodeType.Output]: markRaw(OutputNode),
-	// LLM: markRaw(LLMNode),
-	// code: markRaw(CodeNode),
-	// knowledge: markRaw(KnowledgeNode),
-	// api: markRaw(ApiNode),
-};
+const nodeTypes = {};
 const elements = ref<Elements>();
-const { findNode, nodes, addNodes, addEdges, project, vueFlowRef, onConnect, setNodes, setEdges, setViewport, fromObject } =
-	useVueFlow(
-		Object.keys(props.flowJson).length > 0
-			? props.flowJson
-			: {
-					nodes: [
-						{
-							id: '1',
-							type: 'start',
-							data: VueFlowHelper.getDefaultData(NodeType.Start),
+const {
+	findNode,
+	nodes,
+	addNodes,
+	addEdges,
+	project,
+	vueFlowRef,
+	onConnect,
+	setNodes,
+	setEdges,
+	setViewport,
+	fitView,
+	setInteractive,
+} = useVueFlow(
+	Object.keys(props.flowJson).length > 0
+		? props.flowJson
+		: ({
+				nodes: [
+					{
+						id: '1',
+						type: 'start',
+						data: VueFlowHelper.getDefaultData(NodeType.Start),
 
-							position: { x: 25, y: 400 },
-						},
-						{
-							id: '2',
-							type: 'end',
-							data: VueFlowHelper.getDefaultData(NodeType.End),
-							position: { x: 1000, y: 400 },
-						},
-					],
-					edges: [
-						// {
-						// 	id: 'test',
-						// 	source: '1',
-						// 	target: '2',
-						// },
-					],
-			  }
-	);
+						position: { x: 25, y: 400 },
+					},
+				],
+				edges: [],
+		  } as FlowProps)
+);
 
 onConnect((params) => {
-	addEdges(params);
+	addEdges({
+		id: VueFlowHelper.genGeometryId(),
+
+		source: params.source,
+		target: params.target,
+		sourceHandle: params.sourceHandle,
+		targetHandle: params.targetHandle,
+		type: 'custom',
+		markerEnd: {
+			type: MarkerType.ArrowClosed,
+			width: 40,
+			height: 70,
+		},
+	});
+
+	// addEdges());
+});
+const initFlowStatus = () => {
+	fitView();
+
+	setInteractive(!props.isViewMode);
+};
+onMounted(() => {
+	setTimeout(() => {
+		initFlowStatus();
+	}, 30);
 });
 
 function handleOnDrop(event: DragEvent) {
@@ -134,18 +194,51 @@
 		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';
 @import '@vue-flow/core/dist/theme-default.css';
 @import '@vue-flow/controls/dist/style.css';
+@import '@vue-flow/minimap/dist/style.css';
+@import '@vue-flow/node-resizer/dist/style.css';
 
 #main-canvas {
 	--vf-handle: #2563eb;
-
+	--handle-size: 13px;
+	--resize-handle-size: 8px;
 	.vue-flow__handle {
-		width: 18px;
-		height: 18px;
+		width: var(--handle-size);
+		height: var(--handle-size);
 	}
+
+	// .vue-flow__resize-control.handle {
+	// 	width: var(--resize-handle-size);
+	// 	height: var(--resize-handle-size);
+	// 	// visibility: hidden;
+	// }
 }
 </style>
+
+<style lang="scss" scoped></style>

--
Gitblit v1.9.3