fix: 看板拓扑网元状态改为ws数据获取
This commit is contained in:
@@ -233,10 +233,11 @@ function handleRanderChart(
|
|||||||
|
|
||||||
function fnChangeData(data: any[], itemID: string) {
|
function fnChangeData(data: any[], itemID: string) {
|
||||||
let info = data.find((item: any) => item.id === itemID);
|
let info = data.find((item: any) => item.id === itemID);
|
||||||
if (!info.neState.online) {
|
if (!info.neState.online) return;
|
||||||
info = data.find((item: any) => item.id === 'OMC');
|
// if (!info.neState.online) {
|
||||||
graphNodeClickID.value = 'OMC';
|
// info = data.find((item: any) => item.id === itemID);
|
||||||
}
|
// graphNodeClickID.value = itemID;
|
||||||
|
// }
|
||||||
// console.log(info.id);
|
// console.log(info.id);
|
||||||
// console.log(info.neState.cpu.nfCpuUsage);
|
// console.log(info.neState.cpu.nfCpuUsage);
|
||||||
// console.log(info.neState.cpu.sysCpuUsage);
|
// console.log(info.neState.cpu.sysCpuUsage);
|
||||||
|
|||||||
@@ -1,62 +1,26 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, ref, onBeforeUnmount } from 'vue';
|
import { onMounted, ref, onBeforeUnmount } from 'vue';
|
||||||
import { PageContainer } from 'antdv-pro-layout';
|
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
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 { message } from 'ant-design-vue/lib';
|
||||||
import { getGraphData } from '@/api/monitor/topology';
|
import { getGraphData } from '@/api/monitor/topology';
|
||||||
import { parseDateToStr } from '@/utils/date-utils';
|
import { Graph, GraphData, Tooltip } from '@antv/g6';
|
||||||
import { Graph, GraphData, Menu, Tooltip } from '@antv/g6';
|
import { edgeLineAnimateState } from '@/views/monitor/topologyBuild/hooks/registerEdge';
|
||||||
|
import { nodeImageAnimateState } from '@/views/monitor/topologyBuild/hooks/registerNode';
|
||||||
import {
|
import {
|
||||||
edgeCubicAnimateCircleMove,
|
graphG6,
|
||||||
edgeCubicAnimateLineDash,
|
graphState,
|
||||||
edgeLineAnimateState,
|
graphNodeClickID,
|
||||||
} from '@/views/monitor/topologyBuild/hooks/registerEdge';
|
notNeNodes,
|
||||||
import {
|
} from '../../hooks/useTopology';
|
||||||
nodeCircleAnimateShapeR,
|
|
||||||
nodeCircleAnimateShapeStroke,
|
|
||||||
nodeImageAnimateState,
|
|
||||||
nodeRectAnimateState,
|
|
||||||
} from '@/views/monitor/topologyBuild/hooks/registerNode';
|
|
||||||
import { graphState, graphNodeClickID } from '../../hooks/useTopology';
|
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import useWS from '../../hooks/useWS';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
// const { graphState } = useTopology();
|
const { wsSend } = useWS();
|
||||||
|
|
||||||
/**图DOM节点实例对象 */
|
/**图DOM节点实例对象 */
|
||||||
const graphG6Dom = ref<HTMLElement | undefined>(undefined);
|
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({
|
const graphNodeTooltip = new Tooltip({
|
||||||
offsetX: 10,
|
offsetX: 10,
|
||||||
@@ -129,13 +93,16 @@ function handleRanderGraph(
|
|||||||
if (!container) return;
|
if (!container) return;
|
||||||
const { clientHeight, clientWidth } = container;
|
const { clientHeight, clientWidth } = container;
|
||||||
|
|
||||||
|
edgeLineAnimateState();
|
||||||
|
nodeImageAnimateState();
|
||||||
|
|
||||||
const graph = new Graph({
|
const graph = new Graph({
|
||||||
container: container,
|
container: container,
|
||||||
width: clientWidth,
|
width: clientWidth,
|
||||||
height: clientHeight - 36,
|
height: clientHeight - 36,
|
||||||
fitCenter: true,
|
fitCenter: true,
|
||||||
fitView: true,
|
fitView: true,
|
||||||
fitViewPadding: [40],
|
fitViewPadding: [20],
|
||||||
autoPaint: true,
|
autoPaint: true,
|
||||||
modes: {
|
modes: {
|
||||||
default: ['drag-canvas', 'zoom-canvas'],
|
default: ['drag-canvas', 'zoom-canvas'],
|
||||||
@@ -282,97 +249,22 @@ const stateTimeout = ref<any>(null);
|
|||||||
/**查询网元状态 */
|
/**查询网元状态 */
|
||||||
async function fnGetState() {
|
async function fnGetState() {
|
||||||
clearTimeout(stateTimeout.value);
|
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;
|
if (notNeNodes.includes(node.id)) continue;
|
||||||
const { neType, neId, neName } = node.neInfo;
|
const { neType, neId } = node.neInfo;
|
||||||
if (!neType || !neId) continue;
|
if (!neType || !neId) continue;
|
||||||
const result = await stateNe(neType, neId);
|
wsSend({
|
||||||
if (result.code === RESULT_CODE_SUCCESS) {
|
requestId: `neState_${neType}_${neId}`,
|
||||||
// 更新网元状态
|
type: 'ne_state',
|
||||||
const newNeState = Object.assign(node.neState, result.data, {
|
data: {
|
||||||
refreshTime: parseDateToStr(result.data.refreshTime, 'HH:mm:ss'),
|
neType: neType,
|
||||||
});
|
neId: neId,
|
||||||
|
},
|
||||||
// 通过 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置边状态
|
stateTimeout.value = setTimeout(() => fnGetState(), 10_000);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -1,5 +1,22 @@
|
|||||||
|
import { parseDateToStr } from '@/utils/date-utils';
|
||||||
import { computed, reactive, ref } from 'vue';
|
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>>({
|
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');
|
export const graphNodeClickID = ref<string>('UPF');
|
||||||
|
|
||||||
@@ -24,3 +44,91 @@ export const graphNodeState = computed(() =>
|
|||||||
neState: item.neState,
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { parseSizeFromBytes } from '@/utils/parse-utils';
|
import { parseSizeFromBytes } from '@/utils/parse-utils';
|
||||||
import { reactive, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
type TFType = {
|
type TFType = {
|
||||||
/**上行 N3 */
|
/**上行 N3 */
|
||||||
@@ -33,6 +33,5 @@ export function upfTFParse(data: Record<string, string>) {
|
|||||||
return { up, down };
|
return { up, down };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**UPF-总流量数 选中 */
|
/**UPF-总流量数 选中 */
|
||||||
export const upfTFActive = ref<number>(0);
|
export const upfTFActive = ref<number>(0);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
cdrEventParse,
|
cdrEventParse,
|
||||||
} from './useCDREvent';
|
} from './useCDREvent';
|
||||||
import { upfTotalFlow, upfTFParse } from './useUPFTotalFlow';
|
import { upfTotalFlow, upfTFParse } from './useUPFTotalFlow';
|
||||||
|
import { neStateParse } from './useTopology';
|
||||||
|
|
||||||
/**websocket连接 */
|
/**websocket连接 */
|
||||||
export default function useWS() {
|
export default function useWS() {
|
||||||
@@ -38,6 +39,15 @@ export default function useWS() {
|
|||||||
console.warn(res.msg);
|
console.warn(res.msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!requestId) return;
|
||||||
|
|
||||||
|
// 网元状态
|
||||||
|
if (requestId.startsWith('neState')) {
|
||||||
|
const neType = requestId.split('_')[1];
|
||||||
|
neStateParse(neType, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 普通信息
|
// 普通信息
|
||||||
switch (requestId) {
|
switch (requestId) {
|
||||||
// ueEvent UE会话事件
|
// ueEvent UE会话事件
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onBeforeUnmount, onMounted, reactive, ref } from 'vue';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
import Topology from './components/Topology/index.vue';
|
import Topology from './components/Topology/index.vue';
|
||||||
import NeResources from './components/NeResources/index.vue';
|
import NeResources from './components/NeResources/index.vue';
|
||||||
@@ -43,6 +43,9 @@ let onlineInfo: {
|
|||||||
const viewportDom = ref<HTMLElement | null>(null);
|
const viewportDom = ref<HTMLElement | null>(null);
|
||||||
const { isFullscreen, toggle } = useFullscreen(viewportDom);
|
const { isFullscreen, toggle } = useFullscreen(viewportDom);
|
||||||
|
|
||||||
|
/**10s调度器 */
|
||||||
|
const stateInterval = ref<any>(null);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
Promise.allSettled([
|
Promise.allSettled([
|
||||||
listSub({
|
listSub({
|
||||||
@@ -89,7 +92,7 @@ onMounted(() => {
|
|||||||
upfTFSend(7);
|
upfTFSend(7);
|
||||||
upfTFSend(30);
|
upfTFSend(30);
|
||||||
|
|
||||||
setInterval(() => {
|
stateInterval.value = setInterval(() => {
|
||||||
upfTFActive.value = upfTFActive.value >= 2 ? 0 : upfTFActive.value + 1;
|
upfTFActive.value = upfTFActive.value >= 2 ? 0 : upfTFActive.value + 1;
|
||||||
if (upfTFActive.value === 0) {
|
if (upfTFActive.value === 0) {
|
||||||
upfTFSend(7);
|
upfTFSend(7);
|
||||||
@@ -101,6 +104,10 @@ onMounted(() => {
|
|||||||
}, 10_000);
|
}, 10_000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
clearTimeout(stateInterval.value);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -385,9 +385,11 @@ function wsMessage(res: Record<string, any>) {
|
|||||||
// 图片类型不能填充
|
// 图片类型不能填充
|
||||||
if (node.type.startsWith('image')) {
|
if (node.type.startsWith('image')) {
|
||||||
// 更新节点
|
// 更新节点
|
||||||
graphG6.value.updateItem(item, {
|
if (node.label !== newNeState.neName) {
|
||||||
label: newNeState.neName,
|
graphG6.value.updateItem(item, {
|
||||||
});
|
label: newNeState.neName,
|
||||||
|
});
|
||||||
|
}
|
||||||
// 设置状态
|
// 设置状态
|
||||||
graphG6.value.setItemState(item, 'top-right-dot', stateColor);
|
graphG6.value.setItemState(item, 'top-right-dot', stateColor);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user