From 6b48b8fac3e04a92a475e163844d1e26d91f6957 Mon Sep 17 00:00:00 2001 From: caoxiaozhu Date: Mon, 13 Jul 2026 10:31:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=A1=AC=E4=BB=B6=E7=9C=8B=E6=9D=BF?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=20GPU=20=E8=BF=9B=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HardwareView 增加显卡进程占用列表展示,配套回归脚本与 npm test:hardware 脚本注册。 --- frontend/package.json | 1 + .../scripts/regression-hardware-dashboard.mjs | 41 + frontend/src/views/system/HardwareView.vue | 778 ++++++++++++------ 3 files changed, 585 insertions(+), 235 deletions(-) create mode 100644 frontend/scripts/regression-hardware-dashboard.mjs diff --git a/frontend/package.json b/frontend/package.json index 950825d..92a6362 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,6 +17,7 @@ "test:eval-create": "node scripts/regression-eval-create-wizard.mjs", "test:eval-detail": "node scripts/regression-eval-detail.mjs", "test:model-manage": "node scripts/regression-model-manage.mjs", + "test:hardware": "node scripts/regression-hardware-dashboard.mjs", "test:training-log-layout": "node scripts/regression-training-log-layout.mjs", "test:page-surface": "node scripts/regression-page-surface.mjs" }, diff --git a/frontend/scripts/regression-hardware-dashboard.mjs b/frontend/scripts/regression-hardware-dashboard.mjs new file mode 100644 index 0000000..0f20df8 --- /dev/null +++ b/frontend/scripts/regression-hardware-dashboard.mjs @@ -0,0 +1,41 @@ +import assert from 'node:assert/strict' +import { readFile } from 'node:fs/promises' +import { fileURLToPath } from 'node:url' +import path from 'node:path' + +const scriptDir = path.dirname(fileURLToPath(import.meta.url)) +const sourceRoot = path.resolve(scriptDir, '../src') + +const [viewSource, typeSource, mockSource] = await Promise.all([ + readFile(path.join(sourceRoot, 'views/system/HardwareView.vue'), 'utf8'), + readFile(path.join(sourceRoot, 'types/index.ts'), 'utf8'), + readFile(path.join(sourceRoot, 'mock/data.ts'), 'utf8'), +]) + +assert.match(viewSource, /title="平台性能"/, '平台性能页缺少明确标题') +assert.match(viewSource, /硬件资源概览/, '平台性能页缺少硬件资源概览') +assert.match(viewSource, /系统资源趋势/, '平台性能页缺少资源趋势') +assert.match(viewSource, /GPU 资源池/, '平台性能页缺少 GPU 资源池') +assert.match(viewSource, /gpu-detail-drawer/, 'GPU 卡片缺少详情抽屉') +assert.match(viewSource, /GPU 进程/, 'GPU 详情缺少占用进程表') +assert.match(viewSource, /visibilitychange/, '轮询没有在页面不可见时暂停') +assert.match(viewSource, /requesting \|\| disposed/, '轮询缺少防重入保护') +assert.match(viewSource, /slice\(-60\)/, '趋势快照没有限制为最近 60 个采样点') +assert.match(viewSource, /@keydown="handleGpuKeydown/, 'GPU 卡片缺少键盘访问能力') +assert.match(viewSource, /download_mb_s/, '网络概览没有使用明确的实时速率字段') +assert.doesNotMatch( + viewSource, + /download_mb_s\s*\?\?\s*info\.network\?\.download_mb/, + '不能把累计网络流量回退显示为实时速率', +) + +assert.match(typeSource, /export interface GpuProcess/, '系统监控类型缺少 GPU 进程结构') +assert.match(typeSource, /processes\?: GpuProcess\[\]/, 'GPU 类型缺少进程详情') +assert.match(typeSource, /download_mb_s\?: number/, '系统类型缺少实时网络接收速率') +assert.match(typeSource, /power_limit_w\?: number/, 'GPU 类型缺少功耗上限') + +for (let id = 0; id < 8; id += 1) { + assert.match(mockSource, new RegExp(`id:\\s*${id},[\\s\\S]*?uuid:\\s*'GPU-MOCK-A800-0${id}'`), `Mock 缺少 GPU ${id} 详情`) +} + +console.log('平台性能页回归检查通过') diff --git a/frontend/src/views/system/HardwareView.vue b/frontend/src/views/system/HardwareView.vue index 9c11724..765cfcd 100644 --- a/frontend/src/views/system/HardwareView.vue +++ b/frontend/src/views/system/HardwareView.vue @@ -1,283 +1,591 @@