= {};
res.data.main.nodeLogs.forEach((log: any) => {
// state: 1=成功(success), 0=运行中(running), -1=失败(failed)
if (log.state === 1) {
statusMap[log.nodeId] = 'success';
} else if (log.state === -1) {
statusMap[log.nodeId] = 'failed';
} else if (log.state === 0) {
statusMap[log.nodeId] = 'running';
}
});
setNodeStatusMap(statusMap);
}
// 处理运行数据(input/output)
if (res.data.main?.nodeLogs && Array.isArray(res.data.main.nodeLogs) && res.data.main.nodeLogs.length > 0) {
const dataMap: RuntimeData = {};
res.data.main.nodeLogs.forEach((log: any) => {
if (log.input || log.output) {
dataMap[log.nodeId] = {
nodeName: log.name,
input: log.input || {},
output: log.output || {},
duration: log.duration,
startTime: log.startTime,
endTime: log.endTime,
state: log.state === 1 ? '成功' : log.state === -1 ? '失败' : '运行中'
};
}
});
setRuntimeData(dataMap);
}
}
else {
Message.error(res.msg || '获取实例数据失败');
}
} catch (error) {
console.error('获取实例定义失败:', error);
Message.error('获取实例数据失败');
} finally {
setLoading(false);
}
}, [instanceData?.id]);
// 当 instanceData 变化时,重新获取数据
useEffect(() => {
flowDataRef.current = null; // 重置 ref
fetchInstanceDefinition();
}, [instanceData?.id, fetchInstanceDefinition]);
// 处理 Tab 点击事件
const handleTabClick = (key: string) => {
if (key === activeTab) {
setLogBarExpanded(!logBarExpanded);
}
else {
setActiveTab(key);
setLogBarExpanded(true);
}
};
// 当展开/收起状态改变时,更新元素样式
useEffect(() => {
if (resizeBoxRef.current) {
resizeBoxRef.current.style.height = logBarExpanded ? logContainerHeight : '0px';
}
}, [logBarExpanded, logContainerHeight]);
// 处理 ResizeBox 手动调整大小事件
const handleResize = useCallback((e: MouseEvent, size: { width: number; height: number }) => {
if (size.height <= 40) {
setLogBarExpanded(false);
}
else {
setLogBarExpanded(true);
setLogContainerHeight(`${size.height}px`);
}
}, []);
// 使用 useMemo 创建带有节点状态的 flowData
const flowDataWithStatus = useMemo(() => {
if (!flowData || Object.keys(nodeStatusMap).length === 0) {
return flowData;
}
// 深拷贝 flowData 并注入节点状态
const componentsWithStatus = { ...flowData.components };
Object.keys(nodeStatusMap).forEach((nodeId) => {
if (componentsWithStatus[nodeId]) {
componentsWithStatus[nodeId] = {
...componentsWithStatus[nodeId],
status: nodeStatusMap[nodeId],
isStatusVisible: true // 显示状态指示器
};
}
});
const result = {
...flowData,
components: componentsWithStatus,
main: {
...flowData.main,
components: componentsWithStatus
}
};
return result;
}, [flowData, nodeStatusMap]);
// 渲染运行日志内容
const renderRuntimeLogs = () => {
return (
{runtimeLogs.length === 0 ? (
暂无运行日志
) : (
runtimeLogs.map((log: any) => (
{log.timestamp}
{log.message}
))
)}
);
};
// 定义运行数据表格列
const dataColumns: TableColumnProps[] = [
{
title: '节点',
dataIndex: 'nodeName',
width: 120
},
{
title: '时间',
width: 160,
render: (_: any, record: any) => (
<>
开始 {dayjs(record.startTime).format('MM-DD HH:mm:ss')}
{record.endTime > 0 && 结束 {dayjs(record.endTime).format('MM-DD HH:mm:ss')}}
>
)
},
{
title: '耗时',
dataIndex: 'duration',
width: 80,
render: (_: any, record: any) => (
record.duration > 1000 ?
{formatSeconds((record.duration / 1000).toString())} :
{record.duration}ms
)
},
{
title: '状态',
dataIndex: 'state',
width: 60,
align: 'center',
render: (_: any, record: any) => (
<>
{record.state === 1 && }
{record.state === 0 && }
{record.state === -1 && }
>
)
},
{
title: '输入参数',
dataIndex: 'input',
width: 200,
render: (_: any, record: any) => (
{JSON.stringify(record.input)}
)
},
{
title: '输出参数',
dataIndex: 'output',
width: 200,
render: (_: any, record: any) => (
{JSON.stringify(record.output)}
)
}
];
// 渲染运行数据内容
const renderRuntimeData = () => {
// 将 runtimeData 对象转换为表格数据数组
const tableData = Object.entries(runtimeData).map(([nodeId, data]: [string, any]) => ({
key: nodeId,
nodeId,
nodeName: data.nodeName,
startTime: data.startTime || 0,
endTime: data.endTime || 0,
duration: data.duration,
state: data.state === '成功' ? 1 : data.state === '失败' ? -1 : 0,
input: data.input,
output: data.output
}));
return (
{tableData.length === 0 ? (
暂无运行数据
) : (
)}
);
};
return (
{/* 顶部标题栏 */}
{title && (
{onBack && (
}
onClick={onBack}
className={styles.backButton}
>
返回列表
)}
实例名称:{title}
)}
{/* 主内容区域 */}
{/* 流程画布 */}
{loading ? (
加载中...
) : flowDataWithStatus ? (
) : (
暂无流程数据
)}
{/* 底部日志栏 */}
{renderRuntimeLogs()}
{renderRuntimeData()}
{/* Tab 标签栏(始终可见) */}
{!logBarExpanded && (
)}
);
};
export default InstanceCanvas;