From f89522cb887d23be174eb5e8afb3b8dab760cff1 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Thu, 27 Nov 2025 00:40:50 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=8D=A1=E7=89=87=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=8D=A0=E6=BB=A1=E6=97=B6=E4=BB=A5K=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E6=98=BE=E7=A4=BA=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...复CPU使用率卡片WebSocket自动更新问题 (1).md | 22 ++ .../修复CPU使用率卡片WebSocket自动更新问题.md | 18 + .../documents/减小统计卡片大小并移除统计图.md | 40 ++ static/index.html | 367 +++++++++--------- static/js/app.js | 15 +- static/js/dashboard.js | 55 ++- static/js/server-status.js | 15 +- 7 files changed, 327 insertions(+), 205 deletions(-) create mode 100644 .trae/documents/修复CPU使用率卡片WebSocket自动更新问题 (1).md create mode 100644 .trae/documents/修复CPU使用率卡片WebSocket自动更新问题.md create mode 100644 .trae/documents/减小统计卡片大小并移除统计图.md diff --git a/.trae/documents/修复CPU使用率卡片WebSocket自动更新问题 (1).md b/.trae/documents/修复CPU使用率卡片WebSocket自动更新问题 (1).md new file mode 100644 index 0000000..26bf7f2 --- /dev/null +++ b/.trae/documents/修复CPU使用率卡片WebSocket自动更新问题 (1).md @@ -0,0 +1,22 @@ +## 问题分析 +CPU使用率卡片在WebSocket实时更新时没有刷新数据,原因是: +1. `processRealTimeData`函数调用了`updateStatsCards(stats)`,但该函数的CPU使用率更新逻辑可能没有被正确执行 +2. `processRealTimeData`函数对其他卡片(如平均响应时间、最常用查询类型、活跃IP数)有单独的更新逻辑,但缺少了CPU使用率卡片的更新逻辑 +3. `loadDashboardData`函数中有完整的CPU使用率更新逻辑,这就是为什么页面初始加载时CPU使用率能显示,但后续WebSocket更新时不能显示的原因 + +## 修复方案 +1. **在`processRealTimeData`函数中添加CPU使用率卡片的更新逻辑**:类似于`loadDashboardData`函数中的实现 +2. **确保从`stats`对象中正确获取CPU使用率数据**:支持从不同的数据结构中获取CPU使用率 +3. **更新DOM元素**:将获取到的CPU使用率数据更新到`cpu-usage`和`cpu-status`元素中 +4. **添加状态判断**:根据CPU使用率值设置不同的状态文本和样式 + +## 实现步骤 +1. 打开`dashboard.js`文件 +2. 找到`processRealTimeData`函数(约第120行) +3. 在函数末尾添加CPU使用率更新逻辑,位于其他卡片更新逻辑之后 +4. 确保从`stats`对象中正确获取CPU使用率数据 +5. 更新`cpu-usage`和`cpu-status`元素的内容和样式 +6. 测试修复是否生效 + +## 预期效果 +修复后,当WebSocket接收到实时数据更新时,CPU使用率卡片会自动更新显示最新的CPU使用率和状态,与其他统计卡片保持一致的实时更新效果。 \ No newline at end of file diff --git a/.trae/documents/修复CPU使用率卡片WebSocket自动更新问题.md b/.trae/documents/修复CPU使用率卡片WebSocket自动更新问题.md new file mode 100644 index 0000000..942931f --- /dev/null +++ b/.trae/documents/修复CPU使用率卡片WebSocket自动更新问题.md @@ -0,0 +1,18 @@ +## 问题分析 +CPU使用率卡片数据不会跟随WebSocket自动更新的原因是`updateStatsCards`函数中缺少了CPU使用率的更新逻辑。该函数负责处理WebSocket实时数据并更新统计卡片,但只更新了7个统计卡片,遗漏了CPU使用率卡片。 + +## 修复方案 +1. **修改`updateStatsCards`函数**:在`dashboard.js`文件中添加CPU使用率和状态的更新逻辑 +2. **添加数据获取逻辑**:从不同可能的数据结构中获取CPU使用率数据 +3. **更新DOM元素**:将获取到的CPU使用率数据更新到`cpu-usage`和`cpu-status`元素中 +4. **添加状态判断**:根据CPU使用率值设置不同的状态文本和样式 + +## 实现步骤 +1. 打开`dashboard.js`文件 +2. 找到`updateStatsCards`函数(约第550行) +3. 在函数末尾添加CPU使用率更新逻辑 +4. 确保从`stats`对象中正确获取CPU使用率数据 +5. 更新`cpu-usage`和`cpu-status`元素的内容和样式 + +## 预期效果 +修复后,当WebSocket接收到实时数据更新时,CPU使用率卡片会自动更新显示最新的CPU使用率和状态,与其他统计卡片保持一致的实时更新效果。 \ No newline at end of file diff --git a/.trae/documents/减小统计卡片大小并移除统计图.md b/.trae/documents/减小统计卡片大小并移除统计图.md new file mode 100644 index 0000000..d29c2b9 --- /dev/null +++ b/.trae/documents/减小统计卡片大小并移除统计图.md @@ -0,0 +1,40 @@ +# 减小统计卡片大小并移除统计图 + +## 需求分析 +用户希望减小统计卡片的大小并移除卡片中的统计图,只保留数值和基本信息。 + +## 实现方案 + +### 1. 修改统计卡片HTML结构 +- 移除每个统计卡片中包含canvas元素的div(高度为16px的图表区域) +- 减小卡片的内边距(从p-6改为p-4) +- 调整卡片内部元素的间距,确保布局紧凑美观 + +### 2. 移除图表相关JavaScript代码 +- 移除dashboard.js中对`initStatCardCharts()`和`updateStatCardCharts()`函数的调用 +- 这些函数负责初始化和更新统计卡片中的折线图 +- 移除后不会影响其他图表功能(如主图表区域的图表) + +### 3. 具体修改点 + +#### HTML文件修改(index.html) +- 对于每个统计卡片(共8个),移除包含canvas的div元素 +- 减小卡片内边距:将`p-6`改为`p-4` +- 调整卡片内部元素的margin和padding,确保布局紧凑 + +#### JavaScript文件修改(dashboard.js) +- 移除第31行的`initStatCardCharts()`调用 +- 移除第139行的`updateStatCardCharts(stats)`调用 +- 移除第367行的`updateStatCardCharts(stats)`调用 +- 移除第525行的`updateStatCardCharts(stats)`调用 + +## 预期效果 +- 统计卡片大小减小,布局更紧凑 +- 卡片中只显示标题、数值和百分比信息 +- 移除了不必要的图表,减少了页面加载时间和资源消耗 +- 整体界面更简洁,重点突出数值信息 + +## 注意事项 +- 确保移除图表后不会导致其他功能错误 +- 保持卡片之间的一致性和美观性 +- 确保数值和百分比信息清晰可见 \ No newline at end of file diff --git a/static/index.html b/static/index.html index 19e7e20..e7fadd8 100644 --- a/static/index.html +++ b/static/index.html @@ -305,209 +305,188 @@
- -
- -
-
-
-

查询总量

-
- -
-
-
-
-

0

- - - 0% - -
-
- -
-
-
+ +
+ +
+
+
+

查询总量

+
+
- - -
- -
-
-
-

屏蔽数量

-
- -
-
-
-
-

0

- - - 0% - -
-
- -
-
-
+
+
+
+

0

+ + + 0% +
- - -
- -
-
-
-

正常解析

-
- -
-
-
-
-

0

- - - 0% - -
-
- -
-
-
+
+
+
+ + +
+ +
+
+
+

屏蔽数量

+
+
- - -
- -
-
-
-

错误数量

-
- -
-
-
-
-

0

- - - 0% - -
-
- -
-
-
+
+
+
+

0

+ + + 0% +
- - -
- -
-
-
-

平均响应时间

-
- -
-
-
-
-

0ms

- - - 0% - -
-
- -
-
-
+
+
+
+ + +
+ +
+
+
+

正常解析

+
+
- - -
- -
-
-
-

最常用查询类型

-
- -
-
-
-

A

- - - 0% - -
-
+
+
+
+

0

+ + + 0% +
- - -
- -
-
-
-

活跃来源IP

-
- -
-
-
-
-

0

- - - 0% - -
-
- -
-
-
+
+
+
+ + +
+ +
+
+
+

错误数量

+
+
- - -
- -
-
-
-

CPU使用率

-
- -
-
-
-
-

0%

- - - 正常 - -
-
- -
-
-
+
+
+
+

0

+ + + 0% +
+
+
+ + +
+ +
+
+
+

平均响应时间

+
+ +
+
+
+
+

0ms

+ + + 0% + +
+
+
+
+ + +
+ +
+
+
+

最常用查询类型

+
+ +
+
+
+

A

+ + + 0% + +
+
+
+ + +
+ +
+
+
+

活跃来源IP

+
+ +
+
+
+
+

0

+ + + 0% + +
+
+
+
+ + +
+ +
+
+
+

CPU使用率

+
+ +
+
+
+
+

0%

+ + + 正常 + +
+
+
+
+
diff --git a/static/js/app.js b/static/js/app.js index a807cc9..c193813 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -197,12 +197,25 @@ function apiRequest(endpoint, method = 'GET', data = null, maxRetries = 3) { // 数字格式化函数 function formatNumber(num) { + // 显示完整数字的最大长度阈值 + const MAX_FULL_LENGTH = 5; + + // 先获取完整数字字符串 + const fullNumStr = num.toString(); + + // 如果数字长度小于等于阈值,直接返回完整数字 + if (fullNumStr.length <= MAX_FULL_LENGTH) { + return fullNumStr; + } + + // 否则使用缩写格式 if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } else if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } - return num.toString(); + + return fullNumStr; } // 确认对话框函数 diff --git a/static/js/dashboard.js b/static/js/dashboard.js index f4b45a6..9bf0d69 100644 --- a/static/js/dashboard.js +++ b/static/js/dashboard.js @@ -27,8 +27,7 @@ async function initDashboard() { // 初始化图表 initCharts(); - // 初始化统计卡片折线图 - initStatCardCharts(); + // 初始化时间范围切换 initTimeRangeToggle(); @@ -135,8 +134,7 @@ function processRealTimeData(stats) { // 更新图表数据 updateCharts(stats, queryTypeStats); - // 更新卡片图表 - updateStatCardCharts(stats); + // 尝试从stats中获取总查询数等信息 if (stats.dns) { @@ -363,8 +361,7 @@ async function loadDashboardData() { updateTopBlockedTable(topBlockedDomains); updateRecentBlockedTable(recentBlockedDomains); - // 更新卡片图表 - updateStatCardCharts(stats); + // 尝试从stats中获取总查询数等信息 if (stats.dns) { @@ -521,8 +518,7 @@ async function loadDashboardData() { // 更新图表 updateCharts({totalQueries, blockedQueries, allowedQueries, errorQueries}); - // 更新统计卡片折线图 - updateStatCardCharts(stats); + // 确保响应时间图表使用API实时数据 if (document.getElementById('avg-response-time')) { @@ -558,6 +554,7 @@ function updateStatsCards(stats) { let totalQueries = 0, blockedQueries = 0, allowedQueries = 0, errorQueries = 0; let topQueryType = 'A', queryTypePercentage = 0; let activeIPs = 0, activeIPsPercentage = 0; + let cpuUsageValue = 0; // 检查数据结构,兼容可能的不同格式 if (stats) { @@ -570,6 +567,12 @@ function updateStatsCards(stats) { queryTypePercentage = stats.queryTypePercentage || 0; activeIPs = stats.activeIPs || 0; activeIPsPercentage = stats.activeIPsPercentage || 0; + // 获取CPU使用率 + cpuUsageValue = stats.cpuUsage || 0; + // 从system对象获取CPU使用率 + if (stats.system && typeof stats.system.cpu === 'number') { + cpuUsageValue = stats.system.cpu; + } // 如果dns对象存在,优先使用其中的数据 if (stats.dns) { @@ -774,6 +777,27 @@ function updateStatsCards(stats) { updatePercentage('allowed-percent', '---'); updatePercentage('error-percent', '---'); } + + // 更新CPU使用率 + updatePercentage('cpu-usage', `${cpuUsageValue.toFixed(2)}%`); + + // 更新CPU状态 + const cpuStatusElem = document.getElementById('cpu-status'); + if (cpuStatusElem) { + let statusText = '正常'; + let statusClass = 'text-success'; + + if (cpuUsageValue > 80) { + statusText = '警告'; + statusClass = 'text-danger'; + } else if (cpuUsageValue > 60) { + statusText = '较高'; + statusClass = 'text-warning'; + } + + updatePercentage('cpu-status', statusText); + cpuStatusElem.className = `text-sm flex items-center ${statusClass}`; + } } // 更新Top屏蔽域名表格 @@ -2292,12 +2316,25 @@ function generateTimeLabels(count) { // 格式化数字显示(使用K/M后缀) function formatNumber(num) { + // 显示完整数字的最大长度阈值 + const MAX_FULL_LENGTH = 5; + + // 先获取完整数字字符串 + const fullNumStr = num.toString(); + + // 如果数字长度小于等于阈值,直接返回完整数字 + if (fullNumStr.length <= MAX_FULL_LENGTH) { + return fullNumStr; + } + + // 否则使用缩写格式 if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } else if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } - return num.toString(); + + return fullNumStr; } // 更新运行状态 diff --git a/static/js/server-status.js b/static/js/server-status.js index b7c6f31..fa2d8c0 100644 --- a/static/js/server-status.js +++ b/static/js/server-status.js @@ -263,12 +263,25 @@ function addGlowEffect() { // 格式化数字 function formatNumber(num) { + // 显示完整数字的最大长度阈值 + const MAX_FULL_LENGTH = 5; + + // 先获取完整数字字符串 + const fullNumStr = num.toString(); + + // 如果数字长度小于等于阈值,直接返回完整数字 + if (fullNumStr.length <= MAX_FULL_LENGTH) { + return fullNumStr; + } + + // 否则使用缩写格式 if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } else if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } - return num.toString(); + + return fullNumStr; } // 在DOM加载完成后初始化