解决web显示iwenti

This commit is contained in:
Alex Yang
2025-12-05 10:22:52 +08:00
parent 62ef6170f5
commit f5635db249
15 changed files with 4797 additions and 101 deletions

View File

@@ -771,18 +771,18 @@ func GetAllDeviceStatus(c *gin.Context) {
allDevices := deviceStorage.GetDevices()
// 查询每个设备的状态
result := make([]map[string]interface{}, 0, len(allDevices))
for _, device := range allDevices {
// 查询设备监控数据
_, status, _ := globalStorage.QueryDeviceStatus(context.Background(), device.ID)
result := make([]map[string]interface{}, 0, len(allDevices))
for _, device := range allDevices {
// 查询设备监控数据
_, status, _ := globalStorage.QueryDeviceStatus(context.Background(), device.ID)
// 总是返回设备信息,无论是否有监控数据
result = append(result, map[string]interface{}{
"device_id": device.ID,
"name": device.Name,
"status": status,
})
}
// 总是返回设备信息,无论是否有监控数据
result = append(result, map[string]interface{}{
"id": device.ID,
"name": device.Name,
"status": status,
})
}
c.JSON(http.StatusOK, gin.H{
"devices": result,

Binary file not shown.

View File

@@ -197,7 +197,7 @@
<div id="serversContent" class="hidden">
<div class="bg-white rounded-xl shadow-md p-6 mb-6">
<h2 class="text-xl font-bold text-gray-900 mb-6">所有服务器</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" id="serversGrid">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" id="serversGrid">
<!-- 服务器卡片将通过JavaScript动态加载 -->
</div>
</div>

View File

@@ -150,6 +150,10 @@ function switchPage() {
let deviceId = '';
if (hash.startsWith('#serverMonitor/')) {
deviceId = hash.split('/')[1];
// 检查deviceId是否为'undefined'字符串
if (deviceId === 'undefined') {
deviceId = '';
}
}
// 直接设置当前设备ID确保loadMetrics能使用正确的设备ID
@@ -157,10 +161,17 @@ function switchPage() {
// 加载服务器信息
if (deviceId) {
loadServerInfo(deviceId);
loadServerInfo(deviceId).then(() => {
// 确保服务器信息加载完成后再加载指标数据
loadMetrics();
});
} else {
// 如果没有设备ID显示错误信息
const serverInfoDisplay = document.getElementById('serverInfoDisplay');
if (serverInfoDisplay) {
serverInfoDisplay.innerHTML = `<p class="text-red-500">无效的服务器ID</p>`;
}
}
loadMetrics();
} else {
showContent('homeContent');
loadHomeData();
@@ -198,28 +209,24 @@ async function loadHomeData() {
async function loadBusinessViewData() {
try {
const response = await fetch(`${API_BASE_URL}/devices/`);
const data = await response.json();
let devices = data.devices || [];
// 如果没有设备,使用模拟数据
if (devices.length === 0) {
devices = [
{ id: 'device-1', name: '服务器1', ip: '192.168.1.100' },
{ id: 'device-2', name: '服务器2', ip: '192.168.1.101' }
];
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
const devices = data.devices || [];
renderBusinessView(devices);
} catch (error) {
console.error('加载业务视图数据失败:', error);
// 使用模拟数据
const mockDevices = [
{ id: 'device-1', name: 'LIS', ip: '192.129.6.108', os: 'Linux', status: 'P1' },
{ id: 'device-2', name: '互联网医院', ip: '192.129.6.57', os: 'Linux', status: 'P3' },
{ id: 'device-3', name: 'HIS', ip: '192.129.51.21', os: 'Windows', status: 'P2' },
{ id: 'device-4', name: 'OA', ip: '192.129.6.42', os: 'Linux', status: 'P2' }
];
renderBusinessView(mockDevices);
// 只显示错误信息,不使用模拟数据
const tableBody = document.getElementById('businessViewTableBody');
if (tableBody) {
tableBody.innerHTML = `
<tr>
<td colspan="4" class="px-6 py-4 text-center text-red-500">加载业务视图数据失败</td>
</tr>
`;
}
}
}
@@ -232,7 +239,7 @@ function renderBusinessView(devices) {
devices.forEach(device => {
const row = document.createElement('tr');
row.className = 'hover:bg-gray-50 transition-colors';
row.className = 'hover:bg-gray-50 transition-colors cursor-pointer';
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${device.name}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${device.ip}</td>
@@ -243,21 +250,39 @@ function renderBusinessView(devices) {
</span>
</td>
`;
// 为表格行添加点击事件
row.addEventListener('click', () => {
goToServerMonitor(device.id);
});
tableBody.appendChild(row);
});
}
// 加载告警列表数据
function loadAlarmListData() {
// 模拟数据
const alarmData = [
{ level: 'warning', message: 'CPU使用率超过阈值', device: '192.129.6.108', time: '2023-11-30 14:30:00' },
{ level: 'error', message: '内存使用率超过阈值', device: '192.129.6.57', time: '2023-11-30 14:28:00' },
{ level: 'warning', message: '磁盘使用率超过阈值', device: '192.129.51.21', time: '2023-11-30 14:25:00' },
{ level: 'info', message: '网络流量异常', device: '192.129.6.42', time: '2023-11-30 14:20:00' }
];
renderAlarmList(alarmData);
async function loadAlarmListData() {
try {
const response = await fetch(`${API_BASE_URL}/alarms`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
const alarmData = data.alarms || [];
renderAlarmList(alarmData);
} catch (error) {
console.error('加载告警列表失败:', error);
// 只显示错误信息,不使用模拟数据
const alarmList = document.getElementById('alarmList');
if (alarmList) {
alarmList.innerHTML = `
<div class="flex items-center justify-center p-4 text-red-500">
加载告警列表失败
</div>
`;
}
}
}
// 渲染告警列表
@@ -330,19 +355,27 @@ async function loadServerCount() {
// 加载所有服务器
async function loadAllServers() {
try {
const response = await fetch(`${API_BASE_URL}/devices/`);
// 调用设备状态API获取详细信息
const response = await fetch(`${API_BASE_URL}/devices/status`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
const devices = data.devices || [];
renderServersGrid(devices);
} catch (error) {
console.error('加载服务器列表失败:', error);
// 模拟数据
const mockDevices = [
{ id: 'device-1', name: '服务器1', ip: '192.168.1.100' },
{ id: 'device-2', name: '服务器2', ip: '192.168.1.101' }
];
renderServersGrid(mockDevices);
// 只显示错误信息,不使用模拟数据
const serversGrid = document.getElementById('serversGrid');
if (serversGrid) {
serversGrid.innerHTML = `
<div class="col-span-full bg-white rounded-xl shadow-md p-6 text-center text-red-500">
<i class="fa fa-exclamation-circle text-2xl mb-2"></i>
<p>加载服务器列表失败</p>
</div>
`;
}
}
}
@@ -359,6 +392,19 @@ function renderServersGrid(devices) {
});
}
// 跳转到服务器监控界面
function goToServerMonitor(deviceId) {
// 确保deviceId有效
if (!deviceId) {
console.error('Invalid device ID');
return;
}
// 设置URL hash
window.location.hash = `#serverMonitor/${deviceId}`;
// 手动调用switchPage来立即更新页面
switchPage();
}
// 创建服务器卡片
function createServerCard(device) {
const card = document.createElement('div');
@@ -366,35 +412,41 @@ function createServerCard(device) {
// 为卡片添加点击事件
card.addEventListener('click', () => {
goToServerMonitor(device.id);
// 确保使用正确的设备ID字段
const deviceId = device.device_id || device.id || device.ID;
goToServerMonitor(deviceId);
});
// 获取设备状态数据
const status = device.status || {};
const cpuUsage = status.cpu !== undefined ? status.cpu.toFixed(1) : '0.0';
const memoryUsage = status.memory !== undefined ? status.memory.toFixed(1) : '0.0';
const diskUsage = status.disk !== undefined ? status.disk.toFixed(1) : '0.0';
const networkTraffic = status.network !== undefined ? status.network.toFixed(1) : '0.0';
card.innerHTML = `
<div class="flex justify-between items-start mb-4">
<div>
<h3 class="text-xl font-bold text-gray-900">${device.name || device.id}</h3>
<h3 class="text-xl font-bold text-gray-900">${device.name || device.device_id || device.id}</h3>
<p class="text-sm text-gray-500">${device.ip || 'N/A'}</p>
</div>
<div class="px-3 py-1 bg-green-100 text-green-800 text-xs font-medium rounded-full">
在线
<div class="flex items-center">
<span class="inline-block w-2 h-2 bg-green-500 rounded-full mr-1"></span>
<span class="text-green-600 text-sm font-medium">在线</span>
</div>
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<p class="text-xs text-gray-500">CPU使用率</p>
<p class="text-lg font-semibold text-gray-900">0.0%</p>
<p class="text-lg font-semibold text-gray-900">${cpuUsage}%</p>
<p class="text-xs text-gray-500">磁盘使用率</p>
<p class="text-lg font-semibold text-gray-900">${diskUsage}%</p>
</div>
<div>
<p class="text-xs text-gray-500">内存使用率</p>
<p class="text-lg font-semibold text-gray-900">0.0%</p>
</div>
<div>
<p class="text-xs text-gray-500">磁盘使用率</p>
<p class="text-lg font-semibold text-gray-900">0.0%</p>
</div>
<div>
<p class="text-lg font-semibold text-gray-900">${memoryUsage}%</p>
<p class="text-xs text-gray-500">网络流量</p>
<p class="text-lg font-semibold text-gray-900">0.0 MB/s</p>
<p class="text-lg font-semibold text-gray-900">${networkTraffic} MB/s</p>
</div>
</div>
<div class="flex justify-end">
@@ -408,7 +460,9 @@ function createServerCard(device) {
const viewDetailBtn = card.querySelector('button');
viewDetailBtn.addEventListener('click', (e) => {
e.stopPropagation(); // 阻止事件冒泡
goToServerMonitor(device.id);
// 确保使用正确的设备ID字段
const deviceId = device.device_id || device.id || device.ID;
goToServerMonitor(deviceId);
});
return card;
@@ -428,12 +482,10 @@ async function loadDeviceManagementList() {
const data = await response.json();
const devices = data.devices || [];
// 如果设备列表为空,使用模拟数据作为回退
if (devices.length === 0) {
console.warn('No devices available, using mock data');
const mockDevices = getMockDevices();
originalDeviceList = mockDevices;
renderDeviceManagementList(mockDevices);
console.warn('No devices available');
originalDeviceList = [];
renderDeviceManagementList([]);
return;
}
@@ -454,10 +506,15 @@ async function loadDeviceManagementList() {
applyDeviceFilters();
} catch (error) {
console.error('加载设备管理列表失败:', error);
// 使用模拟数据作为回退
const mockDevices = getMockDevices();
originalDeviceList = mockDevices;
renderDeviceManagementList(mockDevices);
// 只显示错误信息,不使用模拟数据
const deviceListBody = document.getElementById('deviceListBody');
if (deviceListBody) {
deviceListBody.innerHTML = `
<tr>
<td colspan="6" class="px-6 py-4 text-center text-red-500">加载设备列表失败</td>
</tr>
`;
}
}
}
@@ -504,14 +561,7 @@ function clearDeviceFilters() {
applyDeviceFilters();
}
// 获取模拟设备数据
function getMockDevices() {
return [
{ id: 'device-1', name: '服务器1', ip: '192.168.1.100', status: 'active', created_at: new Date().toLocaleString(), token: 'mock-token-1' },
{ id: 'device-2', name: '服务器2', ip: '192.168.1.101', status: 'inactive', created_at: new Date().toLocaleString(), token: 'mock-token-2' },
{ id: 'device-3', name: '测试服务器', ip: '192.168.1.102', status: 'offline', created_at: new Date().toLocaleString(), token: 'mock-token-3' }
];
}
// 复制文本到剪贴板
function copyToClipboard(text) {
@@ -669,6 +719,7 @@ function renderDeviceManagementList(devices) {
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${device.created_at}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<button class="text-blue-600 hover:text-blue-800 mr-3" onclick="goToServerMonitor('${device.id}')">查看详情</button>
<button class="text-blue-600 hover:text-blue-800 mr-3" onclick="editDevice('${device.id}')">编辑</button>
<button class="text-green-600 hover:text-green-800 mr-3 ${device.status === 'active' ? 'hidden' : ''}" onclick="toggleDeviceStatus('${device.id}', 'active')">激活</button>
<button class="text-yellow-600 hover:text-yellow-800 mr-3 ${device.status !== 'active' ? 'hidden' : ''}" onclick="toggleDeviceStatus('${device.id}', 'inactive')">停用</button>
@@ -1502,10 +1553,10 @@ async function loadServerInfo(deviceId) {
// 即使请求失败也要将设备ID存储到全局状态
state.currentDeviceID = deviceId;
// 使用模拟数据
// 显示错误信息,不使用模拟数据
const serverInfoDisplay = document.getElementById('serverInfoDisplay');
if (serverInfoDisplay) {
serverInfoDisplay.innerHTML = `<p>服务器名称: <strong>服务器 ${deviceId}</strong> | IP地址: <strong>192.168.1.${deviceId}</strong></p>`;
serverInfoDisplay.innerHTML = `<p class="text-red-500">加载服务器信息失败</p>`;
}
}
}
@@ -2388,15 +2439,11 @@ function updateInterfaceDropdown(networkData) {
}
});
} else {
// 如果没有按网卡分组的数据,使用模拟网卡名称
// 这里可以根据实际情况修改,比如从其他地方获取网卡名称列表
const mockInterfaces = ['eth0', 'eth1', 'lo'];
mockInterfaces.forEach(iface => {
const option = document.createElement('option');
option.value = iface;
option.textContent = iface;
select.appendChild(option);
});
// 如果没有按网卡分组的数据,显示"所有接口"选项
const option = document.createElement('option');
option.value = 'all';
option.textContent = '所有接口';
select.appendChild(option);
}
// 恢复当前选中的值
@@ -2919,15 +2966,7 @@ function showContent(contentId) {
}
}
// 跳转到服务器监控详情页面
function goToServerMonitor(deviceId) {
state.currentDeviceID = deviceId;
window.location.hash = `#serverMonitor/${deviceId}`;
// 加载选中设备的监控数据
setTimeout(() => {
loadMetrics();
}, 100);
}
// 注意此函数已被更新的goToServerMonitor函数替代保留用于兼容
// 初始化图表选项卡