feat: 前端节点校验
Some checks are pending
sync2gitee / repo-sync (push) Waiting to run
Typos Check / Spell Check with Typos (push) Waiting to run

This commit is contained in:
shaohuzhang1 2024-06-20 19:27:25 +08:00
parent 5de4065648
commit 0eea4a726e
2 changed files with 135 additions and 3 deletions

View File

@ -12,7 +12,7 @@
<el-button icon="Plus" @click="showPopover = !showPopover" v-click-outside="clickoutside">
添加组件
</el-button>
<el-button @click="showDebug = true" :disabled="showDebug">
<el-button @click="clickShowDebug" :disabled="showDebug">
<AppIcon iconName="app-play-outlined" class="mr-4"></AppIcon>
调试</el-button
>
@ -80,9 +80,10 @@ import Workflow from '@/workflow/index.vue'
import { menuNodes } from '@/workflow/common/data'
import { iconComponent } from '@/workflow/icons/utils'
import applicationApi from '@/api/application'
import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
import { datetimeFormat } from '@/utils/time'
import useStore from '@/stores'
import { WorkFlow } from '@/workflow/common/validate'
const { application } = useStore()
const route = useRoute()
@ -116,7 +117,16 @@ function publicHandle() {
function clickoutside() {
showPopover.value = false
}
const clickShowDebug = () => {
const graphData = getGraphData()
const workflow = new WorkFlow(graphData)
try {
workflow.is_valid()
showDebug.value = true
} catch (e: any) {
MsgError(e.toString())
}
}
function clickoutsideDebug() {
showDebug.value = false
}

View File

@ -0,0 +1,122 @@
const end_nodes = ['ai-chat-node', 'reply-node']
export class WorkFlow {
nodes
edges
constructor(workflow: { nodes: Array<any>; edges: Array<any> }) {
this.nodes = workflow.nodes
this.edges = workflow.edges
}
/**
*
*/
private is_valid_start_node() {
const start_node_list = this.nodes.filter((item) => item.id === 'start-node')
if (start_node_list.length == 0) {
throw '开始节点必填'
} else if (start_node_list.length > 1) {
throw '开始节点只能有一个'
}
}
/**
*
*/
private is_valid_base_node() {
const start_node_list = this.nodes.filter((item) => item.id === 'base-node')
if (start_node_list.length == 0) {
throw '基本信息节点必填'
} else if (start_node_list.length > 1) {
throw '基本信息节点只能有一个'
}
}
/**
*
*/
is_valid() {
this.is_valid_start_node()
this.is_valid_base_node()
this.is_valid_work_flow()
this.is_valid_nodes()
}
/**
*
* @returns
*/
get_start_node() {
const start_node_list = this.nodes.filter((item) => item.id === 'start-node')
return start_node_list[0]
}
/**
*
* @returns
*/
get_base_node() {
const base_node_list = this.nodes.filter((item) => item.id === 'base-node')
return base_node_list[0]
}
/**
*
* @param up_node
*/
private is_valid_work_flow(up_node?: any) {
if (!up_node) {
up_node = this.get_start_node()
}
this.is_valid_node(up_node)
const next_nodes = this.get_next_nodes(up_node)
for (const next_node of next_nodes) {
this.is_valid_work_flow(next_node)
}
}
/**
*
* @param node
* @returns
*/
private get_next_nodes(node: any) {
const edge_list = this.edges.filter((edge) => edge.sourceNodeId == node.id)
const node_list = edge_list
.map((edge) => this.nodes.filter((node) => node.id == edge.targetNodeId))
.reduce((x, y) => [...x, ...y], [])
if (node_list.length == 0 && !end_nodes.includes(node.type)) {
throw '不存在的下一个节点'
}
return node_list
}
private is_valid_nodes() {
for (const node of this.nodes) {
if (node.type !== 'base-node' && node.type !== 'start-node') {
console.log(node.properties.stepName)
if (!this.edges.some((edge) => edge.targetNodeId === node.id)) {
throw `未在流程中的节点:${node.properties.stepName}`
}
}
}
}
/**
*
* @param node
*/
private is_valid_node(node: any) {
if (node.type === 'condition-node') {
const branch_list = node.properties.node_data.branch
for (const branch of branch_list) {
const source_anchor_id = `${node.id}_${branch.id}_right`
const edge_list = this.edges.filter((edge) => edge.sourceAnchorId == source_anchor_id)
if (edge_list.length == 0) {
throw `${node.properties.stepName} 节点的${branch.type}分支需要连接`
} else if (edge_list.length > 1) {
throw `${node.properties.stepName} 节点的${branch.type}分支不能连接俩个节点`
}
}
} else {
const edge_list = this.edges.filter((edge) => edge.sourceNodeId == node.id)
if (edge_list.length == 0 && !end_nodes.includes(node.type)) {
throw `${node.properties.stepName} 节点不能当做结束节点`
} else if (edge_list.length > 1) {
throw `${node.properties.stepName} 节点不能连接俩个节点`
}
}
}
}