LicenseManger/web/static/js/dashboard.js

184 lines
5.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

layui.use(['layer'], function(){
var layer = layui.layer;
var $ = layui.$;
// 初始化图表
var registerTrendChart = echarts.init(document.getElementById('register-trend'));
var deviceTypesChart = echarts.init(document.getElementById('device-types'));
// 加载统计数据
function loadStats() {
fetch('/api/dashboard/stats', {
credentials: 'include',
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
})
.then(response => {
if (response.status === 401) {
window.location.href = '/login';
throw new Error('认证失败');
}
return response.json();
})
.then(result => {
if (result.error) {
layer.msg(result.error);
return;
}
// 更新统计数据
updateStats(result.data);
// 更新图表
updateCharts(result.data);
// 更新系统状态
updateSystemStatus(result.data);
})
.catch(error => {
layer.msg('加载统计数据失败:' + error.message);
});
}
// 更新统计数据
function updateStats(data) {
$('#total-devices').text(data.total_devices);
$('#total-licenses').text(data.total_licenses);
$('#online-devices').text(data.online_devices);
$('#expired-devices').text(data.expired_devices);
$('#today-new').text(data.today_new);
$('#unused-licenses').text(data.unused_licenses);
// 计算比率
var activeRate = data.total_devices > 0 ?
((data.online_devices / data.total_devices) * 100).toFixed(1) : 0;
var expiredRate = data.total_devices > 0 ?
((data.expired_devices / data.total_devices) * 100).toFixed(1) : 0;
$('#active-rate').text(activeRate + '%');
$('#expired-rate').text(expiredRate + '%');
}
// 更新图表
function updateCharts(data) {
// 设备注册趋势图
var trendOption = {
title: {
text: '最近7天设备注册趋势'
},
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: data.trend_dates
},
yAxis: {
type: 'value'
},
series: [{
name: '新增设备',
type: 'line',
smooth: true,
data: data.trend_counts,
itemStyle: {
color: '#009688'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(0, 150, 136, 0.3)'
}, {
offset: 1,
color: 'rgba(0, 150, 136, 0.1)'
}])
}
}]
};
registerTrendChart.setOption(trendOption);
// 设备类型分布图
var typesOption = {
title: {
text: '设备类型分布'
},
tooltip: {
trigger: 'item',
formatter: '{b}: {c} ({d}%)'
},
series: [{
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '20',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: data.device_types.map(item => ({
name: item.type,
value: item.count
}))
}]
};
deviceTypesChart.setOption(typesOption);
}
// 更新系统状态
function updateSystemStatus(data) {
$('#cpu-usage').text(data.cpu_usage + '%');
$('#memory-usage').text(data.memory_usage + '%');
$('#disk-usage').text(data.disk_usage + '%');
$('#uptime').text(formatDuration(data.uptime));
$('#load-avg').text(data.load_avg.join(' '));
$('#network-traffic').text(formatBytes(data.network_traffic) + '/s');
$('#online-users').text(data.online_users);
$('#last-update').text(new Date().toLocaleString());
}
// 格式化时间
function formatDuration(seconds) {
var days = Math.floor(seconds / 86400);
var hours = Math.floor((seconds % 86400) / 3600);
var minutes = Math.floor((seconds % 3600) / 60);
var parts = [];
if (days > 0) parts.push(days + '天');
if (hours > 0) parts.push(hours + '小时');
if (minutes > 0) parts.push(minutes + '分钟');
return parts.join(' ') || '0分钟';
}
// 格式化字节大小
function formatBytes(bytes) {
if (bytes === 0) return '0 B';
var k = 1024;
var sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
var i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
}
// 初始加载
loadStats();
// 定时刷新每30秒
setInterval(loadStats, 30000);
// 窗口大小改变时重绘图表
window.onresize = function() {
registerTrendChart.resize();
deviceTypesChart.resize();
};
});