diff --git a/ui/src/workflow/common/NodeCascader.vue b/ui/src/workflow/common/NodeCascader.vue index d933f3fff..3613acc9b 100644 --- a/ui/src/workflow/common/NodeCascader.vue +++ b/ui/src/workflow/common/NodeCascader.vue @@ -43,8 +43,9 @@ function visibleChange(bool: boolean) { } } -function getIncomingNode(id: string) { - const list = props.nodeModel.graphModel.getNodeIncomingNode(id) +function _getIncomingNode(id: String, startId: String) { + let list = props.nodeModel.graphModel.getNodeIncomingNode(id) + list = list.filter((item: any) => item.id !== startId) let firstElement = null if (list.length > 0) { list.forEach((item: any) => { @@ -67,13 +68,16 @@ function getIncomingNode(id: string) { }) list.forEach((item: any) => { - getIncomingNode(item.id) + _getIncomingNode(item.id, startId) }) } if (firstElement) { options.value.unshift(firstElement) } } +function getIncomingNode(id: string) { + _getIncomingNode(id, id) +} const validate = () => { getIncomingNode(props.nodeModel.id) if (!data.value) { diff --git a/ui/src/workflow/common/NodeContainer.vue b/ui/src/workflow/common/NodeContainer.vue index 74f5e64ac..1cba03c3c 100644 --- a/ui/src/workflow/common/NodeContainer.vue +++ b/ui/src/workflow/common/NodeContainer.vue @@ -99,10 +99,10 @@ function editName(val: string) { } } const mousedown = () => { - props.nodeModel.graphModel.toFront(props.nodeModel.id) props.nodeModel.graphModel.clearSelectElements() props.nodeModel.isSelected = true props.nodeModel.isHovered = true + props.nodeModel.graphModel.toFront(props.nodeModel.id) } const showicon = ref(null) const copyNode = () => { diff --git a/ui/src/workflow/common/validate.ts b/ui/src/workflow/common/validate.ts index 0bddef1c3..192aa3db7 100644 --- a/ui/src/workflow/common/validate.ts +++ b/ui/src/workflow/common/validate.ts @@ -4,9 +4,11 @@ const end_nodes = [WorkflowType.AiChat, WorkflowType.Reply] export class WorkFlowInstance { nodes edges + workFlowNodes: Array constructor(workflow: { nodes: Array; edges: Array }) { this.nodes = workflow.nodes this.edges = workflow.edges + this.workFlowNodes = [] } /** * 校验开始节点 @@ -61,16 +63,28 @@ export class WorkFlowInstance { * 校验工作流 * @param up_node 上一个节点 */ - private is_valid_work_flow(up_node?: any) { + private _is_valid_work_flow(up_node?: any) { if (!up_node) { up_node = this.get_start_node() } + this.workFlowNodes.push(up_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) + this._is_valid_work_flow(next_node) } } + private is_valid_work_flow() { + this.workFlowNodes = [] + this._is_valid_work_flow() + const notInWorkFlowNodes = this.nodes + .filter((node: any) => node.id !== WorkflowType.Start && node.id !== WorkflowType.Base) + .filter((node) => !this.workFlowNodes.includes(node)) + if (notInWorkFlowNodes.length > 0) { + throw `未在流程中的节点:${notInWorkFlowNodes.map((node) => node.properties.stepName).join(',')}` + } + this.workFlowNodes = [] + } /** * 获取流程下一个节点列表 * @param node 节点