From 262189c54f0c6000764f7da23449a461494a03df Mon Sep 17 00:00:00 2001 From: zxhlyh Date: Wed, 17 Sep 2025 13:47:11 +0800 Subject: [PATCH] fix: checklist before publish --- .../workflow/hooks/use-checklist.ts | 30 ++++++++++-- .../hooks/use-nodes-available-var-list.ts | 49 +++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/web/app/components/workflow/hooks/use-checklist.ts b/web/app/components/workflow/hooks/use-checklist.ts index 167b8936c7..8a29551b89 100644 --- a/web/app/components/workflow/hooks/use-checklist.ts +++ b/web/app/components/workflow/hooks/use-checklist.ts @@ -40,7 +40,7 @@ import type { KnowledgeRetrievalNodeType } from '../nodes/knowledge-retrieval/ty import type { DataSet } from '@/models/datasets' import { fetchDatasets } from '@/service/datasets' import { MAX_TREE_DEPTH } from '@/config' -import useNodesAvailableVarList from './use-nodes-available-var-list' +import useNodesAvailableVarList, { useGetNodesAvailableVarList } from './use-nodes-available-var-list' import { getNodeUsedVars, isSpecialVar } from '../nodes/_base/components/variable/utils' export const useChecklist = (nodes: Node[], edges: Edge[]) => { @@ -179,6 +179,7 @@ export const useChecklistBeforePublish = () => { const updateTime = useRef(0) const { getStartNodes } = useWorkflow() const workflowStore = useWorkflowStore() + const { getNodesAvailableVarList } = useGetNodesAvailableVarList() const getCheckData = useCallback((data: CommonNodeType<{}>, datasets: DataSet[]) => { let checkData = data @@ -247,10 +248,11 @@ export const useChecklistBeforePublish = () => { updateDatasetsDetail(datasetsDetail) } } - + const map = getNodesAvailableVarList(nodes) for (let i = 0; i < filteredNodes.length; i++) { const node = filteredNodes[i] let moreDataForCheckValid + let usedVars: ValueSelector[] = [] if (node.data.type === BlockEnum.Tool) moreDataForCheckValid = getToolCheckParams(node.data as ToolNodeType, buildInTools, customTools, workflowTools, language) @@ -269,7 +271,9 @@ export const useChecklistBeforePublish = () => { isReadyForCheckValid, } } - + else { + usedVars = getNodeUsedVars(node).filter(v => v.length > 0) + } const checkData = getCheckData(node.data, datasets) const { errorMessage } = nodesExtraData![node.data.type as BlockEnum].checkValid(checkData, t, moreDataForCheckValid) @@ -278,6 +282,26 @@ export const useChecklistBeforePublish = () => { return false } + const availableVars = map[node.id].availableVars + + for (const variable of usedVars) { + const isSpecialVars = isSpecialVar(variable[0]) + if (!isSpecialVars) { + const usedNode = availableVars.find(v => v.nodeId === variable?.[0]) + if (usedNode) { + const usedVar = usedNode.vars.find(v => v.variable === variable?.[1]) + if (!usedVar) { + notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.errorMsg.invalidVariable')}` }) + return false + } + } + else { + notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.errorMsg.invalidVariable')}` }) + return false + } + } + } + if (!validNodes.find(n => n.id === node.id)) { notify({ type: 'error', message: `[${node.data.title}] ${t('workflow.common.needConnectTip')}` }) return false diff --git a/web/app/components/workflow/hooks/use-nodes-available-var-list.ts b/web/app/components/workflow/hooks/use-nodes-available-var-list.ts index e6df546890..b78597ea37 100644 --- a/web/app/components/workflow/hooks/use-nodes-available-var-list.ts +++ b/web/app/components/workflow/hooks/use-nodes-available-var-list.ts @@ -1,3 +1,4 @@ +import { useCallback } from 'react' import { useIsChatMode, useWorkflow, @@ -72,4 +73,52 @@ const useNodesAvailableVarList = (nodes: Node[], { return nodeAvailabilityMap } +export const useGetNodesAvailableVarList = () => { + const { getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent } = useWorkflow() + const { getNodeAvailableVars } = useWorkflowVariables() + const isChatMode = useIsChatMode() + const getNodesAvailableVarList = useCallback((nodes: Node[], { + onlyLeafNodeVar, + filterVar, + hideEnv, + hideChatVar, + passedInAvailableNodes, + }: Params = { + onlyLeafNodeVar: false, + filterVar: () => true, + }) => { + const nodeAvailabilityMap: { [key: string ]: { availableVars: NodeOutPutVar[], availableNodes: Node[] } } = {} + + nodes.forEach((node) => { + const nodeId = node.id + const availableNodes = passedInAvailableNodes || (onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranchIncludeParent(nodeId)) + if (node.data.type === BlockEnum.Loop) + availableNodes.push(node) + + const { + parentNode: iterationNode, + } = getNodeInfo(nodeId, nodes) + + const availableVars = getNodeAvailableVars({ + parentNode: iterationNode, + beforeNodes: availableNodes, + isChatMode, + filterVar, + hideEnv, + hideChatVar, + }) + const result = { + node, + availableVars, + availableNodes, + } + nodeAvailabilityMap[nodeId] = result + }) + return nodeAvailabilityMap + }, [getTreeLeafNodes, getBeforeNodesInSameBranchIncludeParent, getNodeAvailableVars, isChatMode]) + return { + getNodesAvailableVarList, + } +} + export default useNodesAvailableVarList