You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
flow-playform-react/src/features/workflow/persistence/flowPersistence.ts

267 lines
7.1 KiB
TypeScript

import React from 'react';
import { Edge, Node } from '@xyflow/react';
import { Message } from '@arco-design/web-react';
import { Dispatch } from 'redux';
import { getAppInfoNew, setMainFlowNew, setSubFlowNew } from '@/api/appRes';
import {
updateAppEventChannel,
updateAppFlowData,
} from '@/api/appEvent';
import {
deleteEventPub,
deleteEventSub,
queryEventItemBySceneIdOld,
} from '@/api/event';
import {
updateCanvasDataMap,
updateEventListOld,
updateFlowData,
} from '@/store/ideContainer';
import store from '@/store';
import {
convertFlowData,
reverseConvertFlowData,
revertFlowData,
} from '@/features/workflow/adapters/serverFlowAdapter';
import {
validateAllEdges,
validateAllNodes,
showValidationErrors,
} from '@/components/FlowEditor/nodeEditors/validators/nodeValidators';
import {
handelEventNodeList,
updateEvent,
upDatePublish,
} from '@/pages/flowEditor/utils/common';
import { sleep } from '@/utils/common';
interface SaveWorkflowDataParams {
nodes: Node[];
edges: Edge[];
useDefault: boolean;
initialData: any;
canvasDataMap: any;
dispatch: Dispatch<any>;
setNodes: React.Dispatch<React.SetStateAction<Node[]>>;
setEdges: React.Dispatch<React.SetStateAction<Edge[]>>;
}
export const saveWorkflowData = async ({
nodes,
edges,
useDefault,
initialData,
canvasDataMap,
dispatch,
setNodes,
setEdges,
}: SaveWorkflowDataParams) => {
if (useDefault) {
try {
const nodeValidation = validateAllNodes(nodes);
if (!nodeValidation.isValid) {
showValidationErrors(nodeValidation.errors);
return;
}
const edgeValidation = validateAllEdges(edges, nodes);
if (!edgeValidation.isValid) {
showValidationErrors(edgeValidation.errors);
return;
}
const revertedData = revertFlowData(nodes, edges);
const upDatePublishCB = await upDatePublish(revertedData.nodeConfigs);
const newRevertedData = reverseConvertFlowData(
nodes,
edges,
upDatePublishCB
);
const { flowData, currentAppData, info } =
store.getState().ideContainer;
const { deleteEventSendNodeList, deleteEventlisteneList } =
handelEventNodeList(newRevertedData);
if (currentAppData.key.includes('sub')) {
const appEventDefinition = updateEvent(
revertedData.nodeConfigs,
initialData.appId
);
const params = {
...(currentAppData?.compData || {}),
components: newRevertedData,
appEventDefinition,
sceneId: info.id,
};
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));
const appRes: any = await getAppInfoNew(currentAppData.parentAppId);
dispatch(
updateFlowData({ [currentAppData.parentAppId]: appRes.data })
);
if (appRes.data.main?.components) {
const { nodes: parentNodes, edges: parentEdges } =
convertFlowData(appRes.data.main.components, true);
dispatch(
updateCanvasDataMap({
...canvasDataMap,
[currentAppData.parentAppId]: {
nodes: parentNodes,
edges: parentEdges,
},
})
);
}
dispatch(
updateCanvasDataMap({
...canvasDataMap,
[currentAppData.key]: { nodes, edges },
})
);
} else {
Message.error(res.message);
}
} else {
const appEventDefinition = updateEvent(
revertedData.nodeConfigs,
initialData.appId
);
const params = {
...(flowData[currentAppData.id]?.main || {}),
components: newRevertedData,
appEventDefinition,
sceneId: info.id,
};
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));
dispatch(
updateCanvasDataMap({
...canvasDataMap,
[currentAppData.id]: { nodes, edges },
})
);
const appRes: any = await getAppInfoNew(currentAppData.id);
dispatch(updateFlowData({ [currentAppData.id]: appRes.data }));
if (appRes.data.main?.components) {
const { nodes, edges } = convertFlowData(
appRes.data.main.components,
true
);
setNodes(nodes);
setEdges(edges);
dispatch(
updateCanvasDataMap({
...canvasDataMap,
[currentAppData.id]: { nodes, edges },
})
);
}
} else {
Message.error(res.message);
}
}
if (
deleteEventSendNodeList.length > 0 ||
deleteEventlisteneList.length > 0
) {
deleteEventSendNodeList.length > 0 &&
deleteEventPub({
appId: currentAppData.id,
topics: deleteEventSendNodeList,
});
deleteEventlisteneList.length > 0 &&
deleteEventSub({
appId: currentAppData.id,
topics: deleteEventlisteneList,
});
}
} catch (error) {
console.error('Error saving flow data:', error);
Message.error('保存失败');
}
return;
}
const appFlowParams: any = {
appEventList: {},
eventEdges: [],
};
nodes.forEach((node) => {
appFlowParams.appEventList[node.id] = {
x: node.position.x,
y: node.position.y,
};
});
const eventMap = new Map();
edges.forEach((edge: any) => {
appFlowParams.eventEdges.push({
id: edge.id,
source: edge.source,
target: edge.target,
lineType: 'data',
data: {
displayData: {
...edge.data.displayData,
},
},
});
const sourceId = edge.sourceHandle;
const targetId = edge.targetHandle;
const topic = edge.data.displayData?.topic;
if (eventMap.has(topic)) {
eventMap.get(topic).eventId.push(sourceId);
eventMap.get(topic).eventId.push(targetId);
} else {
eventMap.set(topic, {
eventId: [sourceId, targetId],
topic,
});
}
});
const appEventParams = Array.from(eventMap.values()).map((item) => ({
...item,
eventId: Array.from(new Set(item.eventId)),
}));
try {
updateAppFlowData(appFlowParams);
if (appEventParams.length > 0) {
for (const item of appEventParams) {
if (item.topic) {
await sleep(500);
await updateAppEventChannel(item);
}
}
}
Message.success('保存成功');
} catch (error: any) {
console.error('保存失败:', error);
Message.error('保存失败: ' + error.message);
}
};