From e759ecdb92bfb3de707fb6452d80d71174b7c1c5 Mon Sep 17 00:00:00 2001 From: Ethan-Zhang Date: Mon, 20 Oct 2025 20:14:52 +0800 Subject: [PATCH 1/2] =?UTF-8?q?Fix:=20=E6=8F=92=E4=BB=B6=E7=B1=BB=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/conversation.ts | 20 +- src/views/chat/index.vue | 12 +- src/views/createapp/components/workFlow.vue | 320 ++++++++++++++---- .../workFlowConfig/PluginListPanel.vue | 8 +- .../components/workFlowConfig/PluginNode.vue | 16 +- .../components/workFlowConfig/useDnD.js | 32 +- src/views/dialogue/dialogueView.vue | 2 +- 7 files changed, 320 insertions(+), 90 deletions(-) diff --git a/src/store/conversation.ts b/src/store/conversation.ts index 5eb34263..a28a27e6 100644 --- a/src/store/conversation.ts +++ b/src/store/conversation.ts @@ -66,7 +66,7 @@ export const useSessionStore = defineStore('conversation', () => { // ai回复是否还在生成中 const isAnswerGenerating = ref(false); - const currentTaskId = ref(null); + const currentTaskId = ref(null); // 方法集合 - 用于处理不同类型的event message const dataTransfers = { @@ -181,7 +181,7 @@ export const useSessionStore = defineStore('conversation', () => { progress: messageFlow.stepProgress, status: currentTaskId.value ? messageFlow.flowStatus : 'success', display: true, - taskId: currentTaskId.value, + taskId: currentTaskId.value || undefined, data: conversationItem.flowdata.data, }; } else { @@ -220,7 +220,9 @@ export const useSessionStore = defineStore('conversation', () => { id: flow.stepId, title: flow.stepName, status: flow.stepStatus, - taskId: currentTaskId, + taskId: currentTaskId.value || undefined, + display: true, + progress: flow.stepProgress || '', data: { exData: content, }, @@ -240,7 +242,9 @@ export const useSessionStore = defineStore('conversation', () => { id: flow.stepId, title: flow.stepName, status: flow.stepStatus, - taskId: currentTaskId, + taskId: currentTaskId.value || undefined, + display: true, + progress: flow.stepProgress || '', data: { exParam: content, }, @@ -315,7 +319,6 @@ export const useSessionStore = defineStore('conversation', () => { if ('metadata' in message) { conversationItem.metadata = message.metadata; } - currentTaskId.value = message.taskId; if ('event' in message) { switch (eventType) { case 'text.add': @@ -335,7 +338,8 @@ export const useSessionStore = defineStore('conversation', () => { dataTransfers.suggestionFunc(conversationItem, message); break; case 'init': - //初始化获取 metadata + //初始化获取 metadata 和 taskId + currentTaskId.value = message.taskId || message.id; conversationItem.metadata = message.metadata; conversationItem.createdAt = message.content.createdAt; conversationItem.groupId = message.groupId; @@ -738,7 +742,7 @@ export const useSessionStore = defineStore('conversation', () => { targetItem.message[0] += '暂停生成'; targetItem.isFinish = true; cancel(); - const resp = await api.stopGeneration(currentMessage.value.taskId); + const resp = await api.stopGeneration(currentTaskId.value || ''); if (resp?.[1]?.code === 200) { isAnswerGenerating.value = false; } @@ -930,7 +934,7 @@ export const useSessionStore = defineStore('conversation', () => { ] as RobotConversationItem ).isFinish = true; cancel(); - const resp = await api.stopGeneration(currentMessage.value.taskId); + const resp = await api.stopGeneration(currentTaskId.value || ''); if (resp?.[1]?.code === 200) { isAnswerGenerating.value = false; } diff --git a/src/views/chat/index.vue b/src/views/chat/index.vue index 791a51e9..896642bb 100644 --- a/src/views/chat/index.vue +++ b/src/views/chat/index.vue @@ -154,7 +154,7 @@ function useStream() { // 2. 然后调用后端停止接口,清理后端连接 try { - const [, res] = await api.stopGeneration() + const [, res] = await api.stopGeneration('') if (res && res.code === 200) { // 后端停止成功 } @@ -250,14 +250,16 @@ async function onSend(q: string) { }; const conversationId = localStorage.getItem('conversationId') || ''; if (!conversationId) { - await api.createSession(p).then((res) => { - localStorage.setItem('conversationId', res[1].result.conversationId); + const res = await api.createSession(p); + if (res?.[1]?.result?.conversationId) { + const newConversationId = res[1].result.conversationId; + localStorage.setItem('conversationId', newConversationId); queryStream( q, - res[1].result.conversationId, + newConversationId, language.value as 'zh' | 'en', ); - }); + } } else { queryStream(q, conversationId, language.value as 'zh' | 'en'); } diff --git a/src/views/createapp/components/workFlow.vue b/src/views/createapp/components/workFlow.vue index 2031780f..cc614fc0 100644 --- a/src/views/createapp/components/workFlow.vue +++ b/src/views/createapp/components/workFlow.vue @@ -354,51 +354,62 @@ const loadConversationVariablesForDisplay = async () => { // 验证节点是否都连接 const nodeAndLineConnection = () => { - // 获取当前所有节点和边,过滤掉Comment节点 - const curNodes = [...getNodes.value].filter(node => node.type !== 'comment' && !node.data?.isComment); - const curEdges = [...getEdges.value]; + // 安全地获取当前所有节点和边,过滤掉Comment节点 + const nodesArray = getNodes.value || []; + const edgesArray = getEdges.value || []; - // 如果没有节点,认为是连接的 - if (curNodes.length === 0) { - isNodeAndLineConnect.value = true; - return; - } + try { + const curNodes = [...nodesArray].filter(node => node.type !== 'comment' && !node.data?.isComment); + const curEdges = [...edgesArray]; - // 遍历每个节点,检查连接状态 - for (let i = 0; i < curNodes.length; i++) { - const currentNode = curNodes[i]; - let isCurrentNodeConnected = false; - - if (currentNode.type === 'start') { - // 判断当前开始节点是否有出边连接 - isCurrentNodeConnected = curEdges.some( - (edge) => edge.source === currentNode.id, - ); - } else if (currentNode.type === 'end') { - // 判断当前结束节点是否有入边连接 - isCurrentNodeConnected = curEdges.some( - (edge) => edge.target === currentNode.id, - ); - } else { - // 判断普通节点是否有连接-普通节点开始和结束都需要进行判断 - const hasOutgoingEdge = curEdges.some( - (edge) => edge.source === currentNode.id, - ); - const hasIncomingEdge = curEdges.some( - (edge) => edge.target === currentNode.id, - ); - isCurrentNodeConnected = hasOutgoingEdge && hasIncomingEdge; + // 如果没有节点,认为是连接的 + if (curNodes.length === 0) { + isNodeAndLineConnect.value = true; + return; } - // 如果当前节点未连接,立即设置为false并退出 - if (!isCurrentNodeConnected) { - isNodeAndLineConnect.value = false; - return; + // 遍历每个节点,检查连接状态 + for (let i = 0; i < curNodes.length; i++) { + const currentNode = curNodes[i]; + let isCurrentNodeConnected = false; + + if (currentNode.type === 'start') { + // 判断当前开始节点是否有出边连接 + isCurrentNodeConnected = curEdges.some( + (edge) => edge.source === currentNode.id, + ); + } else if (currentNode.type === 'end') { + // 判断当前结束节点是否有入边连接 + isCurrentNodeConnected = curEdges.some( + (edge) => edge.target === currentNode.id, + ); + } else { + // 判断普通节点是否有连接-普通节点开始和结束都需要进行判断 + const hasOutgoingEdge = curEdges.some( + (edge) => edge.source === currentNode.id, + ); + const hasIncomingEdge = curEdges.some( + (edge) => edge.target === currentNode.id, + ); + isCurrentNodeConnected = hasOutgoingEdge && hasIncomingEdge; + } + + // 如果当前节点未连接,立即设置为false并退出 + if (!isCurrentNodeConnected) { + isNodeAndLineConnect.value = false; + return; + } } + + // 所有节点都已连接 + isNodeAndLineConnect.value = true; + + } catch (error: any) { + console.error('nodeAndLineConnection执行失败:', error); + // 发生错误时,设置为未连接状态 + isNodeAndLineConnect.value = false; + throw error; } - - // 所有节点都已连接 - isNodeAndLineConnect.value = true; }; const editCommonDrawer = (name, desc, nodeId, yamlCode) => { @@ -517,7 +528,7 @@ const editYamlDrawer = (name, desc, yamlCode, nodeId) => { nodeYamlId.value = nodeId; selectedNodeId.value = nodeId; isEditFileExtractorNode.value = true; - } else if (currentNode && currentNode.type === 'plugin-node') { + } else if (currentNode && (currentNode.type === 'plugin-node' || currentNode.data.callId === 'Plugin')) { // 显示插件详情,不是编辑 showPluginDetails(currentNode.data); } else if (currentNode && currentNode.data.callId === 'Loop') { @@ -1056,6 +1067,17 @@ const editSubFlowNode = (nodeName, nodeDesc, nodeParameters, nodeId, loopNodeId) isEditLoopNode.value = true; break; + case 'Plugin': + // Plugin节点:显示插件详情而不是编辑 + const pluginData = { + serviceId: nodeParameters?.serviceId || '', + name: nodeName, + description: nodeDesc, + pluginType: 'semantic_interface' // 默认类型,可以根据实际情况调整 + }; + showPluginDetails(pluginData); + return; // 直接返回,不需要设置编辑状态 + default: // 其他节点类型使用YAML编辑器 editYamlDrawer(nodeName, nodeDesc, nodeParameters, nodeId); @@ -1295,7 +1317,13 @@ const edgesChange = (edges) => { if (edges?.[0]?.type === 'remove' || edges?.[0]?.type === 'add') { emits('updateFlowsDebug', false); updateFlowsDebugStatus.value = false; - nodeAndLineConnection(); + nextTick(() => { + try { + nodeAndLineConnection(); + } catch (error: any) { + console.error('edgesChange中nodeAndLineConnection失败:', error); + } + }); } }; @@ -1309,12 +1337,24 @@ const nodesChange = (nodes) => { delNode(nodes[0].id); // 节点增加删除时直接将工作流debug状态置为false emits('updateFlowsDebug', false); - nodeAndLineConnection(); + nextTick(() => { + try { + nodeAndLineConnection(); + } catch (error: any) { + console.error('nodesChange(remove)中nodeAndLineConnection失败:', error); + } + }); } if (nodes?.[0]?.type === 'add') { // 节点增加删除时直接将工作流debug状态置为false emits('updateFlowsDebug', false); - nodeAndLineConnection(); + nextTick(() => { + try { + nodeAndLineConnection(); + } catch (error: any) { + console.error('nodesChange(add)中nodeAndLineConnection失败:', error); + } + }); } updateFlowsDebugStatus.value = false; }; @@ -1324,6 +1364,8 @@ const getCreatedFlow = async (createdFlowObj) => { if (flowObj.value) { flowObj.value = { ...createdFlowObj }; workFlowItemName.value = createdFlowObj.name; + + // 回显工作流节点和边 redrageFlow(createdFlowObj?.nodes, createdFlowObj?.edges, createdFlowObj?.notes || []); @@ -1380,6 +1422,8 @@ const editFlow = async (item) => { if (res[1]?.result?.flow) { flowObj.value = res[1].result.flow; + + redrageFlow(flowObj.value.nodes || [], flowObj.value.edges || [], flowObj.value.notes || []); // 加载对话变量用于开始节点展示 @@ -1446,7 +1490,7 @@ watch( // 回显工作流节点和边 const redrageFlow = (nodesList, edgesList, notesList = []) => { - const newNodeList = nodesList.map((node) => { + const newNodeList = nodesList.map((node, index) => { let newNode = { id: node.stepId, type: node.callId, @@ -1484,7 +1528,7 @@ const redrageFlow = (nodesList, edgesList, notesList = []) => { newNode.data = { ...newNode.data, parameters: sanitizedChoice.parameters - }; + }; } else if (node.callId === 'VariableAssign') { // VariableAssign节点特殊处理 newNode.type = 'VariableAssign'; @@ -1531,12 +1575,92 @@ const redrageFlow = (nodesList, edgesList, notesList = []) => { nodeId: 'VariableAssign', callId: 'VariableAssign', }; + } else if (node.callId === 'Plugin' && node.nodeId === 'Plugin') { + // API插件节点:当callId和nodeId都为'Plugin'时,识别为插件节点 + newNode.type = 'plugin-node'; + newNode.data = { + ...(newNode.data || {}), + nodeId: node.nodeId || 'Plugin', + callId: node.callId || 'Plugin', + serviceId: node.serviceId || '', + // 保留插件类型信息,如果没有则默认为semantic_interface + pluginType: node.pluginType || node.data?.pluginType || 'semantic_interface', + // 保留其他插件相关字段 + author: node.author || node.data?.author || '', + authorName: node.authorName || node.data?.authorName || '', + icon: node.icon || node.data?.icon || '', + isActive: node.isActive !== undefined ? node.isActive : (node.data?.isActive !== undefined ? node.data.isActive : true), + status: node.status || node.data?.status || 'ready', + published: node.published !== undefined ? node.published : (node.data?.published !== undefined ? node.data.published : true), + // 确保parameters结构完整 + parameters: node.parameters || { + input_parameters: null, + output_parameters: { + type: '', + description: '' + } + } + }; + } else if (node.callId === 'Empty' && node.nodeId === 'Empty') { + newNode.type = 'custom'; + + // 确保newNode.data存在,防止扩展运算符报错 + if (!newNode.data) { + newNode.data = { + name: node.name, + description: node.description, + parameters: node.parameters, + nodeId: node.nodeId, + callId: node.callId, + serviceId: node.serviceId, + }; + } + + newNode.data = { + ...(newNode.data || {}), + nodeId: node.nodeId || 'Empty', + callId: node.callId || 'Empty', + serviceId: node.serviceId || '', + parameters: node.parameters || { + input_parameters: null, + output_parameters: { + type: '', + description: '' + } + } + }; } else { newNode.type = 'custom'; } + // 确保节点具有所有必需的属性 + if (!newNode.id) { + newNode.id = `node-${Date.now()}-${Math.random()}`; + } + + if (!newNode.type) { + newNode.type = 'custom'; + } + + if (!newNode.data) { + newNode.data = {}; + } + + if (!newNode.position) { + newNode.position = { x: 0, y: 0 }; + } + + // 确保data对象有基本属性 + if (!newNode.data.name) { + newNode.data.name = node.name || '未命名节点'; + } + + if (!newNode.data.description) { + newNode.data.description = node.description || ''; + } + return newNode; }); - const newEdgeList = edgesList.map((edge) => { + const newEdgeList = edgesList.map((edge, index) => { const newEdge = { id: edge.edgeId, source: edge.sourceNode, @@ -1545,12 +1669,17 @@ const redrageFlow = (nodesList, edgesList, notesList = []) => { type: 'normal', sourceHandle: edge.branchId, // 这里是分支边需要以确定源头handle }; + // 验证边的必需属性 + if (!newEdge.id) { + newEdge.id = `edge-${Date.now()}-${Math.random()}`; + } + // 线分支条件需后续添加 return newEdge; }); - // 处理notes数据,创建注释节点 - const newNotesList = (notesList || []).map((note: any) => { + const safeNotesList = Array.isArray(notesList) ? notesList : []; + const newNotesList = safeNotesList.map((note: any) => { return { id: note.noteId, type: 'comment', @@ -1574,10 +1703,24 @@ const redrageFlow = (nodesList, edgesList, notesList = []) => { }); // 合并所有节点(包括工作流节点和注释节点) - setNodes([...newNodeList, ...newNotesList]); + const allNodes = [...newNodeList, ...newNotesList]; + + setNodes(allNodes); + // 同步更新组件的nodes ref + nodes.value = allNodes; + setEdges(newEdgeList); + // 同步更新组件的edges ref + edges.value = newEdgeList; // 回显节点和边后,判断各节点连接状态 - nodeAndLineConnection(); + // 使用 nextTick 确保DOM更新完成后再执行连接检查 + nextTick(() => { + try { + nodeAndLineConnection(); + } catch (error: any) { + console.error('nodeAndLineConnection执行失败:', error); + } + }); }; // 处理插入节点事件 @@ -1924,7 +2067,6 @@ const handleYAMLFileImport = async (event: Event) => { flowObj.value.name = yamlData.name; workFlowItemName.value = yamlData.name; } - // 触发保存 await saveFlow(); @@ -2207,7 +2349,13 @@ const executeInsertNode = (nodeMetaData) => { // 触发工作流状态更新 emits('updateFlowsDebug', false); updateFlowsDebugStatus.value = false; - nodeAndLineConnection(); + nextTick(() => { + try { + nodeAndLineConnection(); + } catch (error: any) { + console.error('handleInsertNode中nodeAndLineConnection失败:', error); + } + }); // 关闭菜单 closeInsertNodeMenu(); @@ -2296,11 +2444,12 @@ const updateNodeFunc = (id, status, constTime, content?) => { // 更新当前节点的状态,以及运行时间 updateNode(id, { data: { ...data, status, constTime } }); // 遍历获取以当前节点为起源节点的边和为目的节点的边 + const edges = getEdges.value || []; const changeSourceEdges = [ - ...getEdges.value.filter((item) => item.source === id), + ...edges.filter((item) => item.source === id), ]; const changeTargetEdges = [ - ...getEdges.value.filter((item) => item.target === id), + ...edges.filter((item) => item.target === id), ]; // 分别遍历相应的以该节点为起源的边-并更新它们的状态为最新状态 changeSourceEdges.forEach((item) => { @@ -2340,7 +2489,8 @@ const saveFlow = async (updateNodeParameter?, debug?) => { try { // 第一步:保存所有Loop节点的子工作流 - const loopNodes = getNodes.value.filter(node => node.data.callId === 'Loop'); + const nodes = getNodes.value || []; + const loopNodes = nodes.filter(node => node.data.callId === 'Loop'); for (const loopNode of loopNodes) { // 通过全局变量访问LoopNode组件实例(需要在LoopNode中设置) @@ -2380,7 +2530,10 @@ const saveFlow = async (updateNodeParameter?, debug?) => { // 第二步:保存主工作流(原有逻辑) // 将对应的节点和边存储格式改造,过滤掉注释节点 - let updateNodes = getNodes.value + const currentNodes = getNodes.value || []; + const currentEdges = getEdges.value || []; + + let updateNodes = currentNodes .filter(item => item.type !== 'comment' && !item.data?.isComment) .map((item) => { const { ...otherItem } = item.data; @@ -2435,7 +2588,7 @@ const saveFlow = async (updateNodeParameter?, debug?) => { // 对于branch节点,处理choice数据 let choices = []; // 根据该节点在edge中作为source时的edge - const branchEdges = getEdges.value.filter((edge) => edge.source === item.id); + const branchEdges = currentEdges.filter((edge) => edge.source === item.id); // 如果有边连接,根据边的branchId创建choice if (branchEdges.length > 0) { @@ -2517,18 +2670,47 @@ const saveFlow = async (updateNodeParameter?, debug?) => { } }, }; + } else if (item.type === 'plugin-node') { + // 处理API插件节点:callId和nodeId设置为'Plugin',serviceId保存实际的插件ID + const pluginServiceId = item.data?.serviceId || item.data?.callId || ''; + newItem = { + ...newItem, + callId: 'Plugin', + nodeId: 'Plugin', + serviceId: pluginServiceId, + name: item.data?.name || '', + description: item.data?.description || '', + // 保存插件相关的扩展字段 + pluginType: item.data?.pluginType || 'semantic_interface', + author: item.data?.author || '', + authorName: item.data?.authorName || '', + icon: item.data?.icon || '', + isActive: item.data?.isActive !== undefined ? item.data.isActive : true, + status: item.data?.status || 'ready', + published: item.data?.published !== undefined ? item.data.published : true, + parameters: { + ...(item.data?.parameters || {}), + // 将serviceId备份到parameters中,以防后端清空serviceId字段 + _plugin_service_id: pluginServiceId, + input_parameters: item.data?.parameters?.input_parameters || null, + output_parameters: item.data?.parameters?.output_parameters || { + type: '', + description: '' + } + }, + }; } return newItem; }); - + console.log('处理边'); // 处理边 - const updateEdges = getEdges.value.map((item) => { + const updateEdges = currentEdges.map((item) => { let branchId = item.sourceHandle; // 如果没有sourceHandle,根据源节点类型生成默认的branchId if (!branchId) { - const sourceNode = getNodes.value.find(node => node.id === item.source); + const sourceNode = currentNodes.find(node => node.id === item.source); if (sourceNode) { if (sourceNode.type === 'Choice') { // Choice节点应该有默认分支 @@ -2551,7 +2733,7 @@ const saveFlow = async (updateNodeParameter?, debug?) => { branchId: branchId, }; }); - + console.log('处理notes'); // 处理notes数据,收集注释节点 const updateNotes = getNodes.value .filter(node => node.type === 'comment' && node.data?.isComment) @@ -2562,10 +2744,11 @@ const saveFlow = async (updateNodeParameter?, debug?) => { width: commentNode.data.width || 200, height: commentNode.data.height || 120 })); - + console.log('处理参数'); // 处理节点参数更新 if (updateNodeParameter) { updateNodes.forEach((item) => { + console.log(item); if (item.stepId === updateNodeParameter.id) { if (item.type === 'Code') { item.parameters.input_parameters = updateNodeParameter.parameters.input_parameters; @@ -2604,6 +2787,17 @@ const saveFlow = async (updateNodeParameter?, debug?) => { } item.parameters.input_parameters = updateNodeParameter.parameters.input_parameters; item.parameters.output_parameters = updateNodeParameter.parameters.output_parameters; + } else if (item.callId === 'Plugin') { + // Plugin节点:更新插件相关参数 + if (!item.parameters) { + item.parameters = {}; + } + item.parameters.input_parameters = updateNodeParameter.parameters?.input_parameters || {}; + item.parameters.output_parameters = updateNodeParameter.parameters?.output_parameters || {}; + // 保持serviceId不变 + if (updateNodeParameter.serviceId) { + item.serviceId = updateNodeParameter.serviceId; + } } else if (item.type === 'start') { item.variables == updateNodeParameter.variables; } else if (item.type === 'Loop') { @@ -2666,6 +2860,8 @@ const saveFlow = async (updateNodeParameter?, debug?) => { if (!isNodeConnect.value) { ElMessage.error(i18n.global.t('semantic.check_connect')); } + + redrageFlow(updatedCurFlow?.nodes, updatedCurFlow?.edges, updatedCurFlow?.notes || []); } diff --git a/src/views/createapp/components/workFlowConfig/PluginListPanel.vue b/src/views/createapp/components/workFlowConfig/PluginListPanel.vue index 0244e763..a82e8f8d 100644 --- a/src/views/createapp/components/workFlowConfig/PluginListPanel.vue +++ b/src/views/createapp/components/workFlowConfig/PluginListPanel.vue @@ -279,8 +279,8 @@ const handlePluginClick = (plugin: any) => { // 创建PluginNode节点数据结构 const nodeData = { // 基础节点信息 - nodeId: `plugin-${plugin.serviceId}`, - callId: plugin.serviceId, + nodeId: 'Plugin', + callId: 'Plugin', type: 'plugin-node', // 标识为PluginNode类型 // PluginNode专用数据 @@ -313,8 +313,8 @@ const handleDragStart = (event: DragEvent, plugin: any) => { // 创建与点击时相同的PluginNode节点数据结构 const nodeData = { // 基础节点信息 - nodeId: `plugin-${plugin.serviceId}`, - callId: plugin.serviceId, + nodeId: 'Plugin', + callId: 'Plugin', type: 'plugin-node', // 标识为PluginNode类型 // PluginNode专用数据 diff --git a/src/views/createapp/components/workFlowConfig/PluginNode.vue b/src/views/createapp/components/workFlowConfig/PluginNode.vue index 15cc6591..d657e1fc 100644 --- a/src/views/createapp/components/workFlowConfig/PluginNode.vue +++ b/src/views/createapp/components/workFlowConfig/PluginNode.vue @@ -2,7 +2,7 @@
-
- {{ data.pluginType === 'semantic_interface' ? 'API' : 'MCP' }} +
+ {{ (data.pluginType || 'semantic_interface') === 'semantic_interface' ? 'API' : 'MCP' }}
@@ -37,14 +37,14 @@
{{ data.name }}
-
+
- @{{ (data.authorName || data.author).slice(0, 15) }}... + @{{ (data.authorName || data.author || '').slice(0, 15) }}... @{{ data.authorName || data.author }}
@@ -173,7 +173,9 @@ const defaultIcon = DefaultIcon; // 计算状态类 - 只反映插件本身状态,不受debugInfo影响 const statusClass = computed(() => { - if (props.data.pluginType === 'mcp') { + const pluginType = props.data.pluginType || 'semantic_interface'; // 默认为semantic_interface + + if (pluginType === 'mcp') { if (props.data.status === 'ready' && props.data.isActive) { return 'status--active'; } else if (props.data.status === 'installing') { diff --git a/src/views/createapp/components/workFlowConfig/useDnD.js b/src/views/createapp/components/workFlowConfig/useDnD.js index 41b455f9..0a84547e 100644 --- a/src/views/createapp/components/workFlowConfig/useDnD.js +++ b/src/views/createapp/components/workFlowConfig/useDnD.js @@ -234,8 +234,19 @@ function sanitizeNodeData(nodeData, nodeId) { } }; } else if (cleanNodeData.type === 'plugin-node') { - // 插件节点不需要清洗,直接返回原始数据 - // 插件节点的数据结构已经在PluginListPanel中正确构建 + // 插件节点:确保callId和nodeId正确设置为'Plugin' + cleanNodeData.callId = 'Plugin'; + cleanNodeData.nodeId = 'Plugin'; + + // 确保插件节点有正确的parameters结构 + cleanNodeData.parameters = cleanNodeData.parameters || { + input_parameters: null, + output_parameters: { + type: '', + description: '' + } + }; + return cleanNodeData; } else { // 对于所有其他节点类型(LLM、RAG、API、SQL等),使用API返回的原始parameters @@ -278,7 +289,22 @@ function createNewNode(nodeMetaData, position, customNodeId = null) { data: nodeMetaData.type === 'plugin-node' ? { // 插件节点的完整数据结构 ...nodeMetaData.data, - nodeId: nodeId + nodeId: 'Plugin', // Plugin节点的nodeId应该是'Plugin' + callId: 'Plugin', // Plugin节点的callId应该是'Plugin' + // 确保必需的字段存在,如果没有则提供默认值 + pluginType: nodeMetaData.data.pluginType || 'semantic_interface', + author: nodeMetaData.data.author || nodeMetaData.data.authorName || '', + authorName: nodeMetaData.data.authorName || nodeMetaData.data.author || '', + isActive: nodeMetaData.data.isActive !== undefined ? nodeMetaData.data.isActive : true, + status: nodeMetaData.data.status || 'ready', + published: nodeMetaData.data.published !== undefined ? nodeMetaData.data.published : true, + parameters: nodeMetaData.data.parameters || { + input_parameters: null, + output_parameters: { + type: '', + description: '' + } + } } : { // 常规节点的数据结构 name: cleanNodeData.name, diff --git a/src/views/dialogue/dialogueView.vue b/src/views/dialogue/dialogueView.vue index f719f548..5b2ab398 100644 --- a/src/views/dialogue/dialogueView.vue +++ b/src/views/dialogue/dialogueView.vue @@ -207,7 +207,7 @@ const initCopilot = async (): Promise => { userinfo.value.organization = type; const isLogin = await getUserInfo(); if (isLogin) { - await api.stopGeneration(); + await api.stopGeneration(''); await getHistorySession(); } return; -- Gitee From 38fe5abe2632ebd2dbc6175a8cb2dccb56f8e79f Mon Sep 17 00:00:00 2001 From: Ethan-Zhang Date: Mon, 20 Oct 2025 20:39:05 +0800 Subject: [PATCH 2/2] =?UTF-8?q?Feat:=20workflow=E6=80=A7=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96&preview=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/historySession.ts | 6 - .../createapp/components/AgentAppConfig.vue | 1 - src/views/createapp/components/workFlow.vue | 108 +++++++++++------- .../workFlowConfig/LLMNodeDrawer.vue | 2 - .../dialogue/components/InterPreview.vue | 1 + src/views/tools/index.vue | 2 - 6 files changed, 70 insertions(+), 50 deletions(-) diff --git a/src/store/historySession.ts b/src/store/historySession.ts index 7e1aeade..9068c8fb 100644 --- a/src/store/historySession.ts +++ b/src/store/historySession.ts @@ -211,12 +211,6 @@ export const useHistorySessionStore = defineStore( historySession.value = allConversations.filter((item) => { const itemAppId = item.appId || ''; const matches = itemAppId === currentAppId; - console.log('🔍 [getHistorySession] 对话过滤:', { - conversationId: item.conversationId, - itemAppId, - currentAppId, - matches - }); return matches; }); diff --git a/src/views/createapp/components/AgentAppConfig.vue b/src/views/createapp/components/AgentAppConfig.vue index 09708649..c545609a 100644 --- a/src/views/createapp/components/AgentAppConfig.vue +++ b/src/views/createapp/components/AgentAppConfig.vue @@ -677,7 +677,6 @@ onMounted(async () => { flex: 1; display: flex; flex-direction: column; - gap: 8px; .preview-title { line-height: 24px; diff --git a/src/views/createapp/components/workFlow.vue b/src/views/createapp/components/workFlow.vue index cc614fc0..5c4c9f18 100644 --- a/src/views/createapp/components/workFlow.vue +++ b/src/views/createapp/components/workFlow.vue @@ -1,6 +1,6 @@