Skip to content

Commit 2db8f84

Browse files
committed
fix: Loop validation and other bugs
1 parent 3fad820 commit 2db8f84

File tree

6 files changed

+67
-6
lines changed

6 files changed

+67
-6
lines changed

ui/src/locales/lang/en-US/views/application-workflow.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export default {
7575
nodeUnavailable: 'Node unavailable',
7676
needConnect1: 'The branch of the node needs to be connected',
7777
cannotEndNode: 'This node cannot be used as an end node',
78+
loopNodeBreakNodeRequired: 'Wireless loop must have a Break node',
7879
},
7980
nodes: {
8081
classify: {

ui/src/locales/lang/zh-CN/views/application-workflow.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export default {
7878
needConnect1: '节点的',
7979
needConnect2: '分支需要连接',
8080
cannotEndNode: '节点不能当做结束节点',
81+
loopNodeBreakNodeRequired: '无线循环 必须存在 Break 节点',
8182
},
8283
nodes: {
8384
classify: {

ui/src/locales/lang/zh-Hant/views/application-workflow.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export default {
7676
needConnect1: '節點的',
7777
needConnect2: '分支需要連接',
7878
cannotEndNode: '節點不能當做結束節點',
79+
loopNodeBreakNodeRequired: '無線迴圈必須存在Break節點',
7980
},
8081
nodes: {
8182
classify: {

ui/src/workflow/common/validate.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const end_nodes: Array<string> = [
1515
WorkflowType.TextToVideoGenerateNode,
1616
WorkflowType.ImageGenerateNode,
1717
WorkflowType.LoopBodyNode,
18+
WorkflowType.LoopNode,
19+
WorkflowType.LoopBreakNode,
1820
]
1921
export class WorkFlowInstance {
2022
nodes
@@ -29,7 +31,9 @@ export class WorkFlowInstance {
2931
* 校验开始节点
3032
*/
3133
private is_valid_start_node() {
32-
const start_node_list = this.nodes.filter((item) => item.id === WorkflowType.Start)
34+
const start_node_list = this.nodes.filter((item) =>
35+
[WorkflowType.Start, WorkflowType.LoopStartNode].includes(item.id),
36+
)
3337
if (start_node_list.length == 0) {
3438
throw t('views.applicationWorkflow.validate.startNodeRequired')
3539
} else if (start_node_list.length > 1) {
@@ -57,12 +61,20 @@ export class WorkFlowInstance {
5761
this.is_valid_nodes()
5862
}
5963

64+
is_loop_valid() {
65+
this.is_valid_start_node()
66+
this.is_valid_work_flow()
67+
this.is_valid_nodes()
68+
}
69+
6070
/**
6171
* 获取开始节点
6272
* @returns
6373
*/
6474
get_start_node() {
65-
const start_node_list = this.nodes.filter((item) => item.id === WorkflowType.Start)
75+
const start_node_list = this.nodes.filter((item) =>
76+
[WorkflowType.Start, WorkflowType.LoopStartNode].includes(item.id),
77+
)
6678
return start_node_list[0]
6779
}
6880
/**
@@ -73,7 +85,9 @@ export class WorkFlowInstance {
7385
const base_node_list = this.nodes.filter((item) => item.id === WorkflowType.Base)
7486
return base_node_list[0]
7587
}
76-
88+
extis_break_node() {
89+
return this.nodes.some((item) => item.id === WorkflowType.LoopBreakNode)
90+
}
7791
/**
7892
* 校验工作流
7993
* @param up_node 上一个节点
@@ -117,7 +131,11 @@ export class WorkFlowInstance {
117131
}
118132
private is_valid_nodes() {
119133
for (const node of this.nodes) {
120-
if (node.type !== WorkflowType.Base && node.type !== WorkflowType.Start) {
134+
if (
135+
node.type !== WorkflowType.Base &&
136+
node.type !== WorkflowType.Start &&
137+
node.type !== WorkflowType.LoopStartNode
138+
) {
121139
if (!this.edges.some((edge) => edge.targetNodeId === node.id)) {
122140
throw `${t('views.applicationWorkflow.validate.notInWorkFlowNode')}:${node.properties.stepName}`
123141
}

ui/src/workflow/nodes/loop-body-node/index.vue

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,51 @@ import Dagre from '@/workflow/plugins/dagre'
1212
import { initDefaultShortcut } from '@/workflow/common/shortcut'
1313
import LoopBodyContainer from '@/workflow/nodes/loop-body-node/LoopBodyContainer.vue'
1414
import { WorkflowMode } from '@/enums/application'
15+
import { WorkFlowInstance } from '@/workflow/common/validate'
16+
import { t } from '@/locales'
1517
const nodes: any = import.meta.glob('@/workflow/nodes/**/index.ts', { eager: true })
1618
const props = defineProps<{ nodeModel: any }>()
1719
const containerRef = ref()
1820
1921
const validate = () => {
22+
const workflow = new WorkFlowInstance(lf.value.getGraphData())
2023
return Promise.all(lf.value.graphModel.nodes.map((element: any) => element?.validate?.()))
24+
.then(() => {
25+
const loop_node_id = props.nodeModel.properties.loop_node_id
26+
const loop_node = props.nodeModel.graphModel.getNodeModelById(loop_node_id)
27+
try {
28+
workflow.is_loop_valid()
29+
if (loop_node.properties.node_data.loop_type == 'LOOP' && !workflow.extis_break_node()) {
30+
return Promise.reject({
31+
node: loop_node,
32+
errMessage: t('views.applicationWorkflow.validate.loopNodeBreakNodeRequired'),
33+
})
34+
}
35+
36+
return Promise.resolve({})
37+
} catch (e) {
38+
return Promise.reject({ node: loop_node, errMessage: e })
39+
}
40+
})
41+
.catch((e) => {
42+
props.nodeModel.graphModel.selectNodeById(props.nodeModel.id)
43+
props.nodeModel.graphModel.transformModel.focusOn(
44+
props.nodeModel.x,
45+
props.nodeModel.y,
46+
props.nodeModel.width,
47+
props.nodeModel.height,
48+
)
49+
throw e
50+
})
2151
}
2252
const set_loop_body = () => {
2353
const loop_node_id = props.nodeModel.properties.loop_node_id
2454
const loop_node = props.nodeModel.graphModel.getNodeModelById(loop_node_id)
2555
loop_node.properties.node_data.loop_body = lf.value.getGraphData()
56+
loop_node.properties.node_data.loop = {
57+
x: props.nodeModel.x,
58+
y: props.nodeModel.y,
59+
}
2660
}
2761
2862
const refresh_loop_fields = (fields: Array<any>) => {

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,24 @@ onMounted(() => {
120120
const nodeOutgoingNode = props.nodeModel.graphModel.getNodeOutgoingNode(props.nodeModel.id)
121121
if (!nodeOutgoingNode.some((item: any) => item.type == loopBodyNode.type)) {
122122
let workflow = { nodes: [loopStartNode], edges: [] }
123+
let x = props.nodeModel.x
124+
let y = props.nodeModel.y + 200
123125
if (props.nodeModel.properties.node_data.loop_body) {
124126
workflow = props.nodeModel.properties.node_data.loop_body
125127
}
128+
if (props.nodeModel.properties.node_data.loop) {
129+
x = props.nodeModel.properties.node_data.loop.x
130+
y = props.nodeModel.properties.node_data.loop.y
131+
}
126132
const nodeModel = props.nodeModel.graphModel.addNode({
127133
type: loopBodyNode.type,
128134
properties: {
129135
...loopBodyNode.properties,
130136
workflow: workflow,
131137
loop_node_id: props.nodeModel.id,
132138
},
133-
x: props.nodeModel.x,
134-
y: props.nodeModel.y + loopBodyNode.height,
139+
x: x,
140+
y: y,
135141
})
136142
props.nodeModel.graphModel.addEdge({
137143
type: 'loop-edge',

0 commit comments

Comments
 (0)