Selaa lähdekoodia

fix: 修复节点问题

jiaxing.liao 1 kuukausi sitten
vanhempi
commit
a6b2484af3

+ 2 - 0
apps/web/.gitignore

@@ -10,6 +10,8 @@ lerna-debug.log*
 node_modules
 dist
 dist.zip
+app-agent
+app-agent.zip
 dist-ssr
 *.local
 

+ 0 - 2
apps/web/src/nodes/src/loop-end/index.ts

@@ -1,5 +1,4 @@
 import { NodeConnectionTypes, type INodeType, type INodeDataBaseSchema } from '../../Interface'
-import Setter from './setter.vue'
 
 export type EndData = INodeDataBaseSchema
 
@@ -7,7 +6,6 @@ export const loopEndNode: INodeType = {
 	version: ['1'],
 	displayName: '退出循环',
 	name: 'loop-end',
-	Setter,
 	description: '用于退出迭代或者循环',
 	group: '业务逻辑',
 	icon: 'lucide:rotate-ccw',

+ 0 - 29
apps/web/src/nodes/src/loop-end/setter.vue

@@ -1,29 +0,0 @@
-<script setup lang="ts">
-import { ref, watch } from 'vue'
-import OutputVariables from '@/nodes/_base/OutputVariables.vue'
-
-import type { EndData } from './index'
-
-const props = defineProps<{
-	data: EndData
-}>()
-
-const emit = defineEmits<{
-	(e: 'update', data: EndData): void
-}>()
-
-const formData = ref<EndData>(props.data)
-
-watch(
-	() => formData.value,
-	(newVal) => {
-		emit('update', newVal)
-	}
-)
-</script>
-
-<template>
-	<el-scrollbar class="box-border p-12px">
-		<OutputVariables v-model="formData.outputs" :set-type="false" :set-value="true" />
-	</el-scrollbar>
-</template>

+ 30 - 1
apps/web/src/nodes/src/start/index.ts

@@ -1,10 +1,39 @@
-import { NodeConnectionTypes, type INodeType } from '../../Interface'
+import { NodeConnectionTypes, type INodeType, type INodeDataBaseSchema } from '../../Interface'
+import Setter from './setter.vue'
+
+type FileType = 'document' | 'image' | 'audio' | 'video' | 'custom'
+
+type FormType =
+	| 'text-input'
+	| 'text-area'
+	| 'select'
+	| 'number'
+	| 'checkbox'
+	| 'file'
+	| 'file-list'
+	| 'json_object'
+
+export type StartData = INodeDataBaseSchema & {
+	variables: Array<{
+		label: string
+		max_length: number
+		default_value: Record<string, any>
+		json: Record<string, any>
+		is_require: boolean
+		is_hide: boolean
+		formType: FormType
+		options: any[]
+		file_types: FileType[]
+		file_extensions: string[]
+	}>
+}
 
 export const startNode: INodeType = {
 	version: ['1'],
 	displayName: '用户输入',
 	name: 'start',
 	description: '用户输入节点,用于接收用户输入',
+	Setter,
 	group: '开始',
 	icon: 'lucide:play',
 	iconColor: '#296dff',

+ 24 - 0
apps/web/src/nodes/src/start/setter.vue

@@ -0,0 +1,24 @@
+<template>
+	<div></div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { useSetterModel } from '../_shared/useSetterModel'
+
+import type { StartData } from './index'
+
+interface Emits {
+	(e: 'update', value: StartData): void
+}
+
+const props = defineProps<{
+	data: StartData
+}>()
+
+const emit = defineEmits<Emits>()
+
+const formData = useSetterModel(props, emit)
+</script>
+
+<style scoped></style>

+ 10 - 0
apps/web/src/views/Editor.vue

@@ -68,6 +68,16 @@
 						@dragleave="onDragLeave"
 						@create:connection:cancelled="onConnectionOpenNodeLibary"
 						@click:connection:add="handleClickConectionAdd"
+						@loop:child:click:node="handleSelectNode"
+						@loop:child:dblclick:node="handleNodeClick"
+						@loop:child:create:connection:end="onCreateConnection"
+						@loop:child:run:node="handleRunNode"
+						@loop:child:update:nodes:position="handleUpdateNodesPosition"
+						@loop:child:update:node:attrs="handleUpdateNodeProps"
+						@loop:child:delete:node="handleDeleteNode"
+						@loop:child:delete:connection="handleDeleteEdge"
+						@loop:child:create:connection:cancelled="onConnectionOpenNodeLibary"
+						@loop:child:click:connection:add="handleClickConectionAdd"
 						class="bg-#f5f5f5"
 					>
 						<Toolbar

+ 3 - 0
apps/web/vite.config.ts

@@ -16,6 +16,9 @@ export default defineConfig(({ mode }) => {
 
 	return {
 		base: './',
+		build: {
+			outDir: 'app-agent'
+		},
 		plugins: [
 			vue(),
 			vueJsx(),

+ 44 - 9
packages/workflow/src/components/Canvas.vue

@@ -86,8 +86,28 @@ const emit = defineEmits<{
 	/**
 	 * 连线节点添加
 	 */
-	'click:connection:add': [connection: Connection]
-}>()
+		'click:connection:add': [connection: Connection]
+		'loop:child:click:node': [id: string, position: XYPosition]
+		'loop:child:dblclick:node': [id: string, position: XYPosition]
+		'loop:child:click:node:add': [
+			payload: { nodeId: string; handle: string; position: XYPosition; event?: MouseEvent }
+		]
+		'loop:child:create:connection:end': [connection: Connection, event?: MouseEvent]
+		'loop:child:update:node:attrs': [id: string, attrs: Record<string, unknown>]
+		'loop:child:update:nodes:position': [events: CanvasNodeMoveEvent[]]
+		'loop:child:create:connection:cancelled': [
+			payload: {
+				handle: ConnectStartEvent
+				position: XYPosition
+				event?: MouseEvent
+				parentId?: string
+			}
+		]
+		'loop:child:run:node': [id: string]
+		'loop:child:delete:node': [id: string]
+		'loop:child:delete:connection': [connection: Connection]
+		'loop:child:click:connection:add': [connection: Connection]
+	}>()
 
 const props = withDefaults(
 	defineProps<{
@@ -95,15 +115,13 @@ const props = withDefaults(
 		nodes: IWorkflow['nodes']
 		edges: IWorkflow['edges']
 		hideChildNode?: boolean
-		// 是否隐藏带parentId的节点
-		hideChildNode?: boolean
 		readOnly?: boolean
 		nodeMap: Record<string, any>
 		showControlBar?: boolean
 		zoomToFit?: boolean
 		translateExtent?: CoordinateExtent
 		nodeExtent?: CoordinateExtent | CoordinateExtentRange
-		}>(),
+	}>(),
 	{
 		id: 'canvas',
 		readOnly: false,
@@ -129,10 +147,7 @@ const isValidConnection: ValidConnectionFunc = (connection) => {
 	return connection.source !== connection.target
 }
 
-const clampPositionToExtent = (
-	position: XYPosition,
-	extent?: CoordinateExtent
-): XYPosition => {
+const clampPositionToExtent = (position: XYPosition, extent?: CoordinateExtent): XYPosition => {
 	if (!extent) {
 		return position
 	}
@@ -490,8 +505,28 @@ defineExpose({
 					"
 					@delete="onDeleteNode"
 					@run="onRunNode"
+					@delete:connection="onDeleteConnection"
 					@update:nodes:position="onUpdateNodesPosition"
 					@edge:add:click="onClickConnectionAdd"
+					@loop:child:click:node="(id, position) => emit('loop:child:click:node', id, position)"
+					@loop:child:dblclick:node="
+						(id, position) => emit('loop:child:dblclick:node', id, position)
+					"
+					@loop:child:click:node:add="emit('loop:child:click:node:add', $event)"
+					@loop:child:create:connection:end="
+						(connection, event) => emit('loop:child:create:connection:end', connection, event)
+					"
+					@loop:child:update:node:attrs="
+						(id, attrs) => emit('loop:child:update:node:attrs', id, attrs)
+					"
+					@loop:child:update:nodes:position="emit('loop:child:update:nodes:position', $event)"
+					@loop:child:create:connection:cancelled="
+						(p) => emit('loop:child:create:connection:cancelled', { ...p, parentId: nodeProps.id })
+					"
+					@loop:child:run:node="emit('loop:child:run:node', $event)"
+					@loop:child:delete:node="emit('loop:child:delete:node', $event)"
+					@loop:child:delete:connection="emit('loop:child:delete:connection', $event)"
+					@loop:child:click:connection:add="emit('loop:child:click:connection:add', $event)"
 				/>
 			</slot>
 		</template>

+ 35 - 1
packages/workflow/src/components/elements/nodes/CanvasNode.vue

@@ -12,6 +12,7 @@ import type {
 	IWorkflowNode,
 	IWorkflowEdge,
 	XYPosition,
+	CanvasNodeMoveEvent,
 	CanvasConnectionPort,
 	CanvasElementPortWithRenderData
 } from '../../../Interface'
@@ -40,6 +41,21 @@ const emit = defineEmits<{
 	'create-connection-cancelled': [
 		payload: { handle: ConnectStartEvent; position: XYPosition; event?: MouseEvent }
 	]
+	'loop:child:click:node': [id: string, position: XYPosition]
+	'loop:child:dblclick:node': [id: string, position: XYPosition]
+	'loop:child:click:node:add': [
+		payload: { nodeId: string; handle: string; position: XYPosition; event?: MouseEvent }
+	]
+	'loop:child:create:connection:end': [connection: Connection, event?: MouseEvent]
+	'loop:child:update:node:attrs': [id: string, attrs: Record<string, unknown>]
+	'loop:child:update:nodes:position': [events: CanvasNodeMoveEvent[]]
+	'loop:child:create:connection:cancelled': [
+		payload: { handle: ConnectStartEvent; position: XYPosition; event?: MouseEvent }
+	]
+	'loop:child:run:node': [id: string]
+	'loop:child:delete:node': [id: string]
+	'loop:child:delete:connection': [connection: Connection]
+	'loop:child:click:connection:add': [connection: Connection]
 }>()
 
 /**
@@ -159,7 +175,6 @@ provideCanvasNodeContext({
 <template>
 	<div class="relative w-full h-full">
 		<NodeRenderer
-			v-bind="$attrs"
 			@update="onUpdate"
 			@click:node="(id, position) => emit('click:node', id, position)"
 			@dblclick:node="(id, position) => emit('dblclick:node', id, position)"
@@ -167,6 +182,25 @@ provideCanvasNodeContext({
 			@add-inner-node="emit('add-inner-node')"
 			@add-inner-edge="emit('add-inner-edge', $event)"
 			@create:connection:cancelled="emit('create-connection-cancelled', $event)"
+			@loop:child:click:node="(id, position) => emit('loop:child:click:node', id, position)"
+			@loop:child:dblclick:node="
+				(id, position) => emit('loop:child:dblclick:node', id, position)
+			"
+			@loop:child:click:node:add="emit('loop:child:click:node:add', $event)"
+			@loop:child:create:connection:end="
+				(connection, event) => emit('loop:child:create:connection:end', connection, event)
+			"
+			@loop:child:update:node:attrs="
+				(id, attrs) => emit('loop:child:update:node:attrs', id, attrs)
+			"
+			@loop:child:update:nodes:position="emit('loop:child:update:nodes:position', $event)"
+			@loop:child:create:connection:cancelled="
+				emit('loop:child:create:connection:cancelled', $event)
+			"
+			@loop:child:run:node="emit('loop:child:run:node', $event)"
+			@loop:child:delete:node="emit('loop:child:delete:node', $event)"
+			@loop:child:delete:connection="emit('loop:child:delete:connection', $event)"
+			@loop:child:click:connection:add="emit('loop:child:click:connection:add', $event)"
 		/>
 
 		<template v-for="target in inputs" :key="'handle-inputs-port' + target.index">

+ 25 - 19
packages/workflow/src/components/elements/nodes/render-types/NodeLoop.vue

@@ -34,18 +34,22 @@ const childrenEdges = computed(() =>
 const emit = defineEmits<{
 	update: [id: string, attrs: Record<string, unknown>]
 	move: [position: XYPosition]
-	'click:node': [id: string, position: XYPosition]
-	'dblclick:node': [id: string, position: XYPosition]
-	'click:node:add': [
+	'add-inner-node': [parentId: string]
+	'loop:child:click:node': [id: string, position: XYPosition]
+	'loop:child:dblclick:node': [id: string, position: XYPosition]
+	'loop:child:click:node:add': [
 		payload: { nodeId: string; handle: string; position: XYPosition; event?: MouseEvent }
 	]
-	'add-inner-node': [parentId: string]
-	'add-inner-edge': [connection: Connection]
-	'update:nodes:position': [events: CanvasNodeMoveEvent[]]
-	'create:connection:cancelled': [
+	'loop:child:create:connection:end': [connection: Connection, event?: MouseEvent]
+	'loop:child:update:node:attrs': [id: string, attrs: Record<string, unknown>]
+	'loop:child:update:nodes:position': [events: CanvasNodeMoveEvent[]]
+	'loop:child:create:connection:cancelled': [
 		payload: { handle: ConnectStartEvent; position: XYPosition; event?: MouseEvent }
 	]
-	'edge:add:click': [connection: Connection]
+	'loop:child:run:node': [id: string]
+	'loop:child:delete:node': [id: string]
+	'loop:child:delete:connection': [connection: Connection]
+	'loop:child:click:connection:add': [connection: Connection]
 }>()
 
 const nodeData = computed(() => node.props.value.node?.data ?? node.props.value.data)
@@ -97,9 +101,6 @@ function onAddNode() {
 	}
 }
 
-function onAddEdge(connection: Connection) {
-	emit('add-inner-edge', connection)
-}
 </script>
 
 <template>
@@ -157,15 +158,20 @@ function onAddEdge(connection: Connection) {
 					:auto-pan-on-node-drag="false"
 					:translate-extent="innerCanvasExtent"
 					:node-extent="innerCanvasExtent"
-					@click:node="(id, position) => emit('click:node', id, position)"
-					@dblclick:node="(id, position) => emit('dblclick:node', id, position)"
-					@click:node:add="emit('click:node:add', $event)"
+					@click:node="(id, position) => emit('loop:child:click:node', id, position)"
+					@dblclick:node="(id, position) => emit('loop:child:dblclick:node', id, position)"
+					@click:node:add="emit('loop:child:click:node:add', $event)"
 					@create:node="onAddNode"
-					@create:connection:end="onAddEdge"
-					@create:connection:cancelled="emit('create:connection:cancelled', $event)"
-					@update:node:attrs="(id, attrs) => emit('update', id, attrs)"
-					@update:nodes:position="emit('update:nodes:position', $event)"
-					@click:connection:add="emit('edge:add:click', $event)"
+					@create:connection:end="
+						(connection, event) => emit('loop:child:create:connection:end', connection, event)
+					"
+					@create:connection:cancelled="emit('loop:child:create:connection:cancelled', $event)"
+					@update:node:attrs="(id, attrs) => emit('loop:child:update:node:attrs', id, attrs)"
+					@update:nodes:position="emit('loop:child:update:nodes:position', $event)"
+					@run:node="emit('loop:child:run:node', $event)"
+					@delete:node="emit('loop:child:delete:node', $event)"
+					@delete:connection="emit('loop:child:delete:connection', $event)"
+					@click:connection:add="emit('loop:child:click:connection:add', $event)"
 				/>
 			</div>
 		</div>

+ 35 - 6
packages/workflow/src/components/elements/nodes/render-types/NodeRenderer.vue

@@ -6,7 +6,7 @@ import NodeLoop from './NodeLoop.vue'
 import NodeIcon from './NodeIcon.vue'
 
 import type { Connection } from '@vue-flow/core'
-import type { XYPosition, ConnectStartEvent } from '../../../../Interface'
+import type { XYPosition, ConnectStartEvent, CanvasNodeMoveEvent } from '../../../../Interface'
 import { useCanvasNodeContext } from '../../../../hooks/useCanvasNodeContext'
 
 const node = useCanvasNodeContext()
@@ -20,6 +20,21 @@ defineEmits<{
 	'add-inner-node': []
 	'add-inner-edge': [connection: Connection]
 	'create:connection:cancelled': [payload: { handle: ConnectStartEvent; position: XYPosition; event?: MouseEvent }]
+	'loop:child:click:node': [id: string, position: XYPosition]
+	'loop:child:dblclick:node': [id: string, position: XYPosition]
+	'loop:child:click:node:add': [
+		payload: { nodeId: string; handle: string; position: XYPosition; event?: MouseEvent }
+	]
+	'loop:child:create:connection:end': [connection: Connection, event?: MouseEvent]
+	'loop:child:update:node:attrs': [id: string, attrs: Record<string, unknown>]
+	'loop:child:update:nodes:position': [events: CanvasNodeMoveEvent[]]
+	'loop:child:create:connection:cancelled': [
+		payload: { handle: ConnectStartEvent; position: XYPosition; event?: MouseEvent }
+	]
+	'loop:child:run:node': [id: string]
+	'loop:child:delete:node': [id: string]
+	'loop:child:delete:connection': [connection: Connection]
+	'loop:child:click:connection:add': [connection: Connection]
 }>()
 </script>
 
@@ -28,12 +43,26 @@ defineEmits<{
 	<NodeLoop
 		v-else-if="nodeType === 'loop' || nodeType === 'iteration'"
 		v-bind="$attrs"
-		@click:node="(id, position) => $emit('click:node', id, position)"
-		@dblclick:node="(id, position) => $emit('dblclick:node', id, position)"
-		@click:node:add="$emit('click:node:add', $event)"
 		@add-inner-node="$emit('add-inner-node')"
-		@add-inner-edge="$emit('add-inner-edge', $event)"
-		@create:connection:cancelled="$emit('create:connection:cancelled', $event)"
+		@loop:child:click:node="(id, position) => $emit('loop:child:click:node', id, position)"
+		@loop:child:dblclick:node="
+			(id, position) => $emit('loop:child:dblclick:node', id, position)
+		"
+		@loop:child:click:node:add="$emit('loop:child:click:node:add', $event)"
+		@loop:child:create:connection:end="
+			(connection, event) => $emit('loop:child:create:connection:end', connection, event)
+		"
+		@loop:child:update:node:attrs="
+			(id, attrs) => $emit('loop:child:update:node:attrs', id, attrs)
+		"
+		@loop:child:update:nodes:position="$emit('loop:child:update:nodes:position', $event)"
+		@loop:child:create:connection:cancelled="
+			$emit('loop:child:create:connection:cancelled', $event)
+		"
+		@loop:child:run:node="$emit('loop:child:run:node', $event)"
+		@loop:child:delete:node="$emit('loop:child:delete:node', $event)"
+		@loop:child:delete:connection="$emit('loop:child:delete:connection', $event)"
+		@loop:child:click:connection:add="$emit('loop:child:click:connection:add', $event)"
 	/>
 	<NodeIcon v-else-if="nodeType?.includes('-start')" v-bind="$attrs" />
 	<NodeDefault v-else v-bind="$attrs"> </NodeDefault>