From 4c93714a1c09308e38ad85abdaccf3d628ed6699 Mon Sep 17 00:00:00 2001 From: ZLY Date: Mon, 27 Oct 2025 13:40:54 +0800 Subject: [PATCH 01/24] =?UTF-8?q?feat(ideContainer):=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E8=AF=A6=E6=83=85=E7=9A=84=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=BA=94=E7=94=A8=E4=B8=8B=E7=9A=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ideContainer/sideBar.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/ideContainer/sideBar.tsx b/src/pages/ideContainer/sideBar.tsx index 1fdb3fb..f493520 100644 --- a/src/pages/ideContainer/sideBar.tsx +++ b/src/pages/ideContainer/sideBar.tsx @@ -21,6 +21,7 @@ import { updateMenuData, updateFlowData, updateCurrentAppData } from '@/store/id import { addApp, getProjectEnv, editApp, deleteApp } from '@/api/apps'; import _ from 'lodash'; import { getAppInfoNew } from '@/api/appRes'; +import { getAppEventData } from '@/api/appEvent'; const TreeNode = Tree.Node; const FormItem = Form.Item; @@ -315,6 +316,7 @@ const SideBar: React.FC = ({ const currentMenu = _.cloneDeep(menuData[identity]); const index = currentMenu.findIndex(v => v.key === parentKey); const res: any = await getAppInfoNew(data.id); + getAppEventData(data.id); if (res.code === 200) { const children = currentMenu[index].children.find(v => v.id === data.id); children.children[0].children = res.data.events.map(item => { From b282c45eacc7fe7bfd195a178a1c0ba795ede2a3 Mon Sep 17 00:00:00 2001 From: ZLY Date: Mon, 27 Oct 2025 13:41:14 +0800 Subject: [PATCH 02/24] =?UTF-8?q?fix(flow):=E4=BF=AE=E5=A4=8D=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=95=B0=E6=8D=AE=E8=B7=AF=E5=BE=84=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/flowEditor/utils/projectFlowHandle.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/flowEditor/utils/projectFlowHandle.ts b/src/pages/flowEditor/utils/projectFlowHandle.ts index 6f86781..0da732d 100644 --- a/src/pages/flowEditor/utils/projectFlowHandle.ts +++ b/src/pages/flowEditor/utils/projectFlowHandle.ts @@ -10,7 +10,7 @@ export const projectFlowHandle = (initialData, useDefault, setNodes, setEdges, d const { nodes: convertedNodes, edges: convertedEdges - } = convertFlowData(initialData?.main?.components || initialData?.compData?.components, useDefault); + } = convertFlowData(initialData?.main?.components || initialData?.components, useDefault); // 为所有边添加类型 const initialEdges: Edge[] = convertedEdges.map(edge => ({ From 995a5f9830f0f99435224894d40fea24d92cc8da Mon Sep 17 00:00:00 2001 From: ZLY Date: Mon, 27 Oct 2025 13:48:18 +0800 Subject: [PATCH 03/24] =?UTF-8?q?fix(utils):=E4=BF=AE=E6=AD=A3=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E6=95=B0=E6=8D=AE=E6=98=A0=E5=B0=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/convertAppFlowData.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/convertAppFlowData.ts b/src/utils/convertAppFlowData.ts index 9eac62c..fbe5075 100644 --- a/src/utils/convertAppFlowData.ts +++ b/src/utils/convertAppFlowData.ts @@ -109,9 +109,9 @@ export const convertAppFlowData = (appFlowData: any[]) => { lineType: 'lineType', data: { displayData: { - name: '事件1', - eventId: 'eventId', - topic: 'topic' + name: sourceEvent.eventName, + eventId: sourceEvent.eventId, + topic: sourceEvent.topic } } }); From b3885964992a987c23b158caab157fdb2a73cb49 Mon Sep 17 00:00:00 2001 From: ZLY Date: Mon, 27 Oct 2025 14:23:45 +0800 Subject: [PATCH 04/24] =?UTF-8?q?feat(flowEditor):=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=BA=BF=E5=90=8C=E6=AD=A5=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=92=8C=E6=8B=89=E7=BA=BF=E5=B1=95=E7=A4=BA=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useFlowCallbacks.ts | 51 +++++++++++++++++-- .../components/customConnectionLine.tsx | 27 +++++++--- .../flowEditor/components/customEdge.tsx | 23 ++++++++- .../flowEditor/components/nodeContentApp.tsx | 1 - 4 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 5006a19..9139cf4 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -121,8 +121,8 @@ export const useFlowCallbacks = ( } // 获取源节点和目标节点的参数信息 - const sourceParams = sourceNode.data?.parameters || {}; - const targetParams = targetNode.data?.parameters || {}; + const sourceParams: any = sourceNode.data?.parameters || {}; + const targetParams: any = targetNode.data?.parameters || {}; // 获取源handle和目标handle的类型 (api或data) const sourceHandleType = getHandleType(params.sourceHandle, sourceParams); @@ -142,7 +142,52 @@ export const useFlowCallbacks = ( // 如果验证通过,创建连接 setEdges((edgesSnapshot: Edge[]) => { - const newEdges = addEdge({ ...params, type: 'custom' }, edgesSnapshot); + // 创建带有事件信息的连接 + const edgeParams = { ...params, type: 'custom' }; + + // 检查源节点和目标节点是否都有事件信息 + const sourceApi = (sourceParams.apiOuts || []).find((api: any) => + api.name === params.sourceHandle || api.id === params.sourceHandle); + const targetApi = (targetParams.apiIns || []).find((api: any) => + api.name === params.targetHandle || api.id === params.targetHandle); + + // 如果源节点有事件topic信息 + if (sourceApi && sourceApi.topic) { + // 如果目标节点的topic是**empty**或没有topic,则使用源节点的事件信息 + if (!targetApi || !targetApi.topic || targetApi.topic.includes('**empty**')) { + edgeParams.data = { + displayData: { + name: sourceApi.name, + eventId: sourceApi.eventId, + topic: sourceApi.topic + } + }; + } + // 如果两个节点都有非empty的topic,则以源节点为准 + else if (sourceApi.topic && targetApi.topic && + !sourceApi.topic.includes('**empty**') && + !targetApi.topic.includes('**empty**')) { + edgeParams.data = { + displayData: { + name: sourceApi.name, + eventId: sourceApi.eventId, + topic: sourceApi.topic + } + }; + } + } + // 如果源节点没有事件信息,但目标节点有 + else if (targetApi && targetApi.topic && !targetApi.topic.includes('**empty**')) { + edgeParams.data = { + displayData: { + name: targetApi.name, + eventId: targetApi.eventId, + topic: targetApi.topic + } + }; + } + + const newEdges = addEdge(edgeParams, edgesSnapshot); // 连接建立后记录历史 setTimeout(() => { diff --git a/src/pages/flowEditor/components/customConnectionLine.tsx b/src/pages/flowEditor/components/customConnectionLine.tsx index ba43697..cb9638b 100644 --- a/src/pages/flowEditor/components/customConnectionLine.tsx +++ b/src/pages/flowEditor/components/customConnectionLine.tsx @@ -1,10 +1,23 @@ -import React, { useEffect } from 'react'; +import React from 'react'; import { getBezierPath } from '@xyflow/react'; const CustomConnectionLine = ({ fromNode, fromX, fromY, toX, toY }) => { - useEffect(() => { - console.log('fromNode', fromNode); - }, [fromNode]); + // 查找源节点的事件信息 + let eventData = null; + if (fromNode && fromNode.data) { + const params = fromNode.data.parameters || {}; + const apiOuts = params.apiOuts || []; + + // 查找匹配的输出API + for (const api of apiOuts) { + // 这里假设fromNode存在selectedHandle属性,表示当前拖拽的句柄 + if (api.name || api.id) { + eventData = api; + break; + } + } + } + const [path] = getBezierPath({ sourceX: fromX, sourceY: fromY, @@ -22,10 +35,10 @@ const CustomConnectionLine = ({ fromNode, fromX, fromY, toX, toY }) => { className="animated-stroke" fill="none" /> - {/*TODO 临时定义,后续等接口字段。 存在事件信息的时候才展示连接提示*/} - {fromNode.data.eventData && ( + {/* 当存在事件信息的时候展示连接提示 */} + {eventData && eventData.topic && !eventData.topic.includes('**empty**') && ( - 正在连接... + {`连接事件: ${eventData.name}`} )} diff --git a/src/pages/flowEditor/components/customEdge.tsx b/src/pages/flowEditor/components/customEdge.tsx index 6975803..f4f8154 100644 --- a/src/pages/flowEditor/components/customEdge.tsx +++ b/src/pages/flowEditor/components/customEdge.tsx @@ -84,6 +84,27 @@ const DataDisplayEdge: React.FC = ({ const handleSelect = (option) => { setSelectedValue(option.label); setIsOpen(false); + + // 查找所有具有相同事件ID和连接点的边并同步更新 + setEdges(eds => eds.map((edge: any) => { + // 检查边是否有displayData且与当前选择的事件匹配 + if (edge.data?.displayData && + edge.data.displayData.eventId === displayData.eventId && + edge.data.displayData.topic === displayData.topic) { + return { + ...edge, + data: { + ...edge.data, + displayData: { + ...edge.data.displayData, + name: option.label, + topic: option.value + } + } + }; + } + return edge; + })); }; return ( @@ -169,7 +190,7 @@ const DataDisplayEdge: React.FC = ({ )} - {hovered && Object.keys(displayData).length === 0 && ( + {hovered && Object.keys(displayData).length === 0 && Object.keys(displayData).length === 0 && ( handleEdgeAddNode(e)} /> diff --git a/src/pages/flowEditor/components/nodeContentApp.tsx b/src/pages/flowEditor/components/nodeContentApp.tsx index 8ee00fb..de5834c 100644 --- a/src/pages/flowEditor/components/nodeContentApp.tsx +++ b/src/pages/flowEditor/components/nodeContentApp.tsx @@ -240,7 +240,6 @@ const useEventGroups = (component: any) => { }; }); } - console.log('groups:', groups); return groups; } catch (e) { console.error('解析customDef时出错:', e); From 28721ad45abe794ac0c4bc5939188002e679738e Mon Sep 17 00:00:00 2001 From: ZLY Date: Mon, 27 Oct 2025 14:24:02 +0800 Subject: [PATCH 05/24] =?UTF-8?q?feat(flow):=E4=BC=98=E5=8C=96=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E6=B5=81=E7=A8=8B=E6=95=B0=E6=8D=AE=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/flowEditor/utils/appFlowhandle.ts | 2 -- src/utils/convertAppFlowData.ts | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/pages/flowEditor/utils/appFlowhandle.ts b/src/pages/flowEditor/utils/appFlowhandle.ts index 5dddb09..030d7ea 100644 --- a/src/pages/flowEditor/utils/appFlowhandle.ts +++ b/src/pages/flowEditor/utils/appFlowhandle.ts @@ -12,8 +12,6 @@ export const appFLowHandle = (initialData, useDefault, setNodes, setEdges, dispa nodes: convertedNodes, edges: convertedEdges } = convertAppFlowData(initialData); - console.log('nodes:', convertedNodes); - console.log('edges:', convertedEdges); // 为所有边添加类型 diff --git a/src/utils/convertAppFlowData.ts b/src/utils/convertAppFlowData.ts index fbe5075..b3c6f34 100644 --- a/src/utils/convertAppFlowData.ts +++ b/src/utils/convertAppFlowData.ts @@ -14,6 +14,17 @@ export const convertAppFlowData = (appFlowData: any[]) => { // 处理每个应用流程数据项(每个应用作为一个节点) appFlowData.forEach((app: any, index: number) => { + // 添加过滤逻辑:如果 eventListenes 和 eventSends 都为空,则不生成节点 + const hasEventListenes = app.eventListenes && app.eventListenes.length > 0 && + app.eventListenes.some((event: any) => event && !event.topic?.includes('**empty**')); + const hasEventSends = app.eventSends && app.eventSends.length > 0 && + app.eventSends.some((event: any) => event && !event.topic?.includes('**empty**')); + + // 如果两者都为空,则跳过当前应用节点的创建 + if (!hasEventListenes && !hasEventSends) { + return; + } + // 构造节点数据 const node: any = { id: app.appId || `app_${index}`, @@ -29,7 +40,7 @@ export const convertAppFlowData = (appFlowData: any[]) => { dataType: '', defaultValue: '', topic: event.topic - })) : [], + })).filter((event: any) => event && !event.topic?.includes('**empty**')) : [], // eventSends 作为 apiOuts(输出) apiOuts: app.eventSends ? app.eventSends.map((event: any) => ({ name: event.eventName, @@ -37,7 +48,7 @@ export const convertAppFlowData = (appFlowData: any[]) => { dataType: '', defaultValue: '', topic: event.topic - })) : [], + })).filter((event: any) => event && !event.topic?.includes('**empty**')) : [], // 提取 dataIns 和 dataOuts 属性 dataIns: [], dataOuts: [] From 7a13beaf038867e914cff01b24b8eab0c7709a1c Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 10:18:21 +0800 Subject: [PATCH 06/24] =?UTF-8?q?feat(ideContainer):=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=AD=90=E8=8A=82=E7=82=B9=E6=A0=87=E7=AD=BE=E9=A1=B5=E6=89=93?= =?UTF-8?q?=E5=BC=80=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flowEditor/components/nodeContextMenu.tsx | 14 +++- src/pages/ideContainer/index.tsx | 76 ++++++++++++++++++- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/pages/flowEditor/components/nodeContextMenu.tsx b/src/pages/flowEditor/components/nodeContextMenu.tsx index a739018..3849e18 100644 --- a/src/pages/flowEditor/components/nodeContextMenu.tsx +++ b/src/pages/flowEditor/components/nodeContextMenu.tsx @@ -33,8 +33,18 @@ const NodeContextMenu: React.FC = ({ }; const handleEdit = () => { - onEdit && onEdit(node); - onCloseOpenModal(true); + // 判断节点类型,如果是SUB类型则打开新标签页 + if (node.type === 'SUB') { + // 创建自定义事件来通知打开新标签页 + const openTabEvent = new CustomEvent('openSubNodeTab', { + detail: { node } + }); + document.dispatchEvent(openTabEvent); + } + else { + onEdit && onEdit(node); + onCloseOpenModal(true); + } onCloseMenu(null); }; diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index 4395fdb..8ecba14 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState, useRef } from 'react'; -import { getUrlParams } from '@/utils/common'; +import { getUrlParams, isJSON } from '@/utils/common'; import styles from './style/index.module.less'; import SideBar from './sideBar'; import LogBar from './logBar'; @@ -59,7 +59,7 @@ function IDEContainer() { // 用于跟踪已打开的tab,保持组件状态 const [openedTabs, setOpenedTabs] = useState>(new Set()); const [subMenuData, setSubMenuData] = useState({}); - const { menuData } = useSelector((state) => state.ideContainer); + const { menuData, flowData, currentAppData } = useSelector((state) => state.ideContainer); const dispatch = useDispatch(); const navBarRef = useRef(null); @@ -105,6 +105,78 @@ function IDEContainer() { } }); + // 监听自定义事件,处理打开子节点标签页的逻辑 + useEffect(() => { + const handleOpenSubNodeTab = (event: CustomEvent) => { + const { node } = event.detail; + const subCompList = flowData[currentAppData.id].subs; + const customDef = isJSON(node.data.component.customDef) ? JSON.parse(node.data.component.customDef) : {}; + const currentSubComp = subCompList.find((item) => item.flowId === customDef.subflowId); + // 根据节点信息创建新的标签页 + if (currentSubComp && Object.keys(currentSubComp).length > 0) { + const component = node.data.component; + const newNodeKey = currentSubComp.flowId; + + // 查找菜单项 + const findMenuItem = (menuItems: any[]): any => { + for (const item of menuItems) { + if (item.key === newNodeKey) { + return item; + } + if (item.children) { + const found = findMenuItem(item.children); + if (found) return found; + } + } + return null; + }; + + const menuItems = menuData[urlParams.identity]; + const menuItem = findMenuItem(menuItems); + + if (menuItem) { + // 更新当前应用数据 + dispatch(updateCurrentAppData({ ...menuItem })); + + // 设置选中项,触发tab创建 + setSelected({ + ...menuItem, + key: menuItem.key, + parentKey: menuItem.parentKey + }); + } + else { + // 如果在菜单中找不到对应项,创建一个临时的菜单项 + const tempMenuItem = { + key: newNodeKey, + title: currentSubComp.flowName, + pathTitle: `${currentAppData.name} / ${currentSubComp.flowName}`, + path: 'complexFlow', + parentKey: 'appList', + compData: currentSubComp, + children: null + }; + + dispatch(updateCurrentAppData({ ...tempMenuItem })); + + setSelected({ + ...tempMenuItem, + key: tempMenuItem.key, + parentKey: tempMenuItem.parentKey + }); + } + } + }; + + // 添加事件监听器 + document.addEventListener('openSubNodeTab', handleOpenSubNodeTab as EventListener); + + // 清理事件监听器 + return () => { + document.removeEventListener('openSubNodeTab', handleOpenSubNodeTab as EventListener); + }; + }, [menuData, urlParams.identity, dispatch]); + const connectWS = async () => { const res = await getUserToken(); const token = res.data; From 30ed7d22e6833c81d4884ced8cd9f8eb943689d0 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 11:12:47 +0800 Subject: [PATCH 07/24] =?UTF-8?q?fix(event):=E4=BF=AE=E5=A4=8D=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=88=A0=E9=99=A4=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=94=99=E8=AF=AF-=20=E5=B0=86=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E4=BA=8B=E4=BB=B6=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=BB=8E=20record.id=20=E6=9B=B4=E6=AD=A3?= =?UTF-8?q?=E4=B8=BA=20record.eventId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/orchestration/event/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/orchestration/event/index.tsx b/src/pages/orchestration/event/index.tsx index 879e468..2a8e5ea 100644 --- a/src/pages/orchestration/event/index.tsx +++ b/src/pages/orchestration/event/index.tsx @@ -217,7 +217,7 @@ const EventContainer = () => { title="删除事件" content="事件删除后无法恢复,请谨慎删除!" onOk={async () => { - const res: any = await deleteEventItem(record.id); + const res: any = await deleteEventItem(record.eventId); if (res && res.code === 200) { Message.success('删除成功'); fetchEventData(); From 2fb23fde803f0d67dc5264fd5f9e0251e449da45 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 11:27:15 +0800 Subject: [PATCH 08/24] =?UTF-8?q?feat(flow):=20=E6=94=AF=E6=8C=81=E5=AD=90?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BF=9D=E5=AD=98=E4=B8=8E=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/appRes.ts | 6 +++- src/hooks/useFlowCallbacks.ts | 52 +++++++++++++++++++----------- src/pages/ideContainer/index.tsx | 4 +-- src/pages/ideContainer/sideBar.tsx | 3 +- 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/api/appRes.ts b/src/api/appRes.ts index 3781f29..09833f6 100644 --- a/src/api/appRes.ts +++ b/src/api/appRes.ts @@ -21,7 +21,7 @@ export function setMainFlow(data: FlowDefinition, appId: string) { } // 更新主流程-新数据结构 -export function setMainFlowNew(data: FlowDefinition, appId: string) { +export function setMainFlowNew(data, appId: string) { return axios.post(`${urlPrefix}/appRes/${appId}/updateMainNew`, data); } @@ -51,6 +51,10 @@ export function setSubFlow(data: FlowDefinition, appId: string) { return axios.post(`${urlPrefix}/appRes/${appId}/updateSub`, data); } +export function setSubFlowNew(data, appId: string) { + return axios.post(`${urlPrefix}/appRes/${appId}/updateSubNew`, data); +} + // 导入子流程 export function addSubComp(data: appFlowModel, appId: string) { return axios.post(`${urlPrefix}/appRes/${appId}/addSubComp`, data); diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 9139cf4..3a4e292 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -7,7 +7,7 @@ import { Node, Edge } from '@xyflow/react'; -import { refPublish, setMainFlow, setMainFlowNew } from '@/api/appRes'; +import { refPublish, setMainFlow, setMainFlowNew, setSubFlowNew } from '@/api/appRes'; import { Message } from '@arco-design/web-react'; import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; import { convertFlowData, reverseConvertFlowData, revertFlowData } from '@/utils/convertFlowData'; @@ -1003,7 +1003,7 @@ export const useFlowCallbacks = ( const emptyEvent = eventList.find(item => item.topic.includes('**empty**')); newNode.data.component = { type: nodeType, - customDef: { eventId: emptyEvent.id, name: emptyEvent.name, topic: emptyEvent.topic } + customDef: { eventId: emptyEvent.eventId, name: emptyEvent.name, topic: emptyEvent.topic } }; } // 将未定义的节点动态追加进nodeTypes @@ -1046,7 +1046,7 @@ export const useFlowCallbacks = ( // endregion // 保存所有节点和边数据到服务器,更新事件相关数据 - const updateEvent = (revertedData) => { + const updateEvent = (revertedData, appid) => { // 初始化参数对象 const params: any = { eventListenes: [], @@ -1098,8 +1098,8 @@ export const useFlowCallbacks = ( } }); // 调用更新事件的API - if (params.eventListenes.lengrh > 0 || params.eventSends.length > 0) { - updateAppEvent(initialData.appId, params); + if (params.eventListenes.length > 0 || params.eventSends.length > 0) { + updateAppEvent(appid, params); } }; const upDatePublish = async (revertedData) => { @@ -1141,21 +1141,36 @@ export const useFlowCallbacks = ( const { flowData, currentAppData } = store.getState().ideContainer; // console.log('revertedData:', revertedData); // console.log('newRevertedData:', newRevertedData); - const params = { - ...flowData[currentAppData.id]?.main || {}, - components: newRevertedData - }; - // return; - updateEvent(revertedData.nodeConfigs); - // 旧版数据结构 - // const res: any = await setMainFlow(revertedData, initialData.appId); - // 新版数据结构 - const res: any = await setMainFlowNew(params, initialData.appId); - if (res.code === 200) { - Message.success('保存成功'); + let params = {}; + // 更新复合组件/子流程 + if (currentAppData.key.includes('sub')) { + params = { + ...currentAppData?.compData || {}, + components: newRevertedData + }; + updateEvent(revertedData.nodeConfigs, currentAppData.parentAppId); + const res: any = await setSubFlowNew(params, currentAppData.parentAppId); + if (res.code === 200) { + Message.success('保存成功'); + } + else { + Message.error(res.message); + } } + // 更新主流程 else { - Message.error(res.message); + params = { + ...flowData[currentAppData.id]?.main || {}, + components: newRevertedData + }; + updateEvent(revertedData.nodeConfigs, initialData.appId); + const res: any = await setMainFlowNew(params, initialData.appId); + if (res.code === 200) { + Message.success('保存成功'); + } + else { + Message.error(res.message); + } } } catch (error) { console.error('Error saving flow data:', error); @@ -1167,7 +1182,6 @@ export const useFlowCallbacks = ( nodes, edges }; - console.log('params:', params); } }, [nodes, edges, initialData?.appId]); // 运行处理函数 diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index 8ecba14..ce6f8c6 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -114,7 +114,6 @@ function IDEContainer() { const currentSubComp = subCompList.find((item) => item.flowId === customDef.subflowId); // 根据节点信息创建新的标签页 if (currentSubComp && Object.keys(currentSubComp).length > 0) { - const component = node.data.component; const newNodeKey = currentSubComp.flowId; // 查找菜单项 @@ -153,6 +152,7 @@ function IDEContainer() { pathTitle: `${currentAppData.name} / ${currentSubComp.flowName}`, path: 'complexFlow', parentKey: 'appList', + parentAppId: currentAppData.id, compData: currentSubComp, children: null }; @@ -175,7 +175,7 @@ function IDEContainer() { return () => { document.removeEventListener('openSubNodeTab', handleOpenSubNodeTab as EventListener); }; - }, [menuData, urlParams.identity, dispatch]); + }, [menuData, flowData, currentAppData]); const connectWS = async () => { const res = await getUserToken(); diff --git a/src/pages/ideContainer/sideBar.tsx b/src/pages/ideContainer/sideBar.tsx index f493520..4c988f0 100644 --- a/src/pages/ideContainer/sideBar.tsx +++ b/src/pages/ideContainer/sideBar.tsx @@ -345,7 +345,8 @@ const SideBar: React.FC = ({ path: 'complexFlow', key: info.flowId, pathTitle: `${data.title} / ${info.flowName}`, - parentKey: 'appList' + parentKey: 'appList', + parentAppId: data.id }; }) }; From cebaeafb1bbf9a6b0aea0c0dd4e4fa29de5a46b1 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 11:28:40 +0800 Subject: [PATCH 09/24] =?UTF-8?q?fix(utils):=E4=BC=98=E5=8C=96=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E6=B5=81=E7=A8=8B=E6=95=B0=E6=8D=AE=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E9=80=BB=E8=BE=91-=20=E7=A7=BB=E9=99=A4=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E5=92=8C=E5=8F=91=E9=80=81=E7=9A=84=E7=A9=BA?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=E8=BF=87=E6=BB=A4=E9=80=BB=E8=BE=91=20-=20?= =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BA=8B=E4=BB=B6=E5=88=97=E8=A1=A8=E7=9A=84?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=9D=A1=E4=BB=B6=E5=88=A4=E6=96=AD=20-?= =?UTF-8?q?=E4=BF=9D=E6=8C=81=E6=95=B0=E6=8D=AE=E8=BD=AC=E6=8D=A2=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E4=B8=80=E8=87=B4=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/convertAppFlowData.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/utils/convertAppFlowData.ts b/src/utils/convertAppFlowData.ts index b3c6f34..22ad08a 100644 --- a/src/utils/convertAppFlowData.ts +++ b/src/utils/convertAppFlowData.ts @@ -15,10 +15,8 @@ export const convertAppFlowData = (appFlowData: any[]) => { // 处理每个应用流程数据项(每个应用作为一个节点) appFlowData.forEach((app: any, index: number) => { // 添加过滤逻辑:如果 eventListenes 和 eventSends 都为空,则不生成节点 - const hasEventListenes = app.eventListenes && app.eventListenes.length > 0 && - app.eventListenes.some((event: any) => event && !event.topic?.includes('**empty**')); - const hasEventSends = app.eventSends && app.eventSends.length > 0 && - app.eventSends.some((event: any) => event && !event.topic?.includes('**empty**')); + const hasEventListenes = app.eventListenes && app.eventListenes.length > 0; + const hasEventSends = app.eventSends && app.eventSends.length > 0; // 如果两者都为空,则跳过当前应用节点的创建 if (!hasEventListenes && !hasEventSends) { @@ -40,7 +38,7 @@ export const convertAppFlowData = (appFlowData: any[]) => { dataType: '', defaultValue: '', topic: event.topic - })).filter((event: any) => event && !event.topic?.includes('**empty**')) : [], + })) : [], // eventSends 作为 apiOuts(输出) apiOuts: app.eventSends ? app.eventSends.map((event: any) => ({ name: event.eventName, @@ -48,7 +46,7 @@ export const convertAppFlowData = (appFlowData: any[]) => { dataType: '', defaultValue: '', topic: event.topic - })).filter((event: any) => event && !event.topic?.includes('**empty**')) : [], + })) : [], // 提取 dataIns 和 dataOuts 属性 dataIns: [], dataOuts: [] From d9b97c2fd6df1b8138dee827d1843abaf41f0434 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 15:41:06 +0800 Subject: [PATCH 10/24] =?UTF-8?q?feat(utils):=20=E6=B7=BB=E5=8A=A0=20sleep?= =?UTF-8?q?=20=E5=B7=A5=E5=85=B7=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/common.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/utils/common.ts b/src/utils/common.ts index 9f279f1..1a804e6 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -229,4 +229,8 @@ export const deserializeValue = (value: any): any => { console.warn('Failed to deserialize value:', value, error); return value; } -}; \ No newline at end of file +}; + +export const sleep = (ms: number): Promise => { + return new Promise(resolve => setTimeout(resolve, ms)); +}; From 9f83b09ed6d01cd512ae94d884f20fd78b63f5a9 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 15:41:27 +0800 Subject: [PATCH 11/24] =?UTF-8?q?pref(app-flow):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E8=8A=82=E7=82=B9=E4=BD=8D=E7=BD=AE=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E5=8F=8A=E4=BA=8B=E4=BB=B6ID=E4=BC=A0?= =?UTF-8?q?=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/convertAppFlowData.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/utils/convertAppFlowData.ts b/src/utils/convertAppFlowData.ts index 22ad08a..9313f2a 100644 --- a/src/utils/convertAppFlowData.ts +++ b/src/utils/convertAppFlowData.ts @@ -27,7 +27,7 @@ export const convertAppFlowData = (appFlowData: any[]) => { const node: any = { id: app.appId || `app_${index}`, type: 'APP', - position: { x: 200 + index * 300, y: 200 }, + position: app.position || { x: 200 + index * 300, y: 200 }, data: { title: app.name || `应用${index + 1}`, parameters: { @@ -37,7 +37,8 @@ export const convertAppFlowData = (appFlowData: any[]) => { desc: event.description || '', dataType: '', defaultValue: '', - topic: event.topic + topic: event.topic, + eventId: event.eventId })) : [], // eventSends 作为 apiOuts(输出) apiOuts: app.eventSends ? app.eventSends.map((event: any) => ({ @@ -45,7 +46,8 @@ export const convertAppFlowData = (appFlowData: any[]) => { desc: event.description || '', dataType: '', defaultValue: '', - topic: event.topic + topic: event.topic, + eventId: event.eventId })) : [], // 提取 dataIns 和 dataOuts 属性 dataIns: [], From a3445771f0752ac09a853025e7862de8902c71b9 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 15:41:41 +0800 Subject: [PATCH 12/24] =?UTF-8?q?feat(appEvent):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=BC=96=E6=8E=92=E6=95=B0=E6=8D=AE=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/appEvent.ts | 10 ++++++++++ src/hooks/useFlowCallbacks.ts | 37 ++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/api/appEvent.ts b/src/api/appEvent.ts index e22fb24..bd02d95 100644 --- a/src/api/appEvent.ts +++ b/src/api/appEvent.ts @@ -17,4 +17,14 @@ export function getAppEventList(id: any) { // 更新事件 export function updateAppEvent(id: any, data: any) { return axios.post(`${urlPrefix}/appEvent/${id}/update`, data); +} + +// 更新应用编排数据 +export function updateAppFlowData(data: any) { + return axios.post(`${urlPrefix}/appEvent/update`, data); +} + +// 修改应用编排中的事件通道 +export function updateAppEventChannel(data: any) { + return axios.post(`${urlPrefix}/appEvent/updateTopic`, data); } \ No newline at end of file diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 3a4e292..94a3379 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -32,7 +32,8 @@ import { appFLowHandle } from '@/pages/flowEditor/utils/appFlowhandle'; import { Dispatch } from 'redux'; import { runMainFlow } from '@/api/apps'; import store from '@/store'; -import { updateAppEvent } from '@/api/appEvent'; +import { updateAppEvent, updateAppEventChannel, updateAppFlowData } from '@/api/appEvent'; +import { sleep } from '@/utils/common'; export const useFlowCallbacks = ( nodes: Node[], @@ -1182,6 +1183,40 @@ export const useFlowCallbacks = ( nodes, edges }; + const appFlowParams = { + appEventList: {} + }; + + nodes.forEach(node => { + appFlowParams.appEventList[node.id] = { + x: node.position.x, + y: node.position.y + }; + }); + + const eventMap = new Map(); + edges.forEach((edge: any) => { + const eventId = edge.data.displayData.eventId; + const dto = { + eventId: eventId, + topicDTO: { + topic: edge.data.displayData.topic, + eventName: edge.data.displayData.name + } + }; + eventMap.set(eventId, dto); + }); + const appEventParams = Array.from(eventMap.values()); + + updateAppFlowData(appFlowParams); + if (appEventParams.length > 0) { + for (const item of appEventParams) { + console.log('item:', item); + await sleep(500); + updateAppEventChannel(item); + } + } + } }, [nodes, edges, initialData?.appId]); // 运行处理函数 From 3562e259c6c08e27650da217d66efbcdc35151b5 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 16:08:53 +0800 Subject: [PATCH 13/24] =?UTF-8?q?feat(ide):=20=E6=B7=BB=E5=8A=A0=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E8=BF=90=E8=A1=8C=E6=97=A5=E5=BF=97=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ideContainer/index.tsx | 14 ++++++- src/pages/ideContainer/logBar.tsx | 66 +++++++++++++++++++++++++------ 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index ce6f8c6..5a5583f 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -82,7 +82,7 @@ function IDEContainer() { // 处理节点状态更新 if (socketMessage?.nodeLog) { - const { nodeId, state } = socketMessage.nodeLog; + const { nodeId, state, runLog } = socketMessage.nodeLog; // 将状态映射为前端使用的状态 let status = 'waiting'; switch (state) { @@ -101,6 +101,18 @@ function IDEContainer() { } // 更新节点状态 dispatch(updateNodeStatus({ nodeId, status })); + + // 只有当存在runLog时才发送日志到logBar + if (runLog) { + const logEvent = new CustomEvent('logMessage', { + detail: { + type: 'runtime', + message: runLog, + timestamp: new Date().toISOString() + } + }); + document.dispatchEvent(logEvent); + } } } }); diff --git a/src/pages/ideContainer/logBar.tsx b/src/pages/ideContainer/logBar.tsx index d089bf9..e345749 100644 --- a/src/pages/ideContainer/logBar.tsx +++ b/src/pages/ideContainer/logBar.tsx @@ -30,8 +30,8 @@ const data = [ }, { key: '3', - title: '流程运行日志', - content: '流程运行时日志...' + title: '运行数据', + content: '运行数据日志...' }, { key: '4', @@ -47,6 +47,8 @@ const LogBar: React.FC = () => { const { logBarStatus } = useSelector((state) => state.ideContainer); const dispatch = useDispatch(); const [validationLogs, setValidationLogs] = useState([]); + const [runtimeLogs, setRuntimeLogs] = useState([]); // 添加运行时日志状态 + const [logContainerHeight, setLogContainerHeight] = useState('250px'); // 添加日志容器高度状态 // 处理 Tab 点击事件 const handleTabClick = (key: string) => { @@ -64,9 +66,9 @@ const LogBar: React.FC = () => { // 当 collapsed 状态改变时,直接更新元素的样式 useEffect(() => { if (resizeBoxRef.current) { - resizeBoxRef.current.style.height = logBarStatus ? '250px' : '0px'; + resizeBoxRef.current.style.height = logBarStatus ? logContainerHeight : '0px'; } - }, [logBarStatus]); + }, [logBarStatus, logContainerHeight]); // 处理 ResizeBox 手动调整大小事件 const handleResize = (e: MouseEvent, size: { @@ -79,6 +81,8 @@ const LogBar: React.FC = () => { } else { dispatch(updateLogBarStatus(true)); + // 更新日志容器高度状态 + setLogContainerHeight(`${size.height}px`); } }; @@ -86,7 +90,7 @@ const LogBar: React.FC = () => { useEffect(() => { const handleLogMessage = (event: CustomEvent) => { const { type, message, timestamp } = event.detail; - + // 如果是校验类型的消息且当前校验日志tab可见,则添加到校验日志中 if (type === 'validation') { const newLog: LogMessage = { @@ -95,18 +99,33 @@ const LogBar: React.FC = () => { message, timestamp }; - + setValidationLogs(prev => [...prev, newLog]); - + // 自动切换到校验日志tab并展开logBar setActiveTab('2'); dispatch(updateLogBarStatus(true)); } + // 如果是运行时日志 + else if (type === 'runtime') { + const newLog: LogMessage = { + id: Date.now(), + type, + message, + timestamp + }; + + setRuntimeLogs(prev => [...prev, newLog]); + + // 自动切换到运行日志tab并展开logBar + setActiveTab('1'); + dispatch(updateLogBarStatus(true)); + } }; // 添加事件监听器 document.addEventListener('logMessage', handleLogMessage as EventListener); - + // 清理事件监听器 return () => { document.removeEventListener('logMessage', handleLogMessage as EventListener); @@ -116,7 +135,7 @@ const LogBar: React.FC = () => { // 渲染校验日志内容 const renderValidationLogs = () => { return ( -
+
{validationLogs.length === 0 ? (

暂无校验日志

) : ( @@ -135,6 +154,28 @@ const LogBar: React.FC = () => { ); }; + // 渲染运行时日志内容 + const renderRuntimeLogs = () => { + return ( +
+ {runtimeLogs.length === 0 ? ( +

暂无运行时日志

+ ) : ( + runtimeLogs.map(log => ( +
+
+ {new Date(log.timestamp).toLocaleString()} +
+
+ {log.message} +
+
+ )) + )} +
+ ); + }; + return ( <> = () => { className={styles.logBar} directions={['top']} style={{ - height: logBarStatus ? '250px' : '0px' + height: logBarStatus ? logContainerHeight : '0px' }} onMoving={handleResize} > @@ -150,10 +191,13 @@ const LogBar: React.FC = () => { type="card-gutter" activeTab={activeTab} onClickTab={handleTabClick} + justify={true} > {tabs.map((x) => ( - {x.key === '2' ? renderValidationLogs() : x.content} + {x.key === '1' ? renderRuntimeLogs() : + x.key === '2' ? renderValidationLogs() : + x.content} ))} From aaa568f9a5a92b71ecde142e6d0e0c96d379760d Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 16:18:05 +0800 Subject: [PATCH 14/24] =?UTF-8?q?feat(flow):=20=E8=BF=90=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E7=BC=96=E8=BE=91=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useFlowCallbacks.ts | 1 + src/pages/flowEditor/FlowEditorMain.tsx | 57 ++++++++++++++----------- src/pages/ideContainer/index.tsx | 16 +++---- src/store/ideContainer.ts | 10 ++++- 4 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index 94a3379..e32167f 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -94,6 +94,7 @@ export const useFlowCallbacks = ( }, 100); } }, [nodes, edges]); + // 边变更处理 const onEdgesChange = useCallback((changes: any) => { const newEdges = applyEdgeChanges(changes, edges); diff --git a/src/pages/flowEditor/FlowEditorMain.tsx b/src/pages/flowEditor/FlowEditorMain.tsx index 8f178cf..9a705ed 100644 --- a/src/pages/flowEditor/FlowEditorMain.tsx +++ b/src/pages/flowEditor/FlowEditorMain.tsx @@ -178,12 +178,17 @@ const FlowEditorMain: React.FC = (props) => { onContextMenu={(e) => e.preventDefault()}> ({...node, draggable: !isRunning}))} // 运行时禁用节点拖拽 edges={edges} nodeTypes={nodeTypes} edgeTypes={edgeTypes} snapToGrid={true} snapGrid={[2, 2]} + nodesConnectable={!isRunning} // 运行时禁用节点连接 + nodesDraggable={!isRunning} // 运行时禁用节点拖拽 + elementsSelectable={!isRunning} // 运行时禁用元素选择 + connectOnClick={!isRunning} // 运行时禁用点击连接 + disableKeyboardA11y={isRunning} // 运行时禁用键盘交互 onBeforeDelete={async ({ nodes }) => { // 检查是否有开始或结束节点 const hasStartOrEndNode = nodes.some(node => node.type === 'start' || node.type === 'end'); @@ -198,7 +203,7 @@ const FlowEditorMain: React.FC = (props) => { ); // 允许删除操作继续进行 - return true; + return !isRunning; // 运行时禁止删除节点 }} onNodesDelete={(deleted) => { console.log('deleted:', deleted); @@ -259,21 +264,21 @@ const FlowEditorMain: React.FC = (props) => { setIsEditModalOpen(false); }} - onNodesChange={onNodesChange} - onEdgesChange={onEdgesChange} - onConnect={onConnect} - onReconnect={onReconnect} - onDrop={onDrop} - onDragOver={onDragOver} - onNodeDrag={onNodeDrag} + onNodesChange={!isRunning ? onNodesChange : undefined} // 运行时禁用节点变更 + onEdgesChange={!isRunning ? onEdgesChange : undefined} // 运行时禁用边变更 + onConnect={!isRunning ? onConnect : undefined} // 运行时禁用连接 + onReconnect={!isRunning ? onReconnect : undefined} // 运行时禁用重新连接 + onDragOver={!isRunning ? onDragOver : undefined} // 运行时禁用拖拽 + onDrop={!isRunning ? onDrop : undefined} // 运行时禁用放置 + onNodeDrag={!isRunning ? onNodeDrag : undefined} // 运行时禁用节点拖拽 connectionLineType={ConnectionLineType.SmoothStep} connectionLineComponent={CustomConnectionLine} - onNodeDragStop={onNodeDragStop} - onNodeContextMenu={onNodeContextMenu} - onEdgeContextMenu={onEdgeContextMenu} - onNodeClick={onNodeDoubleClick} - onPaneClick={onPaneClick} - onPaneContextMenu={onPaneContextMenu} + onNodeDragStop={!isRunning ? onNodeDragStop : undefined} // 运行时禁用节点拖拽停止 + onNodeContextMenu={!isRunning ? onNodeContextMenu : undefined} // 运行时禁用节点上下文菜单 + onNodeDoubleClick={!isRunning ? onNodeDoubleClick : undefined} // 运行时禁用节点双击 + onEdgeContextMenu={!isRunning ? onEdgeContextMenu : undefined} // 运行时禁用边上下文菜单 + onPaneClick={!isRunning ? onPaneClick : undefined} // 运行时禁用面板点击 + onPaneContextMenu={!isRunning ? onPaneContextMenu : undefined} // 运行时禁用面板上下文菜单 onEdgeMouseEnter={(_event, edge) => { setEdges((eds) => eds.map(e => { if (e.id === edge.id) { @@ -291,12 +296,12 @@ const FlowEditorMain: React.FC = (props) => { })); }} fitView - selectionKeyCode={['Meta', 'Control']} - selectionMode={SelectionMode.Partial} - panOnDrag={[0, 1, 2]} // 支持多点触控平移 - zoomOnScroll={true} - zoomOnPinch={true} - panOnScrollSpeed={0.5} + selectionOnDrag={!isRunning} // 运行时禁用拖拽选择 + selectionMode={!isRunning ? SelectionMode.Partial : undefined} // 运行时禁用选择模式 + panOnDrag={!isRunning ? [0, 1, 2] : []} // 运行时禁用拖拽平移 + zoomOnScroll={!isRunning} // 运行时禁用滚轮缩放 + zoomOnPinch={!isRunning} // 运行时禁用捏合缩放 + panOnScrollSpeed={!isRunning ? 0.5 : 0} // 运行时禁用滚动平移 > @@ -315,7 +320,7 @@ const FlowEditorMain: React.FC = (props) => { {/*节点右键上下文*/} - {menu && menu.type === 'node' && ( + {!isRunning && menu && menu.type === 'node' && (
= (props) => { )} {/*边右键上下文*/} - {menu && menu.type === 'edge' && ( + {!isRunning && menu && menu.type === 'edge' && (
= (props) => { )} {/*画布右键上下文*/} - {menu && menu.type === 'pane' && ( + {!isRunning && menu && menu.type === 'pane' && (
= (props) => { {/*统一的添加节点菜单*/} - {(edgeForNodeAdd || positionForNodeAdd) && ( + {!isRunning && (edgeForNodeAdd || positionForNodeAdd) && (
{ - const { nodeId, status } = payload; - state.nodeStatusMap[nodeId] = status; + const { nodeId, status, actionType } = payload; + // 如果是运行时更新,不记录到历史记录中 + if (actionType !== 'RUNTIME_UPDATE') { + state.nodeStatusMap[nodeId] = status; + } else { + // 对于运行时更新,我们仍然更新状态但标记为运行时状态 + state.nodeStatusMap[nodeId] = status; + } }, // 重置节点状态 resetNodeStatus: (state) => { From 03976ab0cc63b38228fd5ae35e3b7358edc1c0f7 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 16:30:31 +0800 Subject: [PATCH 15/24] =?UTF-8?q?chore(flow):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E6=97=A5=E5=BF=97=E5=92=8C=E5=86=97=E4=BD=99?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useFlowCallbacks.ts | 1 - src/pages/flowEditor/FlowEditorMain.tsx | 8 +------- src/pages/ideContainer/index.tsx | 3 +-- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index e32167f..f24844e 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -480,7 +480,6 @@ export const useFlowCallbacks = ( }; localStorage.setItem('copiedNode', JSON.stringify(nodeData)); - console.log('复制节点:', node); }, [initialData?.appId]); // 粘贴节点 diff --git a/src/pages/flowEditor/FlowEditorMain.tsx b/src/pages/flowEditor/FlowEditorMain.tsx index 9a705ed..2573032 100644 --- a/src/pages/flowEditor/FlowEditorMain.tsx +++ b/src/pages/flowEditor/FlowEditorMain.tsx @@ -178,7 +178,7 @@ const FlowEditorMain: React.FC = (props) => { onContextMenu={(e) => e.preventDefault()}> ({...node, draggable: !isRunning}))} // 运行时禁用节点拖拽 + nodes={nodes.map(node => ({ ...node, draggable: !isRunning }))} // 运行时禁用节点拖拽 edges={edges} nodeTypes={nodeTypes} edgeTypes={edgeTypes} @@ -206,8 +206,6 @@ const FlowEditorMain: React.FC = (props) => { return !isRunning; // 运行时禁止删除节点 }} onNodesDelete={(deleted) => { - console.log('deleted:', deleted); - // 检查是否有循环节点 const loopNodes = deleted.filter(node => node.data?.type === 'LOOP_START' || node.data?.type === 'LOOP_END' @@ -298,10 +296,6 @@ const FlowEditorMain: React.FC = (props) => { fitView selectionOnDrag={!isRunning} // 运行时禁用拖拽选择 selectionMode={!isRunning ? SelectionMode.Partial : undefined} // 运行时禁用选择模式 - panOnDrag={!isRunning ? [0, 1, 2] : []} // 运行时禁用拖拽平移 - zoomOnScroll={!isRunning} // 运行时禁用滚轮缩放 - zoomOnPinch={!isRunning} // 运行时禁用捏合缩放 - panOnScrollSpeed={!isRunning ? 0.5 : 0} // 运行时禁用滚动平移 > diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index c0cc23d..fe10bad 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -75,8 +75,7 @@ function IDEContainer() { console.error('WebSocket错误:', event); }, onMessage: (event) => { - console.log('收到WebSocket消息:', event.data); - // 这里可以处理从后端收到的消息,例如日志更新等 + // console.log('收到WebSocket消息:', event.data); const socketMessage = JSON.parse(event.data); if (socketMessage?.socketId) dispatch(updateSocketId(socketMessage.socketId)); From 4c4df84c9167f03b41ce6bb899f07b794d1d5997 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 16:46:44 +0800 Subject: [PATCH 16/24] =?UTF-8?q?chore(code):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=9C=AA=E4=BD=BF=E7=94=A8=E7=9A=84=E6=92=A4=E9=94=80=E9=87=8D?= =?UTF-8?q?=E5=81=9A=E6=8C=89=E9=92=AE=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/flowEditor/components/actionBar.tsx | 46 +++++++++---------- src/pages/ideContainer/index.tsx | 2 +- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/pages/flowEditor/components/actionBar.tsx b/src/pages/flowEditor/components/actionBar.tsx index 3ba45f9..93fc5e7 100644 --- a/src/pages/flowEditor/components/actionBar.tsx +++ b/src/pages/flowEditor/components/actionBar.tsx @@ -64,29 +64,29 @@ const ActionBar: React.FC = ({ 日志 - - - - + {/**/} + {/* }*/} + {/* onClick={onUndo}*/} + {/* disabled={!canUndo}*/} + {/* status="danger"*/} + {/* style={{ padding: '0 8px', backgroundColor: '#fff' }}*/} + {/* >*/} + {/* 撤销*/} + {/* */} + {/* }*/} + {/* onClick={onRedo}*/} + {/* disabled={!canRedo}*/} + {/* style={{ padding: '0 8px', backgroundColor: '#fff' }}*/} + {/* >*/} + {/* 重做*/} + {/* */} + {/**/} )}
diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index fe10bad..a8a9194 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { updateSocketId, updateNodeStatus, updateIsRunning, resetNodeStatus } from '@/store/ideContainer'; import useWebSocket from '@/hooks/useWebSocket'; -import { isJSON ,getUrlParams} from '@/utils/common'; +import { isJSON, getUrlParams } from '@/utils/common'; import styles from './style/index.module.less'; import SideBar from './sideBar'; From 6338511741ac93d84c620b8509f2813e219cd7c8 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 17:19:55 +0800 Subject: [PATCH 17/24] =?UTF-8?q?pref(ideContainer):=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E9=A1=B5=E5=92=8C=E8=8F=9C=E5=8D=95=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ideContainer/index.tsx | 3 ++ src/pages/ideContainer/navBar.tsx | 35 ++++++++++----- src/pages/ideContainer/sideBar.tsx | 70 ++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index a8a9194..168c13d 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -371,6 +371,9 @@ function IDEContainer() { key: menuItem.key, parentKey: menuItem.parentKey }); + + // 将选中的tab添加到已打开的tabs集合中 + setOpenedTabs(prev => new Set(prev).add(menuItem.key)); } } else { diff --git a/src/pages/ideContainer/navBar.tsx b/src/pages/ideContainer/navBar.tsx index 0461c2e..2f8c7ea 100644 --- a/src/pages/ideContainer/navBar.tsx +++ b/src/pages/ideContainer/navBar.tsx @@ -8,8 +8,8 @@ const TabPane = Tabs.TabPane; interface NavBarProps { selected?: Selected; menuData?: any[]; - onTabChange?: (path: string) => void; - onTabClose?: (path: string) => void; + onTabChange?: (key: string) => void; + onTabClose?: (key: string) => void; } // 添加ref类型定义 @@ -55,7 +55,7 @@ const NavBar: React.ForwardRefRenderFunction = ({ const title = selected.title; const pathTitle = selected?.pathTitle || null; // 检查tab是否已存在 - const existingTab = tabs.find(tab => tab.key === (key) && tab.title === title); + const existingTab = tabs.find(tab => tab.key === key); if (!existingTab) { // 创建新tab @@ -76,20 +76,31 @@ const NavBar: React.ForwardRefRenderFunction = ({ setActiveTab(key); } } + else if (!selected?.path && tabs.length > 0) { + // 如果没有选中的路径但有tabs存在,保持当前激活的tab + // 这样可以避免在切换tab时意外清除activeTab + } }, [selected, menuData]); const handleDeleteTab = (key: string) => { const newTabs = tabs.filter(tab => tab.key !== key); setTabs(newTabs); - // 如果删除的是当前激活的tab,激活第一个tab(如果存在) - if (key === activeTab && newTabs.length > 0) { - setActiveTab(newTabs[0].key); - onTabChange?.(newTabs[0].key); - } - else if (key === activeTab && newTabs.length === 0) { - setActiveTab(''); - onTabChange?.(''); + // 如果删除的是当前激活的tab,激活下一个tab(如果存在) + if (key === activeTab) { + if (newTabs.length > 0) { + // 尝试激活相邻的tab + const currentIndex = tabs.findIndex(tab => tab.key === key); + const nextIndex = currentIndex > 0 ? currentIndex - 1 : 0; + const nextTab = newTabs[nextIndex]; + + setActiveTab(nextTab.key); + onTabChange?.(nextTab.key); + } else { + // 如果没有更多tabs,重置状态 + setActiveTab(''); + onTabChange?.(''); + } } // 通知父组件tab已关闭 @@ -143,4 +154,4 @@ const NavBar: React.ForwardRefRenderFunction = ({ ); }; -export default React.forwardRef(NavBar); +export default React.forwardRef(NavBar); \ No newline at end of file diff --git a/src/pages/ideContainer/sideBar.tsx b/src/pages/ideContainer/sideBar.tsx index 4c988f0..f3938b3 100644 --- a/src/pages/ideContainer/sideBar.tsx +++ b/src/pages/ideContainer/sideBar.tsx @@ -242,6 +242,20 @@ const SideBar: React.FC = ({ } } + // 监听 subMenuData 和 identity 变化,更新菜单数据 + useEffect(() => { + if (identity === 'scene') { + if (Object.keys(subMenuData).length > 0) { + const newMenu = getMenuData(); + setMenu(newMenu); + } + } + else if (identity === 'componentDevelopment') { + const newMenu = getMenuData(); + setMenu(newMenu); + } + }, [subMenuData, identity]); + // 处理子菜单区域的拖拽调整大小 const handleSubMenuResize = (e: MouseEvent, { width }: { width: number }) => { resizeBoxRef.current.style.width = `${width}px`; @@ -276,6 +290,59 @@ const SideBar: React.FC = ({ onMenuSelect?.({ ...item }); }; + // 监听 selected 状态变化,更新 activeKey + useEffect(() => { + if (menu.length > 0 && selected?.parentKey) { + // 查找匹配的菜单项索引 + const index = menu.findIndex(item => item.key === selected.parentKey); + if (index !== -1) { + setActiveKey(index); + } + } + }, [selected, menu]); + + // 监听 selected 状态变化,确保子菜单正确显示 + useEffect(() => { + if (selected?.key && menuData[identity]) { + // 确保子菜单区域根据selected状态正确展开或收起 + if (['appList', 'appFlow'].includes(selected.parentKey)) { + // 如果应该显示子菜单但当前是收起状态,则展开 + if (isSubMenuCollapsed) { + setIsSubMenuCollapsed(false); + resizeBoxRef.current.style.width = `300px`; + } + } + + // 强制更新filteredMenu以确保显示正确的子菜单 + setSearchValue(''); // 清空搜索值以显示所有项 + } + }, [selected, menuData, identity]); + + // 当菜单数据变化时更新本地状态 + useEffect(() => { + if (identity && menuData[identity]) { + setMenu(menuData[identity]); + } + }, [menuData, identity]); + + // 当 selected 变化时,检查是否需要更新子菜单数据 + useEffect(() => { + if (selected?.parentKey === 'appList' && selected?.id) { + // 检查当前菜单数据是否已加载 + const currentMenu = menuData[identity] || []; + const appParent = currentMenu.find(item => item.key === 'appList'); + if (appParent && appParent.children) { + const appItem = appParent.children.find((item: any) => item.id === selected.id); + if (appItem) { + // 如果应用项没有子菜单数据或者子菜单数据为空,则获取它 + if (!appItem.children || appItem.children.length === 0) { + getProjectEnvData(selected); + } + } + } + } + }, [selected, identity, menuData]); + // 根据搜索值过滤菜单数据 const filteredMenu = useMemo(() => { if (!searchValue || activeKey === undefined || !menu[activeKey]?.children) { @@ -384,6 +451,7 @@ const SideBar: React.FC = ({ // 渲染子菜单 const renderMenuItems = (menuItems?: MenuItemType[], parentKey = '0') => { + console.log('menuItems sidebar', menuItems); if (menuItems && menuItems.length) { return menuItems.map((item, index) => { const key = `${parentKey}-${index}`; @@ -629,6 +697,8 @@ const SideBar: React.FC = ({ }} style={{ background: 'transparent' }} // 移除背景色 renderExtra={selected?.parentKey === 'appList' ? renderNodeExtra : null} + // 当selected或activeKey变化时,强制Tree组件重新渲染 + key={`tree-${activeKey}-${selected?.key || 'none'}`} > {renderMenuItems(filteredMenu[activeKey]?.children)} From 78ff1a9dd2dd3c598ffff19b5c7b011a697c50f9 Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 28 Oct 2025 17:28:49 +0800 Subject: [PATCH 18/24] =?UTF-8?q?pref(sideBar):=20=E7=A7=BB=E9=99=A4Tree?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=B8=AD=E7=9A=84key=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E8=A2=AB=E9=A2=91=E7=B9=81=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ideContainer/sideBar.tsx | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/pages/ideContainer/sideBar.tsx b/src/pages/ideContainer/sideBar.tsx index f3938b3..1e3ca61 100644 --- a/src/pages/ideContainer/sideBar.tsx +++ b/src/pages/ideContainer/sideBar.tsx @@ -325,23 +325,6 @@ const SideBar: React.FC = ({ } }, [menuData, identity]); - // 当 selected 变化时,检查是否需要更新子菜单数据 - useEffect(() => { - if (selected?.parentKey === 'appList' && selected?.id) { - // 检查当前菜单数据是否已加载 - const currentMenu = menuData[identity] || []; - const appParent = currentMenu.find(item => item.key === 'appList'); - if (appParent && appParent.children) { - const appItem = appParent.children.find((item: any) => item.id === selected.id); - if (appItem) { - // 如果应用项没有子菜单数据或者子菜单数据为空,则获取它 - if (!appItem.children || appItem.children.length === 0) { - getProjectEnvData(selected); - } - } - } - } - }, [selected, identity, menuData]); // 根据搜索值过滤菜单数据 const filteredMenu = useMemo(() => { @@ -451,7 +434,6 @@ const SideBar: React.FC = ({ // 渲染子菜单 const renderMenuItems = (menuItems?: MenuItemType[], parentKey = '0') => { - console.log('menuItems sidebar', menuItems); if (menuItems && menuItems.length) { return menuItems.map((item, index) => { const key = `${parentKey}-${index}`; @@ -697,8 +679,6 @@ const SideBar: React.FC = ({ }} style={{ background: 'transparent' }} // 移除背景色 renderExtra={selected?.parentKey === 'appList' ? renderNodeExtra : null} - // 当selected或activeKey变化时,强制Tree组件重新渲染 - key={`tree-${activeKey}-${selected?.key || 'none'}`} > {renderMenuItems(filteredMenu[activeKey]?.children)} From 0f3915bff57da242719752aed60ee73521fc50e3 Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 29 Oct 2025 11:14:55 +0800 Subject: [PATCH 19/24] =?UTF-8?q?style(flowEditor):=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=86=85=E5=AE=B9=E5=B8=83=E5=B1=80=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FlowEditor/node/style/baseOther.module.less | 8 ++++++++ src/pages/flowEditor/components/nodeContentApp.tsx | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/FlowEditor/node/style/baseOther.module.less b/src/components/FlowEditor/node/style/baseOther.module.less index 7732144..e3f2ca2 100644 --- a/src/components/FlowEditor/node/style/baseOther.module.less +++ b/src/components/FlowEditor/node/style/baseOther.module.less @@ -50,6 +50,13 @@ border: 1px solid #cccccc; border-radius: 3px; + .node-inputs { + padding-right: 10px; + } + + .node-outputs { + padding-left: 10px; + } .node-inputs, .node-outputs, @@ -58,6 +65,7 @@ flex: 1; } + .node-outputs-api { .node-input-label { font-size: 12px; diff --git a/src/pages/flowEditor/components/nodeContentApp.tsx b/src/pages/flowEditor/components/nodeContentApp.tsx index de5834c..c85d0e2 100644 --- a/src/pages/flowEditor/components/nodeContentApp.tsx +++ b/src/pages/flowEditor/components/nodeContentApp.tsx @@ -303,6 +303,7 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { <> {/*content栏-api部分*/}
+
{apiIns.length > 0 && (
@@ -325,7 +326,7 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { )} {apiOuts.length > 0 && ( -
+
{apiOuts.map((output, index) => { // 查找关联的事件分组 const group = findApiGroupByTopic(output, eventGroups); From ce375ebc1512697dc7694359ab7605dcf948c998 Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 29 Oct 2025 11:15:09 +0800 Subject: [PATCH 20/24] =?UTF-8?q?pref(utils):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=86=97=E4=BD=99=E7=9A=84=20lineType=20=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/convertAppFlowData.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/convertAppFlowData.ts b/src/utils/convertAppFlowData.ts index 9313f2a..6480375 100644 --- a/src/utils/convertAppFlowData.ts +++ b/src/utils/convertAppFlowData.ts @@ -117,7 +117,6 @@ export const convertAppFlowData = (appFlowData: any[]) => { sourceHandle: sourceEvent.eventName, targetHandle: targetEvent.eventName, type: 'custom', - lineType: 'lineType', data: { displayData: { name: sourceEvent.eventName, From be71426433934ccc2e06ec390b7273c29aedf501 Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 29 Oct 2025 11:16:22 +0800 Subject: [PATCH 21/24] =?UTF-8?q?refactor(ide):=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD=E9=87=8D=E6=9E=84=E6=96=B0?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useFlowCallbacks.ts | 81 ++++++++++++------- src/pages/ideContainer/index.tsx | 8 +- src/pages/ideContainer/sideBar.tsx | 8 +- src/pages/orchestration/application/index.tsx | 12 +-- src/store/ideContainer.ts | 6 ++ 5 files changed, 77 insertions(+), 38 deletions(-) diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index f24844e..d890c30 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -15,7 +15,7 @@ import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData'; import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; import LoopNode from '@/components/FlowEditor/node/loopNode/LoopNode'; -import { updateCanvasDataMap, resetNodeStatus, updateIsRunning } from '@/store/ideContainer'; +import { updateCanvasDataMap, resetNodeStatus, updateIsRunning, updateEventListOld } from '@/store/ideContainer'; import { validateAllNodes, showValidationErrors, @@ -30,10 +30,11 @@ import { projectFlowHandle } from '@/pages/flowEditor/utils/projectFlowHandle'; import { appFLowHandle } from '@/pages/flowEditor/utils/appFlowhandle'; import { Dispatch } from 'redux'; -import { runMainFlow } from '@/api/apps'; +import { runMainFlow, stopApp } from '@/api/apps'; import store from '@/store'; import { updateAppEvent, updateAppEventChannel, updateAppFlowData } from '@/api/appEvent'; import { sleep } from '@/utils/common'; +import { queryEventItemBySceneIdOld } from '@/api/event'; export const useFlowCallbacks = ( nodes: Node[], @@ -1004,7 +1005,7 @@ export const useFlowCallbacks = ( const emptyEvent = eventList.find(item => item.topic.includes('**empty**')); newNode.data.component = { type: nodeType, - customDef: { eventId: emptyEvent.eventId, name: emptyEvent.name, topic: emptyEvent.topic } + customDef: { eventId: emptyEvent?.eventId ?? null, name: emptyEvent.name, topic: emptyEvent.topic } }; } // 将未定义的节点动态追加进nodeTypes @@ -1080,27 +1081,29 @@ export const useFlowCallbacks = ( // 事件接收节点 params.eventListenes.push({ nodeName: nodeConfig.nodeName || '', - eventId: eventConfig?.eventId || '', + eventId: eventConfig?.eventId || null, topic: eventConfig?.topic || '', eventName: eventConfig?.name || '', - dataOuts: nodeConfig.dataOuts || [] + dataOuts: nodeConfig.dataOuts || [], + nodeId: nodeConfig.nodeId }); } else if (nodeType === 'EVENTSEND') { // 事件发送节点 params.eventSends.push({ nodeName: nodeConfig.nodeName || '', - eventId: eventConfig?.eventId || '', + eventId: eventConfig?.eventId || null, topic: eventConfig?.topic || '', eventName: eventConfig?.name || '', - dataIns: nodeConfig.dataIns || [] + dataIns: nodeConfig.dataIns || [], + nodeId: nodeConfig.nodeId }); } } }); // 调用更新事件的API if (params.eventListenes.length > 0 || params.eventSends.length > 0) { - updateAppEvent(appid, params); + return params; } }; const upDatePublish = async (revertedData) => { @@ -1139,20 +1142,23 @@ export const useFlowCallbacks = ( const revertedData = revertFlowData(nodes, edges); const upDatePublishCB = await upDatePublish(revertedData.nodeConfigs); const newRevertedData = reverseConvertFlowData(nodes, edges, upDatePublishCB); - const { flowData, currentAppData } = store.getState().ideContainer; - // console.log('revertedData:', revertedData); - // console.log('newRevertedData:', newRevertedData); + const { flowData, currentAppData, info } = store.getState().ideContainer; let params = {}; // 更新复合组件/子流程 if (currentAppData.key.includes('sub')) { + const appEventDefinition = updateEvent(revertedData.nodeConfigs, initialData.appId); params = { ...currentAppData?.compData || {}, - components: newRevertedData + components: newRevertedData, + appEventDefinition, + sceneId: info.id }; - updateEvent(revertedData.nodeConfigs, currentAppData.parentAppId); const res: any = await setSubFlowNew(params, currentAppData.parentAppId); if (res.code === 200) { Message.success('保存成功'); + // 更新事件枚举表 + const res1: any = await queryEventItemBySceneIdOld(info.id); + if (res1.code === 200) dispatch(updateEventListOld(res1.data)); } else { Message.error(res.message); @@ -1160,14 +1166,19 @@ export const useFlowCallbacks = ( } // 更新主流程 else { + const appEventDefinition = updateEvent(revertedData.nodeConfigs, initialData.appId); params = { ...flowData[currentAppData.id]?.main || {}, - components: newRevertedData + components: newRevertedData, + appEventDefinition, + sceneId: info.id }; - updateEvent(revertedData.nodeConfigs, initialData.appId); const res: any = await setMainFlowNew(params, initialData.appId); if (res.code === 200) { Message.success('保存成功'); + // 更新事件枚举表 + const res1: any = await queryEventItemBySceneIdOld(info.id); + if (res1.code === 200) dispatch(updateEventListOld(res1.data)); } else { Message.error(res.message); @@ -1196,33 +1207,45 @@ export const useFlowCallbacks = ( const eventMap = new Map(); edges.forEach((edge: any) => { - const eventId = edge.data.displayData.eventId; - const dto = { - eventId: eventId, - topicDTO: { - topic: edge.data.displayData.topic, - eventName: edge.data.displayData.name - } - }; - eventMap.set(eventId, dto); + // 应用组件的桩点id就是事件id + const sourceId = edge.source; + const targetId = edge.target; + const topic = edge.data.displayData.topic; + + if (eventMap.has(topic)) { + // 如果topic已存在,将eventId添加到数组中 + eventMap.get(topic).eventId.push(sourceId); + eventMap.get(topic).eventId.push(targetId); + } + else { + // 如果topic不存在,创建新的条目 + eventMap.set(topic, { + eventId: [sourceId, targetId], + topic: topic + }); + } }); - const appEventParams = Array.from(eventMap.values()); + // 对eventId数组进行去重处理 + const appEventParams = Array.from(eventMap.values()).map(item => ({ + ...item, + eventId: Array.from(new Set(item.eventId)) + })); + + console.log('appEventParams:', appEventParams); updateAppFlowData(appFlowParams); if (appEventParams.length > 0) { for (const item of appEventParams) { - console.log('item:', item); await sleep(500); updateAppEventChannel(item); } } - } }, [nodes, edges, initialData?.appId]); // 运行处理函数 const handleRun = useCallback(async (running: boolean) => { + const { currentAppData, socketId } = store.getState().ideContainer; if (running) { - const { currentAppData, socketId } = store.getState().ideContainer; // 启动运行 const params = { appId: currentAppData.id, @@ -1250,6 +1273,8 @@ export const useFlowCallbacks = ( // 设置运行状态为false dispatch(updateIsRunning(false)); + stopApp(currentAppData.id); + // 停止运行 setEdges((eds) => eds.map(edge => ({ ...edge, diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index 168c13d..ef0fff0 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useRef } from 'react'; import { useSelector, useDispatch } from 'react-redux'; -import { updateSocketId, updateNodeStatus, updateIsRunning, resetNodeStatus } from '@/store/ideContainer'; +import { updateSocketId, updateNodeStatus, updateEventListOld } from '@/store/ideContainer'; import useWebSocket from '@/hooks/useWebSocket'; import { isJSON, getUrlParams } from '@/utils/common'; @@ -31,7 +31,7 @@ import ComponentDeployment from '@/pages/componentDevelopment/componentDeploymen import ComponentTest from '@/pages/componentDevelopment/componentTest'; import { getUserToken } from '@/api/user'; import { Message } from '@arco-design/web-react'; -import { queryEventItemBySceneId } from '@/api/event'; +import { queryEventItemBySceneId, queryEventItemBySceneIdOld } from '@/api/event'; type UrlParamsOptions = { identity?: string; @@ -220,7 +220,9 @@ function IDEContainer() { const getEvent = async () => { const res: any = await queryEventItemBySceneId(urlParams.id); + const res1: any = await queryEventItemBySceneIdOld(urlParams.id); if (res.code === 200) dispatch(updateEventList(res.data)); + if (res1.code === 200) dispatch(updateEventListOld(res1.data)); }; useEffect(() => { @@ -371,7 +373,7 @@ function IDEContainer() { key: menuItem.key, parentKey: menuItem.parentKey }); - + // 将选中的tab添加到已打开的tabs集合中 setOpenedTabs(prev => new Set(prev).add(menuItem.key)); } diff --git a/src/pages/ideContainer/sideBar.tsx b/src/pages/ideContainer/sideBar.tsx index 1e3ca61..6792e45 100644 --- a/src/pages/ideContainer/sideBar.tsx +++ b/src/pages/ideContainer/sideBar.tsx @@ -17,11 +17,12 @@ import { menuData1, menuData2 } from './config/menuData'; import { IconSearch, IconPlus } from '@arco-design/web-react/icon'; import { Selected } from '@/pages/ideContainer/types'; import { useDispatch, useSelector } from 'react-redux'; -import { updateMenuData, updateFlowData, updateCurrentAppData } from '@/store/ideContainer'; +import { updateMenuData, updateFlowData, updateCurrentAppData, updateEventListOld } from '@/store/ideContainer'; import { addApp, getProjectEnv, editApp, deleteApp } from '@/api/apps'; import _ from 'lodash'; import { getAppInfoNew } from '@/api/appRes'; import { getAppEventData } from '@/api/appEvent'; +import { queryEventItemBySceneIdOld } from '@/api/event'; const TreeNode = Tree.Node; const FormItem = Form.Item; @@ -191,7 +192,7 @@ const SideBar: React.FC = ({ }); // 添加右键菜单状态 const resizeBoxRef = useRef(null); // 引用第一个 ResizeBox 容器 const contextMenuRef = useRef(null); // 右键菜单引用 - const { menuData } = useSelector(state => state.ideContainer); + const { menuData, info } = useSelector(state => state.ideContainer); const dispatch = useDispatch(); function getMenuData(): MenuItemType[] { @@ -429,6 +430,9 @@ const SideBar: React.FC = ({ newMenu[activeKey] = { ...newMenu[activeKey], children: currentMenu[index].children }; return newMenu; }); + // 获取最新的事件枚举表 + const res1: any = await queryEventItemBySceneIdOld(info.id); + if (res1.code === 200) dispatch(updateEventListOld(res1.data)); } }; diff --git a/src/pages/orchestration/application/index.tsx b/src/pages/orchestration/application/index.tsx index d169cb2..c9c1f2e 100644 --- a/src/pages/orchestration/application/index.tsx +++ b/src/pages/orchestration/application/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import FlowEditor from '@/pages/flowEditor/index'; import { useSelector, useDispatch } from 'react-redux'; import { getAppEventList } from '@/api/appEvent'; -import { getTopicList } from '@/api/event'; +import { getTopicList, queryEventItemBySceneId } from '@/api/event'; import { updateEventTopicList } from '@/store/ideContainer'; const ApplicationContainer = () => { @@ -16,12 +16,14 @@ const ApplicationContainer = () => { }; const getEventList = async () => { - const res: any = await getTopicList(info.id); + const res: any = await queryEventItemBySceneId(info.id); if (res.code === 200) { - dispatch(updateEventTopicList(res.data.map(v => { - return { label: v.eventName, value: v.topic }; - }))); + dispatch(updateEventTopicList(res.data + .filter(v => !v.topic.includes('**empty**')) // 过滤掉topic包含**empty**的项目 + .map(v => { + return { label: v.name, value: v.topic }; + }))); } }; diff --git a/src/store/ideContainer.ts b/src/store/ideContainer.ts index ed11136..bfd9c99 100644 --- a/src/store/ideContainer.ts +++ b/src/store/ideContainer.ts @@ -8,6 +8,7 @@ interface IDEContainerState { canvasDataMap: any; projectComponentData: any; currentAppData: any; + eventListOld: any; eventList: any; eventTopicList: any; logBarStatus?: boolean; @@ -24,6 +25,7 @@ const initialState: IDEContainerState = { canvasDataMap: {}, // 每个画布的缓存信息 projectComponentData: {}, // 工程下的组件列表 currentAppData: {}, // 当前选中的应用数据 + eventListOld: [], // 工程下的事件列表 eventList: [], // 工程下的事件列表 eventTopicList: [], // 应用编排使用的事件名和topic列表 logBarStatus: false, @@ -58,6 +60,9 @@ const ideContainerSlice = createSlice({ updateEventList(state, action) { state.eventList = action.payload; }, + updateEventListOld(state, action) { + state.eventListOld = action.payload; + }, updateEventTopicList(state, action) { state.eventTopicList = action.payload; }, @@ -98,6 +103,7 @@ export const { updateProjectComponentData, updateCurrentAppData, updateEventList, + updateEventListOld, updateEventTopicList, updateLogBarStatus, updateSocketId, From f856a0db4fc6f121adcbcbb17c521552e85d394a Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 29 Oct 2025 11:16:56 +0800 Subject: [PATCH 22/24] =?UTF-8?q?refactor(flow):=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E9=80=89=E6=8B=A9=E5=99=A8=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E8=8A=82=E7=82=B9=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除未使用的 specialOptions 状态- 修改事件匹配逻辑,使用 topic 替代 eventId 进行查找 - 更新事件选择下拉框的选项键值为 topicId - 修正事件描述字段名称从 desc 到 description - 在节点内容组件中引入 Redux 状态以获取事件列表- 调整事件显示逻辑,确保能正确展示事件名称 -优化 footer 格式化函数以兼容旧版事件数据结构 --- .../FlowEditor/nodeEditors/components/EventSelect.tsx | 10 ++++------ src/pages/flowEditor/components/nodeContentOther.tsx | 11 +++++++---- src/pages/orchestration/event/index.tsx | 6 +++--- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx b/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx index 1c3a1f2..749721f 100644 --- a/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx +++ b/src/components/FlowEditor/nodeEditors/components/EventSelect.tsx @@ -24,7 +24,6 @@ const typeMap = { const EventSelect: React.FC = ({ nodeData, eventList, type, onRefresh, onUpdateData }) => { const [options, setOptions] = useState([]); - const [specialOptions, setSpecialOptions] = useState({}); const [form] = Form.useForm(); const [showModal, setShowModal] = useState(false); const [currentEvent, setCurrentEvent] = useState(null); @@ -32,7 +31,6 @@ const EventSelect: React.FC = ({ nodeData, eventList, type, on useEffect(() => { if (nodeData && eventList && eventList.length > 0) { - setSpecialOptions(eventList.find(item => item.topic.includes('**empty**'))); setOptions(eventList.filter(item => !item.topic.includes('**empty**'))); try { const customDef = JSON.parse(nodeData.component?.customDef); @@ -41,7 +39,7 @@ const EventSelect: React.FC = ({ nodeData, eventList, type, on setCurrentEvent(null); } else { - setCurrentEvent(eventList.find(item => customDef.eventId === item.eventId)); + setCurrentEvent(eventList.find(item => customDef.topic === item.topic)); } } catch (e) { // 先判断topic是不是**empty**,是就不设置currentevent @@ -49,7 +47,7 @@ const EventSelect: React.FC = ({ nodeData, eventList, type, on setCurrentEvent(null); } else { - setCurrentEvent(eventList.find(item => nodeData.component?.customDef.eventId === item.eventId)); + setCurrentEvent(eventList.find(item => nodeData.component?.customDef.topic === item.topic)); } } } @@ -85,7 +83,7 @@ const EventSelect: React.FC = ({ nodeData, eventList, type, on const data = { type: typeMap[type], customDef: { - eventId: e.eventId, + eventId: null, name: e.name, topic: e.topic } @@ -126,7 +124,7 @@ const EventSelect: React.FC = ({ nodeData, eventList, type, on dropdownMenuStyle={{ maxHeight: 300 }} > {options.map((option) => ( - ))} diff --git a/src/pages/flowEditor/components/nodeContentOther.tsx b/src/pages/flowEditor/components/nodeContentOther.tsx index c5b086a..456c1ff 100644 --- a/src/pages/flowEditor/components/nodeContentOther.tsx +++ b/src/pages/flowEditor/components/nodeContentOther.tsx @@ -3,6 +3,7 @@ import styles from '@/components/FlowEditor/node/style/baseOther.module.less'; import { Handle, Position, useStore } from '@xyflow/react'; import { deserializeValue, isJSON } from '@/utils/common'; import cronstrue from 'cronstrue/i18n'; +import { useSelector } from 'react-redux'; interface NodeContentData { parameters?: { @@ -178,7 +179,7 @@ const renderRegularNodeHandles = (dataIns: any[], dataOuts: any[], apiIns: any[] ); }; -const formatFooter = (data: any) => { +const formatFooter = (data: any, eventListOld = []) => { try { switch (data?.type) { case 'WAIT': @@ -192,9 +193,10 @@ const formatFooter = (data: any) => { return cronstrue.toString(intervalSeconds, { locale: 'zh_CN' }); case 'EVENTSEND': case 'EVENTLISTENE': - const { name, topic } = isJSON(data.customDef) ? JSON.parse(data.customDef) : data.customDef; + const { eventId, topic, name } = isJSON(data.customDef) ? JSON.parse(data.customDef) : data.customDef; if (topic.includes('**empty**')) return ''; - return `事件: ${name}`; + const currentEvent = eventListOld.length > 0 ? eventListOld.find(item => item.eventId === eventId) : { name: '无' }; + return `事件: ${name || currentEvent.name}`; case 'BASIC': return data.compIdentifier ? `当前实例:${data.compIdentifier}` : ''; default: @@ -206,6 +208,7 @@ const formatFooter = (data: any) => { }; const NodeContent = ({ data }: { data: NodeContentData }) => { + const { eventListOld } = useSelector((state) => state.ideContainer); const apiIns = data.parameters?.apiIns || []; const apiOuts = data.parameters?.apiOuts || []; const dataIns = data.parameters?.dataIns || []; @@ -284,7 +287,7 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { {/*footer栏*/} {showFooter && (
- {formatFooter(footerData)} + {formatFooter(footerData, eventListOld)}
)} diff --git a/src/pages/orchestration/event/index.tsx b/src/pages/orchestration/event/index.tsx index 2a8e5ea..dd0d51a 100644 --- a/src/pages/orchestration/event/index.tsx +++ b/src/pages/orchestration/event/index.tsx @@ -106,7 +106,7 @@ const HandleModal = ({ visible, onChangeVisible, onRefresh }) => { { return eventData.filter(item => { const name = item.name || ''; const topic = item.topic || ''; - const desc = item.description || ''; + const description = item.description || ''; const searchLower = searchValue.toLowerCase(); return ( name.toLowerCase().includes(searchLower) || topic.toLowerCase().includes(searchLower) || - desc.toLowerCase().includes(searchLower) + description.toLowerCase().includes(searchLower) ); }); }, [eventData, searchValue]); From 171205d183de69571b76bdb30f24b0cf2a21fb8c Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 29 Oct 2025 11:17:21 +0800 Subject: [PATCH 23/24] =?UTF-8?q?feat(api):=20=E5=A2=9E=E5=8A=A0=E6=96=B0a?= =?UTF-8?q?pi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/apps.ts | 4 ++-- src/api/event.ts | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/api/apps.ts b/src/api/apps.ts index 9755f07..b437b82 100644 --- a/src/api/apps.ts +++ b/src/api/apps.ts @@ -86,8 +86,8 @@ export function resumeApp(data: any) { } // 停止 -export function stopApp(data: any) { - return axios.post(`${runPrefix}/apps/${data.id}/stop`); +export function stopApp(appid: any) { + return axios.post(`${runPrefix}/apps/${appid}/stop`); } // APi发布 diff --git a/src/api/event.ts b/src/api/event.ts index 34db91a..a84104e 100644 --- a/src/api/event.ts +++ b/src/api/event.ts @@ -35,9 +35,13 @@ export function queryEventItem(name: string) { } // 事件管理-使用场景ID查询事件 -export function queryEventItemBySceneId(sceneId: string) { +export function queryEventItemBySceneIdOld(sceneId: string) { return axios.get(`${urlPrefix}/event/${sceneId}/get`); } +// 事件管理-使用场景ID查询事件新 +export function queryEventItemBySceneId(sceneId: string) { + return axios.get(`${urlPrefix}/event/${sceneId}/getTopic`); +} // 事件管理-获取工程下可用的topic export function getTopicList(id: string) { From afcf4b07cf7b3c83ef6d410f54a4ffe2be76064b Mon Sep 17 00:00:00 2001 From: ZLY Date: Wed, 29 Oct 2025 14:35:40 +0800 Subject: [PATCH 24/24] =?UTF-8?q?fix(flow):=20=E6=9B=B4=E6=96=B0=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=8F=A5=E6=9F=84=E6=A0=87=E8=AF=86=E7=AC=A6=E4=BB=A5?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=20eventId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useFlowCallbacks.ts | 7 +- .../flowEditor/components/nodeContentApp.tsx | 97 ++----------------- src/utils/convertAppFlowData.ts | 4 +- 3 files changed, 12 insertions(+), 96 deletions(-) diff --git a/src/hooks/useFlowCallbacks.ts b/src/hooks/useFlowCallbacks.ts index d890c30..7111c32 100644 --- a/src/hooks/useFlowCallbacks.ts +++ b/src/hooks/useFlowCallbacks.ts @@ -1105,6 +1105,7 @@ export const useFlowCallbacks = ( if (params.eventListenes.length > 0 || params.eventSends.length > 0) { return params; } + else return null; }; const upDatePublish = async (revertedData) => { const { currentAppData } = store.getState().ideContainer; @@ -1208,8 +1209,8 @@ export const useFlowCallbacks = ( const eventMap = new Map(); edges.forEach((edge: any) => { // 应用组件的桩点id就是事件id - const sourceId = edge.source; - const targetId = edge.target; + const sourceId = edge.sourceHandle; + const targetId = edge.targetHandle; const topic = edge.data.displayData.topic; if (eventMap.has(topic)) { @@ -1231,8 +1232,6 @@ export const useFlowCallbacks = ( eventId: Array.from(new Set(item.eventId)) })); - console.log('appEventParams:', appEventParams); - updateAppFlowData(appFlowParams); if (appEventParams.length > 0) { for (const item of appEventParams) { diff --git a/src/pages/flowEditor/components/nodeContentApp.tsx b/src/pages/flowEditor/components/nodeContentApp.tsx index c85d0e2..635b82c 100644 --- a/src/pages/flowEditor/components/nodeContentApp.tsx +++ b/src/pages/flowEditor/components/nodeContentApp.tsx @@ -43,82 +43,6 @@ const handleStyles = { } }; -// 渲染特殊节点(开始/结束节点)的句柄 -const renderSpecialNodeHandles = (isStartNode: boolean, isEndNode: boolean, dataIns: any[], dataOuts: any[], apiIns: any[], apiOuts: any[]) => { - const renderStartNodeHandles = () => { - if (!isStartNode) return null; - - return ( - <> - {apiOuts.map((_, index) => ( - - ))} - {dataOuts.length > 0 && dataOuts.map((_, index) => ( - - ))} - - ); - }; - - const renderEndNodeHandles = () => { - if (!isEndNode) return null; - - return ( - <> - {apiIns.map((_, index) => ( - - ))} - {dataIns.length > 0 && dataIns.map((_, index) => ( - - ))} - - ); - }; - - return ( - <> - {renderStartNodeHandles()} - {renderEndNodeHandles()} - - ); -}; - // 渲染普通节点的句柄 const renderRegularNodeHandles = (dataIns: any[], dataOuts: any[], apiIns: any[], apiOuts: any[]) => { return ( @@ -128,7 +52,7 @@ const renderRegularNodeHandles = (dataIns: any[], dataOuts: any[], apiIns: any[] key={`api-output-handle-${index}`} type="source" position={Position.Right} - id={apiOuts[index].name || apiOuts[index].id || `output-${index}`} + id={apiOuts[index].eventId || `output-${index}`} style={{ ...handleStyles.mainSource, top: `${35 + index * 20}px` @@ -140,7 +64,7 @@ const renderRegularNodeHandles = (dataIns: any[], dataOuts: any[], apiIns: any[] key={`api-input-handle-${index}`} type="target" position={Position.Left} - id={apiIns[index].name || apiIns[index].id || `input-${index}`} + id={apiIns[index].eventId || `input-${index}`} style={{ ...handleStyles.mainTarget, top: `${35 + index * 20}px` @@ -294,11 +218,6 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { // 获取事件分组信息 const eventGroups = useEventGroups(data.component); - // 判断节点类型 - const isStartNode = data.type === 'start'; - const isEndNode = data.type === 'end'; - const isSpecialNode = isStartNode || isEndNode; - return ( <> {/*content栏-api部分*/} @@ -312,7 +231,7 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { const group = findApiGroupByTopic(input, eventGroups); return (
{ const group = findApiGroupByTopic(output, eventGroups); return (
{ {/*content栏-data部分*/}
- {dataIns.length > 0 && !isStartNode && ( + {dataIns.length > 0 && (
{dataIns.map((input, index) => { // 查找关联的事件分组 @@ -374,7 +293,7 @@ const NodeContent = ({ data }: { data: NodeContentData }) => {
)} - {dataOuts.length > 0 && !isEndNode && ( + {dataOuts.length > 0 && (
{dataOuts.map((output, index) => { // 查找关联的事件分组 @@ -407,9 +326,7 @@ const NodeContent = ({ data }: { data: NodeContentData }) => { {/*)}*/} {/* 根据节点类型渲染不同的句柄 */} - {isSpecialNode - ? renderSpecialNodeHandles(isStartNode, isEndNode, dataIns, dataOuts, apiIns, apiOuts) - : renderRegularNodeHandles(dataIns, dataOuts, apiIns, apiOuts)} + {renderRegularNodeHandles(dataIns, dataOuts, apiIns, apiOuts)} ); }; diff --git a/src/utils/convertAppFlowData.ts b/src/utils/convertAppFlowData.ts index 6480375..7fc6e0d 100644 --- a/src/utils/convertAppFlowData.ts +++ b/src/utils/convertAppFlowData.ts @@ -114,8 +114,8 @@ export const convertAppFlowData = (appFlowData: any[]) => { id: `e-${sourceNode.id}-${targetNode.id}-${outIndex}-${inIndex}`, source: sourceNode.id, target: targetNode.id, - sourceHandle: sourceEvent.eventName, - targetHandle: targetEvent.eventName, + sourceHandle: sourceEvent.eventId, + targetHandle: targetEvent.eventId, type: 'custom', data: { displayData: {