拓扑图修改
This commit is contained in:
@@ -22,18 +22,24 @@ const graphG6Dom = ref<HTMLElement | undefined>(undefined);
|
|||||||
|
|
||||||
/**图节点展示 */
|
/**图节点展示 */
|
||||||
const graphNodeTooltip = new Tooltip({
|
const graphNodeTooltip = new Tooltip({
|
||||||
offsetX: 20,
|
offsetX: 10,
|
||||||
offsetY: 20,
|
offsetY: 20,
|
||||||
getContent(evt) {
|
getContent(evt) {
|
||||||
if (!evt) return t('views.monitor.topologyBuild.graphNotInfo');
|
if (!evt) return t('views.monitor.topologyBuild.graphNotInfo');
|
||||||
const { id, label, neState }: any = evt.item?.getModel();
|
const { id, label, neState, neInfoList, neStateMap }: any = evt.item?.getModel();
|
||||||
if (notNeNodes.includes(id)) {
|
if (notNeNodes.includes(id)) {
|
||||||
return `<div><span>${label || id}</span></div>`;
|
return `<div><span>${label || id}</span></div>`;
|
||||||
}
|
}
|
||||||
if (!neState) {
|
if (!neState) {
|
||||||
return `<div><span>${label || id}</span></div>`;
|
return `<div><span>${label || id}</span></div>`;
|
||||||
}
|
}
|
||||||
return `
|
|
||||||
|
// 获取同类型网元列表
|
||||||
|
const sameTypeNes = neInfoList || [];
|
||||||
|
|
||||||
|
// 如果没有网元或只有一个网元,显示原来的信息
|
||||||
|
if (sameTypeNes.length <= 1) {
|
||||||
|
return `
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -56,7 +62,7 @@ const graphNodeTooltip = new Tooltip({
|
|||||||
<div><strong>${t('views.monitor.topology.name')}:</strong><span>
|
<div><strong>${t('views.monitor.topology.name')}:</strong><span>
|
||||||
${neState.neName ?? '--'}
|
${neState.neName ?? '--'}
|
||||||
</span></div>
|
</span></div>
|
||||||
<div><strong>IP:</strong><span>${neState.neIP}</span></div>
|
<div><strong>IP:</strong><span>${neState.neIP ?? '--'}</span></div>
|
||||||
<div><strong>${t('views.monitor.topology.version')}:</strong><span>
|
<div><strong>${t('views.monitor.topology.version')}:</strong><span>
|
||||||
${neState.version ?? '--'}
|
${neState.version ?? '--'}
|
||||||
</span></div>
|
</span></div>
|
||||||
@@ -65,24 +71,71 @@ const graphNodeTooltip = new Tooltip({
|
|||||||
</span></div>
|
</span></div>
|
||||||
<div><strong>${t('views.monitor.topology.expiryDate')}:</strong><span>
|
<div><strong>${t('views.monitor.topology.expiryDate')}:</strong><span>
|
||||||
${neState.expire ?? '--'}
|
${neState.expire ?? '--'}
|
||||||
</span></div>
|
</span></div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有多个网元,聚合显示
|
||||||
|
let content = `
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 300px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div><strong>${t('views.monitor.topology.state')}:</strong><span>
|
||||||
|
${
|
||||||
|
neState.online
|
||||||
|
? t('views.monitor.topology.normalcy')
|
||||||
|
: t('views.monitor.topology.exceptions')
|
||||||
|
}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.refreshTime')}:</strong><span>
|
||||||
|
${neState.refreshTime ?? '--'}
|
||||||
|
</span></div>
|
||||||
|
<div>========================</div>`;
|
||||||
|
|
||||||
|
// 为每个同类型网元添加信息
|
||||||
|
sameTypeNes.forEach((ne: any, index: number) => {
|
||||||
|
// 获取该网元的状态信息
|
||||||
|
const neStateInfo = neStateMap?.[ne.neId] ||
|
||||||
|
(ne.neId === neState.neId ? neState : {});
|
||||||
|
|
||||||
|
content += `
|
||||||
|
<div style="margin-top: 8px;"><strong>${t('views.monitor.topology.name')}:${ne.neName || id + '_' + ne.neId}</strong></div>
|
||||||
|
<div><strong>ID:</strong><span>${ne.neId || '--'}</span></div>
|
||||||
|
<div><strong>IP:</strong><span>${neStateInfo.neIP || ne.neIP || '--'}</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.version')}:</strong><span>
|
||||||
|
${neStateInfo.version || ne.version || '--'}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.serialNum')}:</strong><span>
|
||||||
|
${neStateInfo.sn || ne.sn || '--'}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.expiryDate')}:</strong><span>
|
||||||
|
${neStateInfo.expire || ne.expire || '--'}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.state')}:</strong><span>
|
||||||
|
${
|
||||||
|
neStateInfo.online !== undefined
|
||||||
|
? (neStateInfo.online
|
||||||
|
? t('views.monitor.topology.normalcy')
|
||||||
|
: t('views.monitor.topology.exceptions'))
|
||||||
|
: '未知'
|
||||||
|
}
|
||||||
|
</span></div>
|
||||||
|
${index < sameTypeNes.length - 1 ? '<div>------------------------</div>' : ''}
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
content += '</div>';
|
||||||
|
return content;
|
||||||
},
|
},
|
||||||
itemTypes: ['node'],
|
itemTypes: ['node'],
|
||||||
});
|
});
|
||||||
|
|
||||||
/**图绑定事件 */
|
|
||||||
function fnGraphEvent(graph: Graph) {
|
|
||||||
// 节点点击
|
|
||||||
graph.on('node:click', evt => {
|
|
||||||
// 获得鼠标当前目标节点
|
|
||||||
const node = evt.item?.getModel();
|
|
||||||
if (node && node.id && !notNeNodes.includes(node.id)) {
|
|
||||||
graphNodeClickID.value = node.id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**图数据渲染 */
|
/**图数据渲染 */
|
||||||
function handleRanderGraph(
|
function handleRanderGraph(
|
||||||
@@ -122,7 +175,6 @@ function handleRanderGraph(
|
|||||||
graph.data(data);
|
graph.data(data);
|
||||||
graph.render();
|
graph.render();
|
||||||
|
|
||||||
fnGraphEvent(graph);
|
|
||||||
|
|
||||||
graphG6.value = graph;
|
graphG6.value = graph;
|
||||||
|
|
||||||
@@ -150,14 +202,14 @@ function handleRanderGraph(
|
|||||||
* 获取图组数据渲染到画布
|
* 获取图组数据渲染到画布
|
||||||
* @param reload 是否重载数据
|
* @param reload 是否重载数据
|
||||||
*/
|
*/
|
||||||
function fnGraphDataLoad(reload: boolean = false) {
|
function fnGraphDataLoad(reload: boolean = false) {
|
||||||
Promise.all([
|
Promise.all([
|
||||||
getGraphData(graphState.group),
|
getGraphData(graphState.group),
|
||||||
listAllNeInfo({
|
listAllNeInfo({
|
||||||
bandStatus: false,
|
bandStatus: false,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
.then(resArr => {
|
.then(resArr => {
|
||||||
const graphRes = resArr[0];
|
const graphRes = resArr[0];
|
||||||
const neRes = resArr[1];
|
const neRes = resArr[1];
|
||||||
if (
|
if (
|
||||||
@@ -183,27 +235,43 @@ function fnGraphDataLoad(reload: boolean = false) {
|
|||||||
if (!res) return;
|
if (!res) return;
|
||||||
const { combos, edges, nodes } = res.graphData;
|
const { combos, edges, nodes } = res.graphData;
|
||||||
|
|
||||||
|
// 按网元类型分组
|
||||||
|
const neTypeMap = new Map();
|
||||||
|
res.neList.forEach(ne => {
|
||||||
|
if (!ne.neType) return;
|
||||||
|
if (!neTypeMap.has(ne.neType)) {
|
||||||
|
neTypeMap.set(ne.neType, []);
|
||||||
|
}
|
||||||
|
neTypeMap.get(ne.neType).push(ne);
|
||||||
|
});
|
||||||
|
|
||||||
// 节点过滤
|
// 节点过滤
|
||||||
const nf: Record<string, any>[] = nodes.filter(
|
const nf: Record<string, any>[] = nodes.filter(
|
||||||
(node: Record<string, any>) => {
|
(node: Record<string, any>) => {
|
||||||
Reflect.set(node, 'neState', { online: false });
|
Reflect.set(node, 'neState', { online: false });
|
||||||
|
Reflect.set(node, 'neStateMap', {}); // 初始化状态映射
|
||||||
|
|
||||||
// 图片路径处理
|
// 图片路径处理
|
||||||
if (node.img) node.img = parseBasePath(node.img);
|
if (node.img) node.img = parseBasePath(node.img);
|
||||||
if (node.icon.show && node.icon?.img) {
|
if (node.icon && node.icon.show && node.icon?.img)
|
||||||
node.icon.img = parseBasePath(node.icon.img);
|
node.icon.img = parseBasePath(node.icon.img);
|
||||||
}
|
|
||||||
// 遍历是否有网元数据
|
// 遍历是否有网元数据
|
||||||
const nodeID: string = node.id;
|
const nodeID: string = node.id;
|
||||||
const hasNe = res.neList.some(ne => {
|
|
||||||
Reflect.set(node, 'neInfo', ne.neType === nodeID ? ne : {});
|
// 处理非网元节点
|
||||||
return ne.neType === nodeID;
|
|
||||||
});
|
|
||||||
if (hasNe) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (notNeNodes.includes(nodeID)) {
|
if (notNeNodes.includes(nodeID)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理网元节点
|
||||||
|
if (neTypeMap.has(nodeID)) {
|
||||||
|
// all NeInfo
|
||||||
|
Reflect.set(node, 'neInfoList', neTypeMap.get(nodeID));
|
||||||
|
Reflect.set(node, 'neInfo', neTypeMap.get(nodeID)[0] || {});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -215,7 +283,6 @@ function fnGraphDataLoad(reload: boolean = false) {
|
|||||||
const edgeTarget: string = edge.target;
|
const edgeTarget: string = edge.target;
|
||||||
const hasNeS = nf.some(n => n.id === edgeSource);
|
const hasNeS = nf.some(n => n.id === edgeSource);
|
||||||
const hasNeT = nf.some(n => n.id === edgeTarget);
|
const hasNeT = nf.some(n => n.id === edgeTarget);
|
||||||
// console.log(hasNeS, edgeSource, hasNeT, edgeTarget);
|
|
||||||
if (hasNeS && hasNeT) {
|
if (hasNeS && hasNeT) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,47 +68,59 @@ export const graphNodeStateNum = computed(() => {
|
|||||||
export const neStateRequestMap = ref<Map<string, boolean>>(new Map());
|
export const neStateRequestMap = ref<Map<string, boolean>>(new Map());
|
||||||
|
|
||||||
/**neStateParse 网元状态 数据解析 */
|
/**neStateParse 网元状态 数据解析 */
|
||||||
export function neStateParse(neType: string, data: Record<string, any>) {
|
export function neStateParse(neType: string, data: Record<string, any>,neId: string) {
|
||||||
const { combos, edges, nodes } = graphState.data;
|
const { combos, edges, nodes } = graphState.data;
|
||||||
const node = nodes.find((item: Record<string, any>) => item.id === neType);
|
const node = nodes.find((item: Record<string, any>) => item.id === neType);
|
||||||
|
if (!node) return;
|
||||||
|
|
||||||
|
// 初始化状态映射
|
||||||
|
if (!node.neStateMap) node.neStateMap = {};
|
||||||
|
|
||||||
// 更新网元状态
|
// 更新网元状态
|
||||||
const newNeState = Object.assign(node.neState, data, {
|
const newNeState :any = {
|
||||||
|
...data, // 先展开data对象
|
||||||
refreshTime: parseDateToStr(data.refreshTime, 'HH:mm:ss'),
|
refreshTime: parseDateToStr(data.refreshTime, 'HH:mm:ss'),
|
||||||
online: !!data.cpu,
|
online: !!data.cpu,
|
||||||
});
|
neId: neId
|
||||||
|
};
|
||||||
|
|
||||||
|
// 如果是主要网元,更新节点状态
|
||||||
|
if (node.neInfo && node.neInfo.neId === neId) {
|
||||||
|
// 使用Object.assign更新状态,确保所有字段都被正确复制
|
||||||
|
Object.assign(node.neState, newNeState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无论是否为主要网元,都更新状态映射
|
||||||
|
node.neStateMap[neId] = {...newNeState}; // 创建副本存储
|
||||||
|
|
||||||
// 通过 ID 查询节点实例
|
// 通过 ID 查询节点实例
|
||||||
const item = graphG6.value.findById(node.id);
|
const item = graphG6.value.findById(node.id);
|
||||||
if (item) {
|
if (item) {
|
||||||
const stateColor = newNeState.online ? '#52c41a' : '#f5222d'; // 状态颜色
|
// 如果是主要网元,更新节点显示状态
|
||||||
// 图片类型不能填充
|
if (node.neInfo && node.neInfo.neId === neId) {
|
||||||
if (node.type.startsWith('image')) {
|
const stateColor = newNeState.online ? '#52c41a' : '#f5222d'; // 状态颜色
|
||||||
// 更新节点
|
// 图片类型不能填充
|
||||||
if (node.label !== newNeState.neName) {
|
if (node.type && 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, {
|
graphG6.value.updateItem(item, {
|
||||||
label: newNeState.neName,
|
label: newNeState.neName,
|
||||||
|
style: {
|
||||||
|
fill: stateColor, // 填充色
|
||||||
|
stroke: stateColor, // 填充色
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
// 设置状态
|
||||||
|
graphG6.value.setItemState(item, 'stroke', newNeState.online);
|
||||||
}
|
}
|
||||||
// 设置状态
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ export default function useWS() {
|
|||||||
|
|
||||||
/**接收数据后回调 */
|
/**接收数据后回调 */
|
||||||
function wsMessage(res: Record<string, any>) {
|
function wsMessage(res: Record<string, any>) {
|
||||||
//console.log(res);
|
|
||||||
const { code, requestId, data } = res;
|
const { code, requestId, data } = res;
|
||||||
if (code === RESULT_CODE_ERROR) {
|
if (code === RESULT_CODE_ERROR) {
|
||||||
console.warn(res.msg);
|
console.warn(res.msg);
|
||||||
@@ -43,7 +42,8 @@ export default function useWS() {
|
|||||||
// 网元状态
|
// 网元状态
|
||||||
if (requestId && requestId.startsWith('neState')) {
|
if (requestId && requestId.startsWith('neState')) {
|
||||||
const neType = requestId.split('_')[1];
|
const neType = requestId.split('_')[1];
|
||||||
neStateParse(neType, data);
|
const neId = requestId.split('_')[2];
|
||||||
|
neStateParse(neType, data,neId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,20 +84,24 @@ function fnGetNeState() {
|
|||||||
// 获取节点状态
|
// 获取节点状态
|
||||||
for (const node of graphState.data.nodes) {
|
for (const node of graphState.data.nodes) {
|
||||||
if (notNeNodes.includes(node.id)) continue;
|
if (notNeNodes.includes(node.id)) continue;
|
||||||
const { neType, neId } = node.neInfo;
|
|
||||||
if (!neType || !neId) continue;
|
|
||||||
// 请求标记检查避免重复发送
|
|
||||||
if (neStateRequestMap.value.get(neType)) continue;
|
|
||||||
neStateRequestMap.value.set(neType, true);
|
|
||||||
|
|
||||||
wsSend({
|
|
||||||
requestId: `neState_${neType}_${neId}`,
|
const neInfoList = node.neInfoList || [];
|
||||||
type: 'ne_state',
|
if (neInfoList.length === 0) continue;
|
||||||
data: {
|
|
||||||
neType: neType,
|
|
||||||
neId: neId,
|
for (const neInfo of neInfoList) {
|
||||||
},
|
if (!neInfo.neType || !neInfo.neId) continue;
|
||||||
});
|
|
||||||
|
wsSend({
|
||||||
|
requestId: `neState_${neInfo.neType}_${neInfo.neId}`,
|
||||||
|
type: 'ne_state',
|
||||||
|
data: {
|
||||||
|
neType: neInfo.neType,
|
||||||
|
neId: neInfo.neId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,14 +127,20 @@ const graphNodeTooltip = new Tooltip({
|
|||||||
offsetY: 20,
|
offsetY: 20,
|
||||||
getContent(evt) {
|
getContent(evt) {
|
||||||
if (!evt) return t('views.monitor.topologyBuild.graphNotInfo');
|
if (!evt) return t('views.monitor.topologyBuild.graphNotInfo');
|
||||||
const { id, label, neState }: any = evt.item?.getModel();
|
const { id, label, neState, neInfoList, neStateMap }: any = evt.item?.getModel();
|
||||||
if (notNeNodes.includes(id)) {
|
if (notNeNodes.includes(id)) {
|
||||||
return `<div><span>${label || id}</span></div>`;
|
return `<div><span>${label || id}</span></div>`;
|
||||||
}
|
}
|
||||||
if (!neState) {
|
if (!neState) {
|
||||||
return `<div><span>${label || id}</span></div>`;
|
return `<div><span>${label || id}</span></div>`;
|
||||||
}
|
}
|
||||||
return `
|
|
||||||
|
// 获取同类型网元列表
|
||||||
|
const sameTypeNes = neInfoList || [];
|
||||||
|
|
||||||
|
// 如果没有网元或只有一个网元,显示原来的信息
|
||||||
|
if (sameTypeNes.length <= 1) {
|
||||||
|
return `
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -157,7 +163,7 @@ const graphNodeTooltip = new Tooltip({
|
|||||||
<div><strong>${t('views.monitor.topology.name')}:</strong><span>
|
<div><strong>${t('views.monitor.topology.name')}:</strong><span>
|
||||||
${neState.neName ?? '--'}
|
${neState.neName ?? '--'}
|
||||||
</span></div>
|
</span></div>
|
||||||
<div><strong>IP:</strong><span>${neState.neIP}</span></div>
|
<div><strong>IP:</strong><span>${neState.neIP ?? '--'}</span></div>
|
||||||
<div><strong>${t('views.monitor.topology.version')}:</strong><span>
|
<div><strong>${t('views.monitor.topology.version')}:</strong><span>
|
||||||
${neState.version ?? '--'}
|
${neState.version ?? '--'}
|
||||||
</span></div>
|
</span></div>
|
||||||
@@ -169,6 +175,63 @@ const graphNodeTooltip = new Tooltip({
|
|||||||
</span></div>
|
</span></div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有多个网元,聚合显示
|
||||||
|
let content = `
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 300px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div><strong>${t('views.monitor.topology.state')}:</strong><span>
|
||||||
|
${
|
||||||
|
neState.online
|
||||||
|
? t('views.monitor.topology.normalcy')
|
||||||
|
: t('views.monitor.topology.exceptions')
|
||||||
|
}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.refreshTime')}:</strong><span>
|
||||||
|
${neState.refreshTime ?? '--'}
|
||||||
|
</span></div>
|
||||||
|
<div>========================</div>`;
|
||||||
|
|
||||||
|
// 为每个同类型网元添加信息
|
||||||
|
sameTypeNes.forEach((ne: any, index: number) => {
|
||||||
|
// 获取该网元的状态信息
|
||||||
|
const neStateInfo = neStateMap?.[ne.neId] ||
|
||||||
|
(ne.neId === neState.neId ? neState : {});
|
||||||
|
|
||||||
|
content += `
|
||||||
|
<div style="margin-top: 8px;"><strong>${t('views.monitor.topology.name')}:${ne.neName || id + '_' + ne.neId}</strong></div>
|
||||||
|
<div><strong>ID:</strong><span>${ne.neId || '--'}</span></div>
|
||||||
|
<div><strong>IP:</strong><span>${neStateInfo.neIP || ne.neIP || '--'}</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.version')}:</strong><span>
|
||||||
|
${neStateInfo.version || ne.version || '--'}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.serialNum')}:</strong><span>
|
||||||
|
${neStateInfo.sn || ne.sn || '--'}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.expiryDate')}:</strong><span>
|
||||||
|
${neStateInfo.expire || ne.expire || '--'}
|
||||||
|
</span></div>
|
||||||
|
<div><strong>${t('views.monitor.topology.state')}:</strong><span>
|
||||||
|
${
|
||||||
|
neStateInfo.online !== undefined
|
||||||
|
? (neStateInfo.online
|
||||||
|
? t('views.monitor.topology.normalcy')
|
||||||
|
: t('views.monitor.topology.exceptions'))
|
||||||
|
: '未知'
|
||||||
|
}
|
||||||
|
</span></div>
|
||||||
|
${index < sameTypeNes.length - 1 ? '<div>------------------------</div>' : ''}
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
content += '</div>';
|
||||||
|
return content;
|
||||||
},
|
},
|
||||||
itemTypes: ['node'],
|
itemTypes: ['node'],
|
||||||
});
|
});
|
||||||
@@ -262,7 +325,7 @@ function fnGraphDataLoad(reload: boolean = false) {
|
|||||||
bandStatus: false,
|
bandStatus: false,
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
.then(resArr => {
|
.then(resArr => {
|
||||||
const graphRes = resArr[0];
|
const graphRes = resArr[0];
|
||||||
const neRes = resArr[1];
|
const neRes = resArr[1];
|
||||||
if (
|
if (
|
||||||
@@ -288,26 +351,43 @@ function fnGraphDataLoad(reload: boolean = false) {
|
|||||||
if (!res) return;
|
if (!res) return;
|
||||||
const { combos, edges, nodes } = res.graphData;
|
const { combos, edges, nodes } = res.graphData;
|
||||||
|
|
||||||
|
// 按网元类型分组
|
||||||
|
const neTypeMap = new Map();
|
||||||
|
res.neList.forEach(ne => {
|
||||||
|
if (!ne.neType) return;
|
||||||
|
if (!neTypeMap.has(ne.neType)) {
|
||||||
|
neTypeMap.set(ne.neType, []);
|
||||||
|
}
|
||||||
|
neTypeMap.get(ne.neType).push(ne);
|
||||||
|
});
|
||||||
|
|
||||||
// 节点过滤
|
// 节点过滤
|
||||||
const nf: Record<string, any>[] = nodes.filter(
|
const nf: Record<string, any>[] = nodes.filter(
|
||||||
(node: Record<string, any>) => {
|
(node: Record<string, any>) => {
|
||||||
Reflect.set(node, 'neState', { online: false });
|
Reflect.set(node, 'neState', { online: false });
|
||||||
|
Reflect.set(node, 'neStateMap', {}); // 初始化状态映射
|
||||||
|
|
||||||
// 图片路径处理
|
// 图片路径处理
|
||||||
if (node.img) node.img = parseBasePath(node.img);
|
if (node.img) node.img = parseBasePath(node.img);
|
||||||
if (node.icon.show && node.icon?.img)
|
if (node.icon && node.icon.show && node.icon?.img)
|
||||||
node.icon.img = parseBasePath(node.icon.img);
|
node.icon.img = parseBasePath(node.icon.img);
|
||||||
|
|
||||||
// 遍历是否有网元数据
|
// 遍历是否有网元数据
|
||||||
const nodeID: string = node.id;
|
const nodeID: string = node.id;
|
||||||
const hasNe = res.neList.some(ne => {
|
|
||||||
Reflect.set(node, 'neInfo', ne.neType === nodeID ? ne : {});
|
// 处理非网元节点
|
||||||
return ne.neType === nodeID;
|
|
||||||
});
|
|
||||||
if (hasNe) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (notNeNodes.includes(nodeID)) {
|
if (notNeNodes.includes(nodeID)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理网元节点
|
||||||
|
if (neTypeMap.has(nodeID)) {
|
||||||
|
// all NeInfo
|
||||||
|
Reflect.set(node, 'neInfoList', neTypeMap.get(nodeID));
|
||||||
|
Reflect.set(node, 'neInfo', neTypeMap.get(nodeID)[0] || {});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -319,7 +399,6 @@ function fnGraphDataLoad(reload: boolean = false) {
|
|||||||
const edgeTarget: string = edge.target;
|
const edgeTarget: string = edge.target;
|
||||||
const hasNeS = nf.some(n => n.id === edgeSource);
|
const hasNeS = nf.some(n => n.id === edgeSource);
|
||||||
const hasNeT = nf.some(n => n.id === edgeTarget);
|
const hasNeT = nf.some(n => n.id === edgeTarget);
|
||||||
// console.log(hasNeS, edgeSource, hasNeT, edgeTarget);
|
|
||||||
if (hasNeS && hasNeT) {
|
if (hasNeS && hasNeT) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -366,19 +445,27 @@ const interval10s = ref<any>(null);
|
|||||||
|
|
||||||
/**查询网元状态 */
|
/**查询网元状态 */
|
||||||
function fnGetState() {
|
function fnGetState() {
|
||||||
// 获取节点状态
|
// 遍历所有节点
|
||||||
for (const node of graphState.data.nodes) {
|
for (const node of graphState.data.nodes) {
|
||||||
if (notNeNodes.includes(node.id)) continue;
|
if (notNeNodes.includes(node.id)) continue;
|
||||||
const { neType, neId } = node.neInfo;
|
|
||||||
if (!neType || !neId) continue;
|
|
||||||
ws.send({
|
const neInfoList = node.neInfoList || [];
|
||||||
requestId: `${neType}_${neId}`,
|
if (neInfoList.length === 0) continue;
|
||||||
type: 'ne_state',
|
|
||||||
data: {
|
|
||||||
neType: neType,
|
for (const neInfo of neInfoList) {
|
||||||
neId: neId,
|
if (!neInfo.neType || !neInfo.neId) continue;
|
||||||
},
|
|
||||||
});
|
ws.send({
|
||||||
|
requestId: `${neInfo.neType}_${neInfo.neId}`,
|
||||||
|
type: 'ne_state',
|
||||||
|
data: {
|
||||||
|
neType: neInfo.neType,
|
||||||
|
neId: neInfo.neId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,25 +484,64 @@ function wsMessage(res: Record<string, any>) {
|
|||||||
}
|
}
|
||||||
if (!requestId) return;
|
if (!requestId) return;
|
||||||
const [neType, neId] = requestId.split('_');
|
const [neType, neId] = requestId.split('_');
|
||||||
const { combos, edges, nodes } = graphState.data;
|
const { edges, nodes } = graphState.data;
|
||||||
const node = nodes.find((item: Record<string, any>) => item.id === neType);
|
|
||||||
|
|
||||||
// 更新网元状态
|
const node = nodes.find((item: Record<string, any>) => item.id === neType);
|
||||||
const newNeState = Object.assign(node.neState, data, {
|
if (!node) return;
|
||||||
|
|
||||||
|
if (!node.neStateMap) node.neStateMap = {};
|
||||||
|
|
||||||
|
const newNeState = {
|
||||||
|
...data,
|
||||||
refreshTime: parseDateToStr(data.refreshTime, 'HH:mm:ss'),
|
refreshTime: parseDateToStr(data.refreshTime, 'HH:mm:ss'),
|
||||||
online: !!data.cpu,
|
online: !!data.cpu,
|
||||||
});
|
neId: neId
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (node.neInfo && node.neInfo.neId === neId) {
|
||||||
|
Object.assign(node.neState, newNeState);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.neStateMap[neId] = {...newNeState};
|
||||||
|
|
||||||
// 通过 ID 查询节点实例
|
// 通过 ID 查询节点实例
|
||||||
const item = graphG6.value.findById(node.id);
|
const item = graphG6.value.findById(node.id);
|
||||||
if (item) {
|
if (item) {
|
||||||
const stateColor = newNeState.online ? '#52c41a' : '#f5222d'; // 状态颜色
|
const neInfoList = node.neInfoList || [];
|
||||||
|
let allOnline = true;
|
||||||
|
let allOffline = true;
|
||||||
|
let mixedState = false;
|
||||||
|
|
||||||
|
for (const ne of neInfoList) {
|
||||||
|
const neState = node.neStateMap[ne.neId];
|
||||||
|
if (neState) {
|
||||||
|
if (neState.online) {
|
||||||
|
allOffline = false;
|
||||||
|
} else {
|
||||||
|
allOnline = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果既不是全部在线也不是全部离线,则是混合状态
|
||||||
|
mixedState = !allOnline && !allOffline;
|
||||||
|
|
||||||
|
// 根据状态设置颜色
|
||||||
|
let stateColor = '#52c41a'; // 默认绿色(全部正常)
|
||||||
|
if (allOffline) {
|
||||||
|
stateColor = '#f5222d'; // 红色(全部异常)
|
||||||
|
} else if (mixedState) {
|
||||||
|
stateColor = '#faad14'; // 黄色(部分正常部分异常)
|
||||||
|
}
|
||||||
|
|
||||||
// 图片类型不能填充
|
// 图片类型不能填充
|
||||||
if (node.type.startsWith('image')) {
|
if (node.type && node.type.startsWith('image')) {
|
||||||
// 更新节点
|
// 更新节点
|
||||||
if (node.label !== newNeState.neName) {
|
if (node.label !== node.neInfo.neName) {
|
||||||
graphG6.value.updateItem(item, {
|
graphG6.value.updateItem(item, {
|
||||||
label: newNeState.neName,
|
label: node.neInfo.neType,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 设置状态
|
// 设置状态
|
||||||
@@ -423,63 +549,43 @@ function wsMessage(res: Record<string, any>) {
|
|||||||
} else {
|
} else {
|
||||||
// 更新节点
|
// 更新节点
|
||||||
graphG6.value.updateItem(item, {
|
graphG6.value.updateItem(item, {
|
||||||
label: newNeState.neName,
|
label: node.neInfo.neType,
|
||||||
// neState: newNeState,
|
|
||||||
style: {
|
style: {
|
||||||
fill: stateColor, // 填充色
|
fill: stateColor, // 填充色
|
||||||
stroke: stateColor, // 填充色
|
stroke: stateColor, // 填充色
|
||||||
},
|
},
|
||||||
// labelCfg: {
|
|
||||||
// style: {
|
|
||||||
// fill: '#ffffff', // 标签文本色
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
});
|
});
|
||||||
// 设置状态
|
// 设置状态 - 使用混合状态
|
||||||
graphG6.value.setItemState(item, 'stroke', newNeState.online);
|
graphG6.value.setItemState(item, 'stroke', !allOffline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置边状态
|
// 设置边状态 - 也需要考虑混合状态
|
||||||
for (const edge of edges) {
|
for (const edge of edges) {
|
||||||
const edgeSource: string = edge.source;
|
const edgeSource: string = edge.source;
|
||||||
const edgeTarget: string = edge.target;
|
const edgeTarget: string = edge.target;
|
||||||
const neS = nodes.find((n: any) => n.id === edgeSource);
|
const neS = nodes.find((n: any) => n.id === edgeSource);
|
||||||
const neT = nodes.find((n: any) => n.id === edgeTarget);
|
const neT = nodes.find((n: any) => n.id === edgeTarget);
|
||||||
// console.log(neS, edgeSource, neT, edgeTarget);
|
|
||||||
|
|
||||||
if (neS && neT) {
|
if (neS && neT) {
|
||||||
// 通过 ID 查询节点实例
|
// 计算源节点和目标节点的状态
|
||||||
// const item = graphG6.value.findById(edge.id);
|
const sourceHasOnline = neS.neInfoList?.some((ne: any) => neS.neStateMap?.[ne.neId]?.online) || false;
|
||||||
// console.log(
|
const targetHasOnline = neT.neInfoList?.some((ne: any) => neT.neStateMap?.[ne.neId]?.online) || false;
|
||||||
// `${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(
|
graphG6.value.setItemState(
|
||||||
edge.id,
|
edge.id,
|
||||||
'circle-move',
|
'circle-move',
|
||||||
neS.neState.online && neT.neState.online
|
sourceHasOnline && targetHasOnline
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (neS && notNeNodes.includes(edgeTarget)) {
|
if (neS && notNeNodes.includes(edgeTarget)) {
|
||||||
graphG6.value.setItemState(edge.id, 'line-dash', neS.neState.online);
|
const sourceHasOnline = neS.neInfoList?.some((ne: any) => neS.neStateMap?.[ne.neId]?.online) || false;
|
||||||
|
graphG6.value.setItemState(edge.id, 'line-dash', sourceHasOnline);
|
||||||
}
|
}
|
||||||
if (neT && notNeNodes.includes(edgeSource)) {
|
if (neT && notNeNodes.includes(edgeSource)) {
|
||||||
graphG6.value.setItemState(edge.id, 'line-dash', neT.neState.online);
|
const targetHasOnline = neT.neInfoList?.some((ne: any) => neT.neStateMap?.[ne.neId]?.online) || false;
|
||||||
|
graphG6.value.setItemState(edge.id, 'line-dash', targetHasOnline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user