Files
planet/frontend/public/earth/js/info-card.js

179 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// info-card.js - Unified info card module
import { showStatusMessage } from './ui.js';
let currentType = null;
const CARD_CONFIG = {
cable: {
icon: '🛥️',
title: '电缆详情',
className: 'cable',
fields: [
{ key: 'name', label: '名称' },
{ key: 'owner', label: '所有者' },
{ key: 'status', label: '状态' },
{ key: 'length', label: '长度' },
{ key: 'coords', label: '经纬度' },
{ key: 'rfs', label: '投入使用' }
]
},
satellite: {
icon: '🛰️',
title: '卫星详情',
className: 'satellite',
fields: [
{ key: 'name', label: '名称' },
{ key: 'norad_id', label: 'NORAD ID' },
{ key: 'inclination', label: '倾角', unit: '°' },
{ key: 'period', label: '周期', unit: '分钟' },
{ key: 'perigee', label: '近地点', unit: 'km' },
{ key: 'apogee', label: '远地点', unit: 'km' }
]
},
bgp: {
icon: '📡',
title: 'BGP异常详情',
className: 'bgp',
fields: [
{ key: 'anomaly_type', label: '异常类型' },
{ key: 'severity', label: '严重度' },
{ key: 'status', label: '状态' },
{ key: 'prefix', label: '前缀' },
{ key: 'origin_asn', label: '原始 ASN' },
{ key: 'new_origin_asn', label: '新 ASN' },
{ key: 'confidence', label: '置信度' },
{ key: 'collector', label: '采集器' },
{ key: 'country', label: '国家' },
{ key: 'city', label: '城市' },
{ key: 'created_at', label: '创建时间' },
{ key: 'summary', label: '摘要' }
]
},
bgp_collector: {
icon: '📍',
title: 'BGP观测站详情',
className: 'bgp',
fields: [
{ key: 'collector', label: '采集器' },
{ key: 'country', label: '国家' },
{ key: 'city', label: '城市' },
{ key: 'anomaly_count', label: '当前异常数' },
{ key: 'status', label: '状态' }
]
},
supercomputer: {
icon: '🖥️',
title: '超算详情',
className: 'supercomputer',
fields: [
{ key: 'name', label: '名称' },
{ key: 'rank', label: '排名' },
{ key: 'r_max', label: 'Rmax', unit: 'GFlops' },
{ key: 'r_peak', label: 'Rpeak', unit: 'GFlops' },
{ key: 'country', label: '国家' },
{ key: 'city', label: '城市' }
]
},
gpu_cluster: {
icon: '🎮',
title: 'GPU集群详情',
className: 'gpu_cluster',
fields: [
{ key: 'name', label: '名称' },
{ key: 'country', label: '国家' },
{ key: 'city', label: '城市' }
]
}
};
export function initInfoCard() {
const content = document.getElementById('info-card-content');
if (!content || content.dataset.copyBound === 'true') return;
content.addEventListener('click', async (event) => {
const label = event.target.closest('.info-card-label');
if (!label) return;
const property = label.closest('.info-card-property');
const valueEl = property?.querySelector('.info-card-value');
const value = valueEl?.textContent?.trim();
if (!value || value === '-') {
showStatusMessage('无可复制内容', 'warning');
return;
}
try {
await navigator.clipboard.writeText(value);
showStatusMessage(`已复制${label.textContent}${value}`, 'success');
} catch (error) {
console.error('Copy failed:', error);
showStatusMessage('复制失败', 'error');
}
});
content.dataset.copyBound = 'true';
}
export function setInfoCardNoBorder(noBorder = true) {
const card = document.getElementById('info-card');
if (card) {
card.classList.toggle('no-border', noBorder);
}
}
export function showInfoCard(type, data) {
const config = CARD_CONFIG[type];
if (!config) {
console.warn('Unknown info card type:', type);
return;
}
currentType = type;
const card = document.getElementById('info-card');
const icon = document.getElementById('info-card-icon');
const title = document.getElementById('info-card-title');
const content = document.getElementById('info-card-content');
card.className = 'info-card ' + config.className;
icon.textContent = config.icon;
title.textContent = config.title;
let html = '';
for (const field of config.fields) {
let value = data[field.key];
if (value === undefined || value === null || value === '') {
value = '-';
} else if (typeof value === 'number') {
value = value.toLocaleString();
}
if (field.unit && value !== '-') {
value = value + ' ' + field.unit;
}
html += `
<div class="info-card-property">
<span class="info-card-label">${field.label}</span>
<span class="info-card-value">${value}</span>
</div>
`;
}
content.innerHTML = html;
card.style.display = 'block';
}
export function hideInfoCard() {
const card = document.getElementById('info-card');
if (card) {
card.style.display = 'none';
}
currentType = null;
}
export function getCurrentType() {
return currentType;
}