瀏覽代碼

feat: 完善输入节点配置

jiaxing.liao 1 月之前
父節點
當前提交
eacf48f9c9

+ 1 - 1
apps/web/src/api/index.ts

@@ -10,7 +10,7 @@ export const UploadFile = (data: FormData) => {
 		result: {
 			id: string
 		}[]
-	}>('/api/fileApi/File/UploadFiles', {
+	}>('/api/File/UploadFiles', {
 		method: 'POST',
 		headers: {
 			'Content-Type': 'multipart/form-data'

+ 23 - 3
apps/web/src/nodes/_base/VarSelect.vue

@@ -37,7 +37,11 @@
 									class="var-select__item-prefix env text-10px"
 									:style="{ background: nodeMap[valueInfo?.nodeType ?? '']?.iconColor ?? '' }"
 								>
-									<Icon :icon="nodeMap[valueInfo?.nodeType!]?.icon!" :size="18" />
+									<Icon
+										v-if="nodeMap[valueInfo?.nodeType!]?.icon"
+										:icon="nodeMap[valueInfo?.nodeType!]?.icon!"
+										:size="18"
+									/>
 								</span>
 								<span>{{ valueInfo.nodeName }}</span>
 								<span class="mx-2px text-gray-400">/</span>
@@ -109,6 +113,10 @@ interface Props {
 	 * 过滤方法
 	 */
 	filterFn?: (list: NodeVar[]) => NodeVar[]
+	/**
+	 * 绑定类型
+	 */
+	varType?: VarType | ''
 }
 
 const props = withDefaults(defineProps<Props>(), {
@@ -117,7 +125,9 @@ const props = withDefaults(defineProps<Props>(), {
 
 const emit = defineEmits<{
 	(e: 'update:modelValue', value: string): void
+	(e: 'update:varType', value?: VarType | ''): void
 	(e: 'change', value: { value: string; type: VarType }): void
+	(e: 'clear'): void
 }>()
 
 const nodeVars = inject<Ref<NodeVar[]>>('nodeVars')
@@ -125,6 +135,7 @@ const nodeVars = inject<Ref<NodeVar[]>>('nodeVars')
 const visible = ref(false)
 const keyword = ref('')
 const innerValue = ref<string>(props.modelValue)
+const innerType = ref<VarType | '' | undefined>(props.varType)
 
 watch(
 	() => props.modelValue,
@@ -138,15 +149,23 @@ watch(
 
 const handleClear = () => {
 	innerValue.value = ''
+	innerType.value = ''
+	emit('update:varType', '')
 	emit('update:modelValue', '')
+	emit('clear')
 }
 
 watch(
 	() => innerValue.value,
 	(val) => {
 		emit('update:modelValue', val)
-	},
-	{ deep: true }
+	}
+)
+watch(
+	() => innerType.value,
+	(val) => {
+		emit('update:varType', val)
+	}
 )
 
 const valueInfo = computed(() => {
@@ -232,6 +251,7 @@ const filteredVars = computed(() => {
 
 const handleSelect = (variable: { value: string; type: VarType }) => {
 	innerValue.value = variable.value
+	innerType.value = variable.type
 	visible.value = false
 	keyword.value = ''
 	emit('change', variable)

+ 1 - 1
apps/web/src/nodes/_base/condition/ConditionItem.vue

@@ -8,7 +8,7 @@
 			<!-- 左侧变量选择 -->
 			<VarSelect
 				v-model="modelValue.left_value"
-				class="flex-1 max-w-[160px]"
+				class="flex-1"
 				placeholder="{x} 设置变量值"
 				@change="handleLeftValueChange"
 			/>

+ 40 - 50
apps/web/src/nodes/src/iteration/setter.vue

@@ -1,10 +1,21 @@
 <script lang="ts" setup>
-import { computed } from 'vue'
+import { computed, watch } from 'vue'
 import VarSelect from '@/nodes/_base/VarSelect.vue'
 import { useSetterModel } from '../_shared/useSetterModel'
 
 import type { IterationData } from './index'
-import type { NodeVariableType } from '@/nodes/Interface'
+import type { NodeVariable, NodeVariableType } from '@/nodes/Interface'
+
+const outputsTypeMap = {
+	string: 'array[string]',
+	number: 'array[number]',
+	boolean: 'array[boolean]',
+	object: 'array[object]',
+	'array[string]': 'array[object]',
+	'array[number]': 'array[object]',
+	'array[boolean]': 'array[object]',
+	'array[object]': 'array[object]'
+}
 
 const props = defineProps<{
 	data: IterationData
@@ -24,7 +35,10 @@ const formData = useSetterModel<IterationData>(props, emit)
 
 const inputVar = computed({
 	get() {
-		return formData.value.variables?.[0]
+		return (
+			formData.value.variables?.[0] ||
+			({ value: '', type: '', name: '' } as unknown as NodeVariable)
+		)
 	},
 	set(val) {
 		if (val && formData.value.variables?.[0]) {
@@ -35,49 +49,27 @@ const inputVar = computed({
 	}
 })
 
-const handleInputVarChange = (val: { value: string; type: string }) => {
-	if (inputVar.value) {
-		inputVar.value.value = val.value
-		inputVar.value.type = val.type as NodeVariableType
-	}
-}
-
-const outputsTypeMap = {
-	string: 'array[string]',
-	number: 'array[number]',
-	boolean: 'array[boolean]',
-	object: 'array[object]',
-	'array[string]': 'array[object]',
-	'array[number]': 'array[object]',
-	'array[boolean]': 'array[object]',
-	'array[object]': 'array[object]'
-}
-
-const handleOutputIterationVariableChange = (val: { value: string; type: string }) => {
-	if (formData.value.output_iteration_variable) {
-		formData.value.output_iteration_variable.value = val.value
-		formData.value.output_iteration_variable.type = val.type as NodeVariableType
-	} else {
-		formData.value.output_iteration_variable = {
-			name: '',
-			value: val.value,
-			type: val.type as NodeVariableType
-		}
-	}
-	// 设置输出变量类型
-	if (formData.value.outputs?.[0]) {
-		formData.value.outputs[0].type = outputsTypeMap[
-			val.type as keyof typeof outputsTypeMap
-		] as NodeVariableType
-	} else {
-		formData.value.outputs = [
-			{
-				name: 'outputs',
-				type: outputsTypeMap[val.type as keyof typeof outputsTypeMap] as NodeVariableType
+watch(
+	() => formData.value.output_iteration_variable.type,
+	(val) => {
+		if (val) {
+			if (formData.value.outputs?.[0]) {
+				formData.value.outputs[0].type = outputsTypeMap[
+					val as keyof typeof outputsTypeMap
+				] as NodeVariableType
+			} else {
+				formData.value.outputs = [
+					{
+						name: 'outputs',
+						type: outputsTypeMap[val as keyof typeof outputsTypeMap] as NodeVariableType
+					}
+				]
 			}
-		]
+		} else {
+			formData.value.outputs = []
+		}
 	}
-}
+)
 </script>
 
 <template>
@@ -87,10 +79,9 @@ const handleOutputIterationVariableChange = (val: { value: string; type: string
 				<div class="w-full flex items-center justify-between beautify">
 					<label class="text-14px font-bold text-gray-700">输入</label>
 				</div>
-				<!--TODO: 输入变量类型选择-->
 				<VarSelect
-					:model-value="inputVar?.value"
-					@change="handleInputVarChange"
+					v-model:model-value="inputVar.value"
+					v-model:var-type="inputVar.type"
 					placeholder="请选择输入变量"
 				/>
 			</el-form-item>
@@ -99,10 +90,9 @@ const handleOutputIterationVariableChange = (val: { value: string; type: string
 				<div class="w-full flex items-center justify-between beautify">
 					<label class="text-14px font-bold text-gray-700">输出</label>
 				</div>
-				<!--TODO: 输出变量类型选择 内部迭代节点输出变量-->
 				<VarSelect
-					:model-value="formData?.output_iteration_variable?.value"
-					@change="handleOutputIterationVariableChange"
+					v-model:model-value="formData.output_iteration_variable.value"
+					v-model:var-type="formData.output_iteration_variable.type"
 					placeholder="请选择输入变量"
 				/>
 			</el-form-item>

+ 47 - 41
packages/workflow/src/components/Canvas.vue

@@ -115,6 +115,52 @@ const props = withDefaults(
 const getNodes = computed(() =>
 	props.hideChildNode ? props.nodes.filter((node) => !node?.parentId) : props.nodes
 )
+
+const getEdges = computed(() =>
+	props.edges
+		.filter((edge) => {
+			const { source, target } = edge
+			return getNodes.value.find((node) => node.id === source || node.id === target)
+		})
+		.map((edge) => {
+			const sourceNode = nodeById.value[edge.source]
+			const targetNode = nodeById.value[edge.target]
+			const sourceParentId = sourceNode?.parentId || ''
+			const targetParentId = targetNode?.parentId || ''
+			const executionStatus = getEdgeExecutionStatus(sourceNode, targetNode)
+
+			if (sourceParentId && sourceParentId !== targetParentId) {
+				return {
+					...edge,
+					source: sourceParentId,
+					data: {
+						...(edge.data || {}),
+						executionStatus
+					}
+				}
+			}
+
+			if (targetParentId && targetParentId !== sourceParentId) {
+				return {
+					...edge,
+					target: targetParentId,
+					data: {
+						...(edge.data || {}),
+						executionStatus
+					}
+				}
+			}
+
+			return {
+				...edge,
+				data: {
+					...(edge.data || {}),
+					executionStatus
+				}
+			}
+		})
+)
+
 const defaultViewport = { x: 0, y: 0, zoom: 1 }
 const projectExtent = computed<CoordinateExtent | undefined>(() => {
 	return Array.isArray(props.translateExtent) ? props.translateExtent : undefined
@@ -166,46 +212,6 @@ const nodeById = computed((): Record<string, IWorkflowNode> => {
 	}, {})
 })
 
-const normalizedEdges = computed(() =>
-	props.edges.map((edge) => {
-		const sourceNode = nodeById.value[edge.source]
-		const targetNode = nodeById.value[edge.target]
-		const sourceParentId = sourceNode?.parentId || ''
-		const targetParentId = targetNode?.parentId || ''
-		const executionStatus = getEdgeExecutionStatus(sourceNode, targetNode)
-
-		if (sourceParentId && sourceParentId !== targetParentId) {
-			return {
-				...edge,
-				source: sourceParentId,
-				data: {
-					...(edge.data || {}),
-					executionStatus
-				}
-			}
-		}
-
-		if (targetParentId && targetParentId !== sourceParentId) {
-			return {
-				...edge,
-				target: targetParentId,
-				data: {
-					...(edge.data || {}),
-					executionStatus
-				}
-			}
-		}
-
-		return {
-			...edge,
-			data: {
-				...(edge.data || {}),
-				executionStatus
-			}
-		}
-	})
-)
-
 /**
  * Edge and Nodes Hovering
  */
@@ -430,7 +436,7 @@ defineExpose({
 	<VueFlow
 		:id="id"
 		:nodes="getNodes"
-		:edges="normalizedEdges"
+		:edges="getEdges"
 		:default-viewport="defaultViewport"
 		:fit-view-on-init="zoomToFit"
 		:is-valid-connection="isValidConnection"