feat(flowEditor): 数据流程编辑和保存功能

production
钟良源 7 months ago
parent 24fe10ad54
commit c9cf8a07e8

@ -18,10 +18,9 @@ import {
ConnectionLineType ConnectionLineType
} from '@xyflow/react'; } from '@xyflow/react';
import '@xyflow/react/dist/style.css'; import '@xyflow/react/dist/style.css';
import { Button, Modal } from '@arco-design/web-react';
import { nodeTypeMap, nodeTypes, registerNodeType } from '@/components/FlowEditor/node'; import { nodeTypeMap, nodeTypes, registerNodeType } from '@/components/FlowEditor/node';
import SideBar from './sideBar/sideBar'; import SideBar from './sideBar/sideBar';
import { convertFlowData } from '@/utils/convertFlowData'; import { convertFlowData, revertFlowData } from '@/utils/convertFlowData';
import { exampleFlowData } from '@/pages/flowEditor/test/exampleFlowData'; import { exampleFlowData } from '@/pages/flowEditor/test/exampleFlowData';
import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode'; import LocalNode from '@/components/FlowEditor/node/localNode/LocalNode';
import CustomEdge from './components/customEdge'; import CustomEdge from './components/customEdge';
@ -35,23 +34,24 @@ import ActionBar from './components/actionBar';
import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType'; import { defaultNodeTypes } from '@/components/FlowEditor/node/types/defaultType';
import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData'; import { localNodeData } from '@/pages/flowEditor/sideBar/config/localNodeData';
import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines'; import { useAlignmentGuidelines } from '@/hooks/useAlignmentGuidelines';
import { setMainFlow } from '@/api/appRes';
const edgeTypes: EdgeTypes = { const edgeTypes: EdgeTypes = {
custom: CustomEdge custom: CustomEdge
}; };
const FlowEditorWithProvider: React.FC = () => { const FlowEditorWithProvider: React.FC<{ initialData?: any }> = ({ initialData }) => {
return ( return (
<div style={{ width: '100%', height: '91vh', display: 'flex' }} onContextMenu={(e) => e.preventDefault()}> <div style={{ width: '100%', height: '91vh', display: 'flex' }} onContextMenu={(e) => e.preventDefault()}>
<ReactFlowProvider> <ReactFlowProvider>
{/*<SideBar />*/} {/*<SideBar />*/}
<FlowEditor /> <FlowEditor initialData={initialData} />
</ReactFlowProvider> </ReactFlowProvider>
</div> </div>
); );
}; };
const FlowEditor: React.FC = () => { const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => {
const [nodes, setNodes] = useState<Node[]>([]); const [nodes, setNodes] = useState<Node[]>([]);
const [edges, setEdges] = useState<Edge[]>([]); const [edges, setEdges] = useState<Edge[]>([]);
const reactFlowInstance = useReactFlow(); const reactFlowInstance = useReactFlow();
@ -309,8 +309,8 @@ const FlowEditor: React.FC = () => {
}, [clearGuidelines]); }, [clearGuidelines]);
useEffect(() => { useEffect(() => {
const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(exampleFlowData); const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData);
// 为所有边添加类型 // 为所有边添加类型-
const initialEdges: Edge[] = convertedEdges.map(edge => ({ const initialEdges: Edge[] = convertedEdges.map(edge => ({
...edge, ...edge,
type: 'custom' type: 'custom'
@ -318,7 +318,7 @@ const FlowEditor: React.FC = () => {
setNodes(convertedNodes); setNodes(convertedNodes);
setEdges(initialEdges); setEdges(initialEdges);
}, []); }, [initialData]);
// 监听边的变化,处理添加节点的触发 // 监听边的变化,处理添加节点的触发
useEffect(() => { useEffect(() => {
@ -601,26 +601,10 @@ const FlowEditor: React.FC = () => {
nodes: nodes, nodes: nodes,
edges: edges edges: edges
}; };
// TODO 接口对接后修改后续的更新操作 // 转换会原始数据类型
console.log('flowData:', flowData); const revertedData = revertFlowData(nodes, edges);
return;
// 发送到服务器的示例代码需要根据您的实际API进行调整
const response = await fetch('/api/flow/save', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(flowData)
});
if (response.ok) { const res = await setMainFlow(revertedData, initialData.id);
console.log('Flow data saved successfully');
// 可以添加成功提示
}
else {
console.error('Failed to save flow data');
// 可以添加失败提示
}
} catch (error) { } catch (error) {
console.error('Error saving flow data:', error); console.error('Error saving flow data:', error);
// 可以添加错误提示 // 可以添加错误提示

@ -108,7 +108,7 @@ function IDEContainer() {
const getContentByPath = (path: string) => { const getContentByPath = (path: string) => {
switch (path) { switch (path) {
case 'compFlow': case 'compFlow':
return <ProjectContainer />; return <ProjectContainer selected={selected} />;
case 'appFlow': case 'appFlow':
return <ApplicationContainer />; return <ApplicationContainer />;
case 'compList': case 'compList':

@ -5,7 +5,7 @@ import { menuData1, menuData2 } from './config/menuData';
import { ResizeBox, Tree } from '@arco-design/web-react'; import { ResizeBox, Tree } from '@arco-design/web-react';
import { Selected } from '@/pages/ideContainer/types'; import { Selected } from '@/pages/ideContainer/types';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { updateMenuData } from '@/store/ideContainer'; import { updateMenuData, updateFlowData } from '@/store/ideContainer';
import { getProjectEnv } from '@/api/apps'; import { getProjectEnv } from '@/api/apps';
import _ from 'lodash'; import _ from 'lodash';
@ -138,6 +138,8 @@ const SideBar: React.FC<SideBarProps> = ({ selectedKey, identity, subMenuData, o
// 更新 menuData 中的数据 // 更新 menuData 中的数据
dispatch(updateMenuData({ ...menuData, [identity]: currentMenu })); dispatch(updateMenuData({ ...menuData, [identity]: currentMenu }));
// 更新 flowData 中的数据
dispatch(updateFlowData({ [data.id]: res.data.app }));
// 同时更新本地 menu 状态以触发重新渲染 // 同时更新本地 menu 状态以触发重新渲染
setMenu(prevMenu => { setMenu(prevMenu => {
@ -217,10 +219,10 @@ const SideBar: React.FC<SideBarProps> = ({ selectedKey, identity, subMenuData, o
> >
<Tree <Tree
defaultExpandedKeys={['0-0']} defaultExpandedKeys={['0-0']}
onSelect={(_selectedKeys, info) => { onSelect={async (_selectedKeys, info) => {
const selectedNode = info.node; const selectedNode = info.node;
const originalData = selectedNode.props.dataRef; const originalData = selectedNode.props.dataRef;
getProjectEnvData(originalData); await getProjectEnvData(originalData);
// 保持主菜单的选中状态 // 保持主菜单的选中状态
const mainMenuKey = `${menu[activeKey]?.key}`; const mainMenuKey = `${menu[activeKey]?.key}`;
setMainMenuSelectedKey(mainMenuKey); setMainMenuSelectedKey(mainMenuKey);

@ -1,9 +1,17 @@
import React from 'react'; import React, { useEffect, useState } from 'react';
import FlowEditor from '@/pages/flowEditor/index'; import FlowEditor from '@/pages/flowEditor/index';
import { useSelector } from 'react-redux';
const ProjectContainer = ({ selected }) => {
const { flowData } = useSelector(state => state.ideContainer);
const [selectedFlowData, setSelectedFlowData] = useState<any>({});
useEffect(() => {
setSelectedFlowData(flowData[selected.id]);
}, [selected]);
const ProjectContainer = () => {
return ( return (
<FlowEditor /> <FlowEditor initialData={selectedFlowData} />
); );
}; };

Loading…
Cancel
Save