fix: 看板拓扑网元状态改为ws数据获取

This commit is contained in:
TsMask
2024-01-29 19:56:33 +08:00
parent ed77ffc54b
commit b312e5e9b5
7 changed files with 166 additions and 147 deletions

View File

@@ -233,10 +233,11 @@ function handleRanderChart(
function fnChangeData(data: any[], itemID: string) {
let info = data.find((item: any) => item.id === itemID);
if (!info.neState.online) {
info = data.find((item: any) => item.id === 'OMC');
graphNodeClickID.value = 'OMC';
}
if (!info.neState.online) return;
// if (!info.neState.online) {
// info = data.find((item: any) => item.id === itemID);
// graphNodeClickID.value = itemID;
// }
// console.log(info.id);
// console.log(info.neState.cpu.nfCpuUsage);
// console.log(info.neState.cpu.sysCpuUsage);

View File

@@ -1,62 +1,26 @@
<script setup lang="ts">
import { reactive, onMounted, ref, onBeforeUnmount } from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { onMounted, ref, onBeforeUnmount } from 'vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { listNe, stateNe } from '@/api/ne/ne';
import { listNe } from '@/api/ne/ne';
import { message } from 'ant-design-vue/lib';
import { getGraphData } from '@/api/monitor/topology';
import { parseDateToStr } from '@/utils/date-utils';
import { Graph, GraphData, Menu, Tooltip } from '@antv/g6';
import { Graph, GraphData, Tooltip } from '@antv/g6';
import { edgeLineAnimateState } from '@/views/monitor/topologyBuild/hooks/registerEdge';
import { nodeImageAnimateState } from '@/views/monitor/topologyBuild/hooks/registerNode';
import {
edgeCubicAnimateCircleMove,
edgeCubicAnimateLineDash,
edgeLineAnimateState,
} from '@/views/monitor/topologyBuild/hooks/registerEdge';
import {
nodeCircleAnimateShapeR,
nodeCircleAnimateShapeStroke,
nodeImageAnimateState,
nodeRectAnimateState,
} from '@/views/monitor/topologyBuild/hooks/registerNode';
import { graphState, graphNodeClickID } from '../../hooks/useTopology';
graphG6,
graphState,
graphNodeClickID,
notNeNodes,
} from '../../hooks/useTopology';
import useI18n from '@/hooks/useI18n';
import useWS from '../../hooks/useWS';
const { t } = useI18n();
// const { graphState } = useTopology();
const { wsSend } = useWS();
/**图DOM节点实例对象 */
const graphG6Dom = ref<HTMLElement | undefined>(undefined);
/**图状态 */
// const graphState = reactive<Record<string, any>>({
// /**当前图组名 */
// group: '5GC System Architecture2',
// /**图数据 */
// data: {
// combos: [],
// edges: [],
// nodes: [],
// },
// });
/**非网元元素 */
const notNeNodes = [
'5GC',
'DN',
'UE',
'Base',
'lan',
'lan1',
'lan2',
'lan3',
'lan4',
'lan5',
'lan6',
'lan7',
];
/**图实例对象 */
const graphG6 = ref<any>(null);
/**图节点展示 */
const graphNodeTooltip = new Tooltip({
offsetX: 10,
@@ -129,13 +93,16 @@ function handleRanderGraph(
if (!container) return;
const { clientHeight, clientWidth } = container;
edgeLineAnimateState();
nodeImageAnimateState();
const graph = new Graph({
container: container,
width: clientWidth,
height: clientHeight - 36,
fitCenter: true,
fitView: true,
fitViewPadding: [40],
fitViewPadding: [20],
autoPaint: true,
modes: {
default: ['drag-canvas', 'zoom-canvas'],
@@ -282,97 +249,22 @@ const stateTimeout = ref<any>(null);
/**查询网元状态 */
async function fnGetState() {
clearTimeout(stateTimeout.value);
const { combos, edges, nodes } = graphState.data;
// console.log({ combos, edges, nodes })
// 获取节点状态
for (const node of nodes) {
for (const node of graphState.data.nodes) {
if (notNeNodes.includes(node.id)) continue;
const { neType, neId, neName } = node.neInfo;
const { neType, neId } = node.neInfo;
if (!neType || !neId) continue;
const result = await stateNe(neType, neId);
if (result.code === RESULT_CODE_SUCCESS) {
// 更新网元状态
const newNeState = Object.assign(node.neState, result.data, {
refreshTime: parseDateToStr(result.data.refreshTime, 'HH:mm:ss'),
});
// 通过 ID 查询节点实例
const item = graphG6.value.findById(node.id);
if (item) {
const stateColor = newNeState.online ? '#52c41a' : '#f5222d'; // 状态颜色
// 图片类型不能填充
if (node.type.startsWith('image')) {
// 更新节点
graphG6.value.updateItem(item, {
label: neName,
});
// 设置状态
graphG6.value.setItemState(item, 'top-right-dot', stateColor);
} else {
// 更新节点
graphG6.value.updateItem(item, {
label: neName,
// neState: newNeState,
style: {
fill: stateColor, // 填充色
stroke: stateColor, // 填充色
},
// labelCfg: {
// style: {
// fill: '#ffffff', // 标签文本色
// },
// },
});
// 设置状态
graphG6.value.setItemState(item, 'stroke', newNeState.online);
}
}
}
wsSend({
requestId: `neState_${neType}_${neId}`,
type: 'ne_state',
data: {
neType: neType,
neId: neId,
},
});
}
// 设置边状态
for (const edge of edges) {
const edgeSource: string = edge.source;
const edgeTarget: string = edge.target;
const neS = nodes.find((n: any) => n.id === edgeSource);
const neT = nodes.find((n: any) => n.id === edgeTarget);
// console.log(neS, edgeSource, neT, edgeTarget);
// 通过 ID 查询节点实例
const item = graphG6.value.findById(edge.id);
if (neS && neT && item) {
// console.log(
// `${edgeSource} - ${edgeTarget}`,
// neS.neState.online && neT.neState.online
// );
const stateColor =
neS.neState.online && neT.neState.online ? '#000000' : '#ff4d4f'; // 状态颜色
// 更新边
// graphG6.value.updateItem(item, {
// label: `${edgeSource} - ${edgeTarget}`,
// style: {
// stroke: stateColor, // 填充色
// },
// labelCfg: {
// style: {
// fill: '#ffffff', // 标签文本色
// },
// },
// });
// 设置状态
// graphG6.value.setItemState(
// item,
// 'line-dash',
// neS.neState.online && neT.neState.online
// );
}
if (neS && notNeNodes.includes(edgeTarget)) {
}
if (neT && notNeNodes.includes(edgeSource)) {
}
}
stateTimeout.value = setTimeout(() => fnGetState(), 5_000);
stateTimeout.value = setTimeout(() => fnGetState(), 10_000);
}
onMounted(() => {

View File

@@ -1,5 +1,22 @@
import { parseDateToStr } from '@/utils/date-utils';
import { computed, reactive, ref } from 'vue';
/**非网元元素 */
export const notNeNodes = [
'5GC',
'DN',
'UE',
'Base',
'lan',
'lan1',
'lan2',
'lan3',
'lan4',
'lan5',
'lan6',
'lan7',
];
/**图状态 */
export const graphState = reactive<Record<string, any>>({
/**当前图组名 */
@@ -12,6 +29,9 @@ export const graphState = reactive<Record<string, any>>({
},
});
/**图实例对象 */
export const graphG6 = ref<any>(null);
/**图点击选择 */
export const graphNodeClickID = ref<string>('UPF');
@@ -24,3 +44,91 @@ export const graphNodeState = computed(() =>
neState: item.neState,
}))
);
/**neStateParse 网元状态 数据解析 */
export function neStateParse(neType: string, data: Record<string, any>) {
const { combos, edges, nodes } = graphState.data;
const node = nodes.find((item: Record<string, any>) => item.id === neType);
// 更新网元状态
const newNeState = Object.assign(node.neState, data, {
refreshTime: parseDateToStr(data.refreshTime, 'HH:mm:ss'),
online: !!data.cpu,
});
// 通过 ID 查询节点实例
const item = graphG6.value.findById(node.id);
if (item) {
const stateColor = newNeState.online ? '#52c41a' : '#f5222d'; // 状态颜色
// 图片类型不能填充
if (node.type.startsWith('image')) {
// 更新节点
if (node.label !== newNeState.neName) {
graphG6.value.updateItem(item, {
label: newNeState.neName,
});
}
// 设置状态
graphG6.value.setItemState(item, 'top-right-dot', stateColor);
} else {
// 更新节点
graphG6.value.updateItem(item, {
label: newNeState.neName,
// neState: newNeState,
style: {
fill: stateColor, // 填充色
stroke: stateColor, // 填充色
},
// labelCfg: {
// style: {
// fill: '#ffffff', // 标签文本色
// },
// },
});
// 设置状态
graphG6.value.setItemState(item, 'stroke', newNeState.online);
}
}
// 设置边状态
for (const edge of edges) {
const edgeSource: string = edge.source;
const edgeTarget: string = edge.target;
const neS = nodes.find((n: any) => n.id === edgeSource);
const neT = nodes.find((n: any) => n.id === edgeTarget);
// console.log(neS, edgeSource, neT, edgeTarget);
// 通过 ID 查询节点实例
const item = graphG6.value.findById(edge.id);
if (neS && neT && item) {
// console.log(
// `${edgeSource} - ${edgeTarget}`,
// neS.neState.online && neT.neState.online
// );
// const stateColor = neS.neState.online && neT.neState.online ? '#000000' : '#ff4d4f'; // 状态颜色
// 更新边
// graphG6.value.updateItem(item, {
// label: `${edgeSource} - ${edgeTarget}`,
// style: {
// stroke: stateColor, // 填充色
// },
// labelCfg: {
// style: {
// fill: '#ffffff', // 标签文本色
// },
// },
// });
// 设置状态
graphG6.value.setItemState(
item,
'line-dash',
neS.neState.online && neT.neState.online
);
}
if (neS && notNeNodes.includes(edgeTarget)) {
graphG6.value.setItemState(item, 'line-dash', neT.neState.online);
}
if (neT && notNeNodes.includes(edgeSource)) {
graphG6.value.setItemState(item, 'line-dash', neT.neState.online);
}
}
}

View File

@@ -1,5 +1,5 @@
import { parseSizeFromBytes } from '@/utils/parse-utils';
import { reactive, ref } from 'vue';
import { ref } from 'vue';
type TFType = {
/**上行 N3 */
@@ -33,6 +33,5 @@ export function upfTFParse(data: Record<string, string>) {
return { up, down };
}
/**UPF-总流量数 选中 */
export const upfTFActive = ref<number>(0);
export const upfTFActive = ref<number>(0);

View File

@@ -14,6 +14,7 @@ import {
cdrEventParse,
} from './useCDREvent';
import { upfTotalFlow, upfTFParse } from './useUPFTotalFlow';
import { neStateParse } from './useTopology';
/**websocket连接 */
export default function useWS() {
@@ -38,6 +39,15 @@ export default function useWS() {
console.warn(res.msg);
return;
}
if (!requestId) return;
// 网元状态
if (requestId.startsWith('neState')) {
const neType = requestId.split('_')[1];
neStateParse(neType, data);
return;
}
// 普通信息
switch (requestId) {
// ueEvent UE会话事件

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue';
import { onBeforeUnmount, onMounted, reactive, ref } from 'vue';
import useI18n from '@/hooks/useI18n';
import Topology from './components/Topology/index.vue';
import NeResources from './components/NeResources/index.vue';
@@ -43,6 +43,9 @@ let onlineInfo: {
const viewportDom = ref<HTMLElement | null>(null);
const { isFullscreen, toggle } = useFullscreen(viewportDom);
/**10s调度器 */
const stateInterval = ref<any>(null);
onMounted(() => {
Promise.allSettled([
listSub({
@@ -89,7 +92,7 @@ onMounted(() => {
upfTFSend(7);
upfTFSend(30);
setInterval(() => {
stateInterval.value = setInterval(() => {
upfTFActive.value = upfTFActive.value >= 2 ? 0 : upfTFActive.value + 1;
if (upfTFActive.value === 0) {
upfTFSend(7);
@@ -101,6 +104,10 @@ onMounted(() => {
}, 10_000);
});
});
onBeforeUnmount(() => {
clearTimeout(stateInterval.value);
});
</script>
<template>

View File

@@ -385,9 +385,11 @@ function wsMessage(res: Record<string, any>) {
// 图片类型不能填充
if (node.type.startsWith('image')) {
// 更新节点
graphG6.value.updateItem(item, {
label: newNeState.neName,
});
if (node.label !== newNeState.neName) {
graphG6.value.updateItem(item, {
label: newNeState.neName,
});
}
// 设置状态
graphG6.value.setItemState(item, 'top-right-dot', stateColor);
} else {