feat(flow): 支持复合组件节点类型

- 将节点类型 'BASIC' 更新为 'SUB'以支持复合组件
- 在 appRes API 中新增 refPublish 方法用于引用公开组件
- 更新 convertFlowData 和 flowCommon 工具函数以识别 SUB 类型节点
- 在 FlowEditor 组件中注册并映射 SUB 节点类型及其显示名称
- 移除 setIsRunning 状态及相关逻辑
- 修改 useFlowCallbacks 钩子以处理复合组件的保存和发布逻辑
- 调整节点配置中的 compId 获取方式以兼容 flowHousVO.id
master
钟良源 3 months ago
parent 653d989fa3
commit 3f5f568443

@ -25,6 +25,11 @@ export function setMainFlowNew(data: FlowDefinition, appId: string) {
return axios.post(`${urlPrefix}/appRes/${appId}/updateMainNew`, data); return axios.post(`${urlPrefix}/appRes/${appId}/updateMainNew`, data);
} }
// 引用公开组件到应用组件内
export function refPublish(data) {
return axios.put(`${urlPrefix}/appRes/refPublish`, data);
}
// 新增子流程 // 新增子流程
export function addSub(appId: string, data?: FlowDefinition[]) { export function addSub(appId: string, data?: FlowDefinition[]) {
return axios.post( return axios.post(

@ -15,6 +15,7 @@ export const nodeTypes: NodeTypes = {
start: StartNode, start: StartNode,
end: EndNode, end: EndNode,
BASIC: BasicNode, BASIC: BasicNode,
SUB: BasicNode,
APP: AppNode, APP: AppNode,
CODE: CodeNode, CODE: CodeNode,
IMAGE: ImageNode, IMAGE: ImageNode,
@ -28,6 +29,7 @@ export const nodeTypeMap: Record<string, string> = {
'start': 'start', 'start': 'start',
'end': 'end', 'end': 'end',
'basic': 'BASIC', 'basic': 'BASIC',
'sub': 'SUB',
'app': 'APP', 'app': 'APP',
'code': 'CODE', 'code': 'CODE',
'image': 'IMAGE', 'image': 'IMAGE',
@ -41,6 +43,7 @@ export const nodeTypeNameMap: Record<string, string> = {
'start': '开始节点', 'start': '开始节点',
'end': '结束节点', 'end': '结束节点',
'basic': '基础节点', 'basic': '基础节点',
'sub': '复合节点',
'app': '应用节点', 'app': '应用节点',
'code': '代码节点', 'code': '代码节点',
'image': '图片节点', 'image': '图片节点',

@ -7,7 +7,7 @@ import {
Node, Node,
Edge Edge
} from '@xyflow/react'; } from '@xyflow/react';
import { setMainFlow, setMainFlowNew } from '@/api/appRes'; import { refPublish, setMainFlow, setMainFlowNew } from '@/api/appRes';
import { Message } from '@arco-design/web-react'; import { Message } from '@arco-design/web-react';
import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node'; import { nodeTypeMap, registerNodeType } from '@/components/FlowEditor/node';
import { convertFlowData, reverseConvertFlowData, revertFlowData } from '@/utils/convertFlowData'; import { convertFlowData, reverseConvertFlowData, revertFlowData } from '@/utils/convertFlowData';
@ -60,8 +60,7 @@ export const useFlowCallbacks = (
setEdgeForNodeAdd: React.Dispatch<React.SetStateAction<Edge | null>>, setEdgeForNodeAdd: React.Dispatch<React.SetStateAction<Edge | null>>,
positionForNodeAdd: { x: number, y: number } | null, positionForNodeAdd: { x: number, y: number } | null,
setPositionForNodeAdd: React.Dispatch<React.SetStateAction<{ x: number, y: number } | null>>, setPositionForNodeAdd: React.Dispatch<React.SetStateAction<{ x: number, y: number } | null>>,
setIsDelete: React.Dispatch<React.SetStateAction<boolean>>, setIsDelete: React.Dispatch<React.SetStateAction<boolean>>
setIsRunning: React.Dispatch<React.SetStateAction<boolean>>
) => { ) => {
const { getGuidelines, clearGuidelines } = useAlignmentGuidelines(); const { getGuidelines, clearGuidelines } = useAlignmentGuidelines();
// region 画布操作 // region 画布操作
@ -633,7 +632,7 @@ export const useFlowCallbacks = (
...nodeDefinition.data, ...nodeDefinition.data,
title: nodeDefinition.nodeName, title: nodeDefinition.nodeName,
type: nodeType, type: nodeType,
compId: nodeDefinition.id compId: nodeDefinition.id || nodeDefinition.flowHousVO.id
} }
}; };
@ -750,7 +749,7 @@ export const useFlowCallbacks = (
...nodeDefinition.data, ...nodeDefinition.data,
title: nodeDefinition.nodeName, title: nodeDefinition.nodeName,
type: nodeType, type: nodeType,
compId: nodeDefinition.id compId: nodeDefinition.id || nodeDefinition.flowHousVO.id
} }
}; };
@ -770,7 +769,6 @@ export const useFlowCallbacks = (
customDef: { eventId: emptyEvent.id, name: emptyEvent.name, topic: emptyEvent.topic } customDef: { eventId: emptyEvent.id, name: emptyEvent.name, topic: emptyEvent.topic }
}; };
} }
// 将未定义的节点动态追加进nodeTypes // 将未定义的节点动态追加进nodeTypes
const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key)); const nodeMap = Array.from(Object.values(nodeTypeMap).map(key => key));
// 目前默认添加的都是系统组件/本地组件 // 目前默认添加的都是系统组件/本地组件
@ -867,6 +865,17 @@ export const useFlowCallbacks = (
updateAppEvent(initialData.appId, params); updateAppEvent(initialData.appId, params);
} }
}; };
const upDatePublish = (revertedData) => {
const { currentAppData } = store.getState().ideContainer;
const params = {
appId: currentAppData.id,
publishAppId: []
};
revertedData.forEach(item => {
if (item?.component && item.component.type === 'SUB') params.publishAppId.push(item.component.compId); // 复合组件的这个compId实际上就是flowHousVO里面的id
});
if (params.publishAppId.length > 0) refPublish(params);
};
const saveFlowDataToServer = useCallback(async () => { const saveFlowDataToServer = useCallback(async () => {
if (useDefault) { if (useDefault) {
try { try {
@ -895,7 +904,7 @@ export const useFlowCallbacks = (
components: newRevertedData components: newRevertedData
}; };
// return; // return;
upDatePublish(revertedData.nodeConfigs);
updateEvent(revertedData.nodeConfigs); updateEvent(revertedData.nodeConfigs);
// 旧版数据结构 // 旧版数据结构
// const res: any = await setMainFlow(revertedData, initialData.appId); // const res: any = await setMainFlow(revertedData, initialData.appId);

@ -51,7 +51,6 @@ interface FlowEditorMainProps {
positionForNodeAdd: { x: number, y: number } | null; positionForNodeAdd: { x: number, y: number } | null;
setPositionForNodeAdd: React.Dispatch<React.SetStateAction<{ x: number, y: number } | null>>; setPositionForNodeAdd: React.Dispatch<React.SetStateAction<{ x: number, y: number } | null>>;
isRunning: boolean; isRunning: boolean;
setIsRunning: React.Dispatch<React.SetStateAction<boolean>>;
initialData: any; initialData: any;
canvasDataMap: any; canvasDataMap: any;

@ -59,7 +59,7 @@ const AddNodeMenu: React.FC<AddNodeMenuProps> = ({
return { return {
...v, ...v,
nodeName: v?.main?.name || '复合组件', nodeName: v?.main?.name || '复合组件',
nodeType: 'BASIC', nodeType: 'SUB',
nodeGroup: 'composite', nodeGroup: 'composite',
data: { data: {
parameters: { parameters: {

@ -53,7 +53,6 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini
positionForNodeAdd, positionForNodeAdd,
setPositionForNodeAdd, setPositionForNodeAdd,
isRunning, isRunning,
setIsRunning,
historyInitialized, historyInitialized,
setHistoryInitialized, setHistoryInitialized,
historyTimeoutRef, historyTimeoutRef,
@ -120,8 +119,7 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini
setEdgeForNodeAdd, setEdgeForNodeAdd,
positionForNodeAdd, positionForNodeAdd,
setPositionForNodeAdd, setPositionForNodeAdd,
setIsDelete, setIsDelete
setIsRunning
); );
// 节点右键菜单处理 // 节点右键菜单处理
@ -275,7 +273,6 @@ const FlowEditor: React.FC<{ initialData?: any, useDefault?: boolean }> = ({ ini
positionForNodeAdd={positionForNodeAdd} positionForNodeAdd={positionForNodeAdd}
setPositionForNodeAdd={setPositionForNodeAdd} setPositionForNodeAdd={setPositionForNodeAdd}
isRunning={isRunning} isRunning={isRunning}
setIsRunning={setIsRunning}
initialData={initialData} initialData={initialData}
canvasDataMap={canvasDataMap} canvasDataMap={canvasDataMap}

@ -333,7 +333,6 @@ export const convertFlowData = (flowData: any, useDefault = true) => {
}); });
} }
} }
return { nodes, edges }; return { nodes, edges };
}; };
@ -396,7 +395,7 @@ export const revertFlowData = (nodes: any[], edges: any[]) => {
type: nodeType type: nodeType
}; };
} }
if (['BASIC'].includes(nodeType)) nodeConfig.component.compId = node.data.compId || ''; if (['BASIC', 'SUB'].includes(nodeType)) nodeConfig.component.compId = node.data.compId || '';
// 处理参数信息 // 处理参数信息
const parameters = node.data?.parameters || {}; const parameters = node.data?.parameters || {};
@ -776,6 +775,7 @@ const getCurrentProjectStoreData = () => {
const getNodeComponent = (nodeType: string) => { const getNodeComponent = (nodeType: string) => {
switch (nodeType) { switch (nodeType) {
case 'BASIC': case 'BASIC':
case 'SUB':
return BasicNode; return BasicNode;
case 'SWITCH': case 'SWITCH':
return SwitchNode; return SwitchNode;

@ -81,6 +81,7 @@ const validateDataType = (sourceNode: defaultNodeTypes, targetNode: defaultNodeT
const getNodeComponent = (nodeType: string) => { const getNodeComponent = (nodeType: string) => {
switch (nodeType) { switch (nodeType) {
case 'BASIC': case 'BASIC':
case 'SUB':
return BasicNode; return BasicNode;
case 'SWITCH': case 'SWITCH':
return SwitchNode; return SwitchNode;

Loading…
Cancel
Save