pref: 优化状态指示器的渲染时机

master
钟良源 3 weeks ago
parent bc02892413
commit 52c55b5988

@ -2,11 +2,58 @@ import { useState, useRef, useEffect, useMemo } from 'react';
import { Node, Edge } from '@xyflow/react';
import { debounce } from 'lodash';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { updateCanvasDataMap } from '@/store/ideContainer';
import { updateCanvasDataMap, updateNodeStatus } from '@/store/ideContainer';
import { getCurrentAppKey } from '@/utils/flow/runtime';
import { getNodeData } from '@/api/appIns';
import { Dispatch } from 'redux';
const getRuntimeNodeStatus = (state: any) => {
switch (state) {
case 0:
case '0':
return 'running';
case 1:
case '1':
return 'success';
case -1:
case '-1':
return 'failed';
default:
return '';
}
};
const collectRuntimeNodes = (runtimeData: any) => {
if (!runtimeData) {
return [];
}
if (Array.isArray(runtimeData)) {
return runtimeData.flatMap((item) => {
if (Array.isArray(item?.nodes)) {
return item.nodes;
}
return item?.nodeId || item?.id ? [item] : [];
});
}
if (Array.isArray(runtimeData?.main?.nodeLogs)) {
return runtimeData.main.nodeLogs;
}
if (Array.isArray(runtimeData?.nodes)) {
return runtimeData.nodes;
}
if (Array.isArray(runtimeData?.data)) {
return collectRuntimeNodes(runtimeData.data);
}
return [];
};
export const useFlowEditorState = (initialData?: any, readOnly?: boolean) => {
const [nodes, setNodes] = useState<Node[]>([]);
const [edges, setEdges] = useState<Edge[]>([]);
@ -46,6 +93,11 @@ export const useFlowEditorState = (initialData?: any, readOnly?: boolean) => {
// 在组件顶部添加历史记录相关状态
const [historyInitialized, setHistoryInitialized] = useState(false);
const historyTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const syncedRuntimeKeyRef = useRef('');
const currentRunId =
currentAppKey && appRuntimeData[currentAppKey]
? appRuntimeData[currentAppKey].runId
: '';
// 更新节点状态将从store获取的状态应用到节点上
useEffect(() => {
@ -112,6 +164,70 @@ export const useFlowEditorState = (initialData?: any, readOnly?: boolean) => {
readOnly,
]);
useEffect(() => {
if (
readOnly ||
!currentAppKey ||
!currentAppIsRunning ||
!currentRunId ||
nodes.length === 0
) {
return;
}
const syncKey = `${currentAppKey}:${currentRunId}`;
if (syncedRuntimeKeyRef.current === syncKey) {
return;
}
let canceled = false;
syncedRuntimeKeyRef.current = syncKey;
const syncRuntimeNodeStatus = async () => {
try {
const nodeDataRes: any = await getNodeData(currentRunId);
const runtimeData = nodeDataRes?.data || nodeDataRes;
const runtimeNodes = collectRuntimeNodes(runtimeData);
if (canceled || runtimeNodes.length === 0) {
return;
}
runtimeNodes.forEach((node) => {
const nodeId = node?.nodeId || node?.id;
const status = getRuntimeNodeStatus(node?.state);
if (nodeId && status) {
dispatch(updateNodeStatus({
nodeId,
status,
appId: currentAppKey,
actionType: 'RUNTIME_RECONNECT_SYNC',
}));
}
});
} catch (error) {
if (!canceled) {
syncedRuntimeKeyRef.current = '';
console.error('同步运行实例节点状态失败:', error);
}
}
};
syncRuntimeNodeStatus();
return () => {
canceled = true;
};
}, [
currentAppKey,
currentAppIsRunning,
currentRunId,
dispatch,
nodes.length,
readOnly,
]);
const updateCanvasDataMapDebounced = useRef(
debounce(
(

@ -64,6 +64,22 @@ const ALL_PATHS = [
'systemResource', 'appGuide'
];
const getRuntimeNodeStatus = (state: any) => {
switch (state) {
case 0:
case '0':
return 'running';
case 1:
case '1':
return 'success';
case -1:
case '-1':
return 'failed';
default:
return '';
}
};
function IDEContainer() {
const [selected, setSelected] = useState<Selected>({});
const [urlParams, setUrlParams] = useState<UrlParamsOptions>({});
@ -94,25 +110,10 @@ function IDEContainer() {
// 处理节点状态更新
if (socketMessage?.nodeLog) {
const { nodeId, state, runLog, appId } = socketMessage.nodeLog;
// 将状态映射为前端使用的状态
let status = 'waiting';
switch (state) {
case 0: // 运行中
status = 'running';
break;
case 1: // 运行成功
status = 'success';
break;
case -1: // 运行失败
status = 'failed';
break;
default:// 等待运行
status = 'waiting';
break;
}
const status = getRuntimeNodeStatus(state);
// 更新节点状态使用特殊的actionType标记这是运行时状态更新
// 如果后端提供了 appId则传递给 action 以确保更新正确的应用状态
if (nodeId) {
if (nodeId && status) {
dispatch(updateNodeStatus({ nodeId, status, appId, actionType: 'RUNTIME_UPDATE' }));
}
@ -160,6 +161,7 @@ function IDEContainer() {
if (!canceled && reconnectResult?.success === false) {
lastReconnectKeyRef.current = '';
Message.error(reconnectResult.message || '运行实例重连失败');
return;
}
} catch (error) {
if (!canceled) {

Loading…
Cancel
Save