Skip to content

Commit eadd605

Browse files
feat: loop
1 parent 48fff67 commit eadd605

7 files changed

Lines changed: 92 additions & 77 deletions

File tree

‎ui/src/workflow-canvas/config/node-data.ts‎

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ export const parameterExtractionNode = {
276276
properties: { stepName: '参数提取', config: { fields: [{ label: '结果', value: 'result' }] } },
277277
}
278278

279-
280279
/* 知识库检索 */
281280
export const searchKnowledgeNode = {
282281
type: WorkflowNodeType.SearchKnowledge,
@@ -344,7 +343,6 @@ export const rerankerNode = {
344343
},
345344
}
346345

347-
348346
/* MCP 调用 */
349347
export const mcpNode = {
350348
type: WorkflowNodeType.McpNode,
@@ -361,7 +359,6 @@ export const toolCustomNode = {
361359
properties: { stepName: '自定义工具', config: { fields: [{ label: '结果', value: 'result' }] } },
362360
}
363361

364-
365362
/* 智能体节点 */
366363
export const applicationNode = {
367364
type: WorkflowNodeType.Application,
@@ -370,99 +367,92 @@ export const applicationNode = {
370367
properties: { stepName: '智能体节点', config: { fields: [{ label: '结果', value: 'result' }] } },
371368
}
372369

373-
374370
/**
375371
* 工具配置数据
376372
*/
377373
export const toolLibNode = {
378374
type: WorkflowNodeType.ToolLib,
379-
text: '通过执行自定义脚本,实现数据处理',
380-
label: '自定义工具',
381-
height: 170,
382-
properties: { stepName: '自定义工具', config: { fields: [{ label: '结果', value: 'result' }] } },
383-
}
384-
385-
/**
386-
* 工作流工具配置数据
387-
*/
388-
export const toolWorkflowLibNode = {
389-
type: WorkflowNodeType.ToolWorkflowLib,
390-
text: '工作流工具',
391-
label: '工作流工具',
392-
height: 170,
393-
properties: { stepName: '工作流工具', config: { fields: [] } },
375+
text: '工具节点',
376+
label: '工具节点',
377+
properties: { stepName: '工具节点', config: { fields: [{ label: '结果', value: 'result' }] } },
394378
}
395379

396-
397-
398-
399-
export const loopStartNode = {
400-
id: WorkflowNodeType.LoopStartNode,
401-
type: WorkflowNodeType.LoopStartNode,
402-
x: 480,
403-
y: 3340,
404-
properties: {
405-
height: 364,
406-
stepName: '循环开始',
407-
config: {
408-
fields: [
409-
{ label: '下标', value: 'index' },
410-
{ label: '循环元素', value: 'item' },
411-
],
412-
globalFields: [],
413-
},
414-
showNode: true,
415-
},
416-
}
380+
/* 循环节点 */
417381

418382
export const loopNode = {
419383
type: WorkflowNodeType.LoopNode,
420384
visible: false,
421385
text: '通过设置循环次数和逻辑,重复执行一系列任务',
422386
label: '循环节点',
423-
height: 252,
424387
properties: {
425388
stepName: '循环节点',
426389
workflow: {
427390
edges: [],
428391
nodes: [
429392
{
430393
x: 480,
431-
y: 3340,
394+
y: 200,
432395
id: 'loop-start-node',
433396
type: 'loop-start-node',
434-
properties: { config: { fields: [], globalFields: [] }, fields: [], height: 361.333, showNode: true, stepName: '开始', globalFields: [] },
397+
properties: { config: { fields: [], globalFields: [] }, fields: [], showNode: true, stepName: '开始', globalFields: [] },
435398
},
436399
],
437400
},
438401
config: { fields: [] },
439402
},
440403
}
441404

405+
export const loopStartNode = {
406+
id: WorkflowNodeType.LoopStartNode,
407+
type: WorkflowNodeType.LoopStartNode,
408+
x: 480,
409+
y: 200,
410+
properties: {
411+
stepName: '循环开始',
412+
config: {
413+
fields: [
414+
{ label: '下标', value: 'index' },
415+
{ label: '循环元素', value: 'item' },
416+
],
417+
globalFields: [],
418+
},
419+
showNode: true,
420+
},
421+
}
422+
442423
export const loopBodyNode = {
443424
type: WorkflowNodeType.LoopBodyNode,
444425
text: '循环体',
445426
label: '循环体',
446427
height: 1080,
428+
447429
properties: { width: 1920, stepName: '循环体', config: { fields: [] } },
448430
}
449431

450432
export const loopContinueNode = {
451433
type: WorkflowNodeType.LoopContinueNode,
452434
text: '用于终止当前循环,执行下次循环',
453435
label: 'Continue',
454-
height: 100,
455436
properties: { width: 600, stepName: 'Continue', config: { fields: [] } },
456437
}
457438

458439
export const loopBreakNode = {
459440
type: WorkflowNodeType.LoopBreakNode,
460441
text: '终止当前循环,跳出循环体',
461442
label: 'Break',
462-
height: 100,
463443
properties: { width: 600, stepName: 'Break', config: { fields: [] } },
464444
}
465445

446+
/**
447+
* 工作流工具配置数据
448+
*/
449+
export const toolWorkflowLibNode = {
450+
type: WorkflowNodeType.ToolWorkflowLib,
451+
text: '工作流工具',
452+
label: '工作流工具',
453+
properties: { stepName: '工作流工具', config: { fields: [] } },
454+
}
455+
466456
/* 文档分段 */
467457
export const documentSplitNode = {
468458
type: WorkflowNodeType.DocumentSplitNode,

‎ui/src/workflow-canvas/core/node-container/index.vue‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,16 +273,16 @@ onBeforeUnmount(() => {
273273
>
274274
<div>
275275
<div class="flex-between">
276-
<div class="flex items-center" @dragstart.prevent @drag.prevent @dragover.prevent @dragend.prevent>
277-
<component :is="iconComponent(`${model.type}-icon`)" class="mr-2" :size="24" :item="model?.properties.node_data" />
276+
<div class="flex min-w-0 flex-1 items-center" @dragstart.prevent @drag.prevent @dragover.prevent @dragend.prevent>
277+
<component :is="iconComponent(`${model.type}-icon`)" class="mr-2 shrink-0" :size="24" :item="model?.properties.node_data" />
278278
<h4
279-
class="truncate break-all"
279+
class="truncate"
280280
:title="String(model.properties.stepName ?? '')"
281281
v-html="highlightedStepName(String(model.properties.stepName ?? ''))"
282282
></h4>
283283
</div>
284284

285-
<div class="flex items-center gap-1" @pointerdown.stop @mousemove.stop @mousedown.stop @keydown.stop @click.stop>
285+
<div class="flex shrink-0 items-center gap-1" @pointerdown.stop @mousemove.stop @mousedown.stop @keydown.stop @click.stop>
286286
<el-button text @click="showNode = !showNode">
287287
<MkIcon name="icon_down_outlined" />
288288
</el-button>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<script setup lang="ts">
2+
import type { ToolType } from '@/api/types'
3+
4+
const props = defineProps<{
5+
item?: {
6+
name: string
7+
icon: string
8+
tool_type: ToolType
9+
kind?: string
10+
}
11+
size?: string | number
12+
}>()
13+
</script>
14+
15+
<template>
16+
<ToolIcon v-if="item?.kind !== 'data-source'" :icon="props.item?.icon" :type="props.item?.tool_type" />
17+
<el-avatar v-else-if="item?.kind === 'data-source'" class="bg-purple!" shape="square">
18+
<img src="@/assets/tool/icon_datasource.svg" style="width: 58%" alt="" />
19+
</el-avatar>
20+
<el-avatar v-else class="bg-success!" shape="square" :size="size">
21+
<img style="width: 63%" src="@/assets/tool/icon_tool.svg" alt="" />
22+
</el-avatar>
23+
</template>

‎ui/src/workflow-canvas/nodes/loop-body-node/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class LoopBodyModel extends WorkflowNodeModel {
88
loopLayout?: () => void
99

1010
getDefaultAnchor(): Model.AnchorConfig[] {
11-
return [{ x: this.x, y: this.y - this.height / 2 + 10, id: `${this.id}_children`, type: 'children', edgeAddable: false }]
11+
return [{ x: this.x, y: this.y - this.height / 2, id: `${this.id}_children`, type: 'children', edgeAddable: false }]
1212
}
1313

1414
refreshBranch() {

‎ui/src/workflow-canvas/nodes/loop-node/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Model } from '@logicflow/core'
77
class LoopNodeModel extends WorkflowNodeModel {
88
getDefaultAnchor(): Model.AnchorConfig[] {
99
const anchors = super.getDefaultAnchor()
10-
anchors.push({ x: this.x, y: this.y + this.height / 2 - 25, id: `${this.id}_children`, type: 'children', edgeAddable: false })
10+
anchors.push({ x: this.x, y: this.y + this.height / 2, id: `${this.id}_children`, type: 'children', edgeAddable: false })
1111
return anchors
1212
}
1313

‎ui/src/workflow-canvas/nodes/loop-node/index.vue‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function mountLoopBodyNode() {
103103
edges: [],
104104
}
105105
let x = model.x
106-
let y = model.y + 350
106+
let y = model.y + 850
107107
if (nodeData?.loop_body) workflow = nodeData.loop_body
108108
if (nodeData?.loop) {
109109
x = nodeData.loop.x

‎ui/src/workflow-canvas/nodes/tool-lib-node/index.vue‎

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -104,36 +104,38 @@ onMounted(() => {
104104

105105
<div class="mk-gray-card">
106106
<el-form ref="formRef" :model="formData" label-position="top" hide-required-asterisk @submit.prevent>
107+
<!-- 输入参数 -->
107108
<h6 class="mb-2">输入参数</h6>
108109
<template v-if="formData.input_field_list.length">
109-
<el-form-item
110-
v-for="(field, index) in formData.input_field_list"
111-
:key="`${field.name}-${index}`"
112-
:prop="`input_field_list.${index}.value`"
113-
:rules="{
114-
required: field.is_required,
115-
message: field.source === 'reference' ? '请选择参数' : '请输入参数',
116-
trigger: field.source === 'reference' ? 'change' : 'blur',
117-
}"
118-
>
119-
<template #label>
120-
<div class="flex w-full items-center gap-1">
121-
<span class="max-w-40 truncate" :class="{ 'mk-required': field.is_required }" :title="field.name">{{ field.name }}</span>
122-
<el-tooltip v-if="field.desc" :content="field.desc" effect="dark" placement="right">
123-
<MkIcon name="icon_info_outlined" class="text-N600!" />
124-
</el-tooltip>
125-
<el-tag size="small" type="info">{{ field.type }}</el-tag>
126-
</div>
127-
</template>
128-
129-
<NodeCascader v-if="field.source === 'reference'" v-model="field.value" :node-model="model" placeholder="请选择参数" />
130-
<el-input v-else v-model="field.value" placeholder="请输入参数" />
131-
</el-form-item>
110+
<div class="mk-white-card">
111+
<el-form-item
112+
v-for="(field, index) in formData.input_field_list"
113+
:key="`${field.name}-${index}`"
114+
:prop="`input_field_list.${index}.value`"
115+
:rules="{
116+
required: field.is_required,
117+
message: field.source === 'reference' ? '请选择参数' : '请输入参数',
118+
trigger: field.source === 'reference' ? 'change' : 'blur',
119+
}"
120+
>
121+
<template #label>
122+
<div class="flex w-full items-center gap-1">
123+
<span class="max-w-40 truncate" :class="{ 'mk-required': field.is_required }" :title="field.name">{{ field.name }}</span>
124+
<el-tooltip v-if="field.desc" :content="field.desc" effect="dark" placement="right">
125+
<MkIcon name="icon_info_outlined" class="text-N600!" />
126+
</el-tooltip>
127+
<el-tag size="small" type="info">{{ field.type }}</el-tag>
128+
</div>
129+
</template>
130+
131+
<NodeCascader v-if="field.source === 'reference'" v-model="field.value" :node-model="model" placeholder="请选择参数" />
132+
<el-input v-else v-model="field.value" placeholder="请输入参数" />
133+
</el-form-item>
134+
</div>
132135
</template>
133-
<MkEmpty v-else :image-size="60" class="mb-4" />
134136

135137
<!-- 返回内容 -->
136-
<div v-if="showReturnContent" class="flex-between w-full">
138+
<div v-if="showReturnContent" class="flex-between w-full mt-4">
137139
<span class="flex items-center gap-1">
138140
返回内容
139141
<el-tooltip content="关闭后该节点的内容则不输出给用户。如果你想让用户看到该节点的输出内容,请打开开关。" placement="right">

0 commit comments

Comments
 (0)