feat: 新增服务看板页面
实现 Dashboard 看板视图并将应用默认入口由调优改为看板,路由、侧边栏默认菜单与登录跳转同步调整;侧边栏增加导航失败高亮校正,布局与 ECharts 注册柱状图适配看板,补充两份回归脚本、设计走查记录与五张设计截图。
This commit is contained in:
50
frontend/scripts/regression-dashboard.mjs
Normal file
50
frontend/scripts/regression-dashboard.mjs
Normal file
@@ -0,0 +1,50 @@
|
||||
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 [routerSource, dashboardSource, echartsSource, mainLayoutSource] = await Promise.all([
|
||||
readFile(path.resolve(scriptDir, '../src/router/index.ts'), 'utf8'),
|
||||
readFile(path.resolve(scriptDir, '../src/views/dashboard/DashboardView.vue'), 'utf8'),
|
||||
readFile(path.resolve(scriptDir, '../src/plugins/echarts.ts'), 'utf8'),
|
||||
readFile(path.resolve(scriptDir, '../src/layouts/MainLayout.vue'), 'utf8'),
|
||||
])
|
||||
|
||||
assert.match(
|
||||
routerSource,
|
||||
/path:\s*['"]dashboard['"][\s\S]*?DashboardView\.vue/,
|
||||
'服务看板路由应使用独立 DashboardView',
|
||||
)
|
||||
|
||||
assert.match(echartsSource, /import\s*\{[^}]*BarChart[^}]*\}\s*from\s*['"]echarts\/charts['"]/, 'ECharts 未注册 BarChart')
|
||||
assert.match(echartsSource, /use\(\[[\s\S]*?BarChart[\s\S]*?\]\)/, 'BarChart 未加入 ECharts 按需注册列表')
|
||||
|
||||
for (const copy of [
|
||||
'平台运行状态',
|
||||
'近 7 天训练统计',
|
||||
'训练次数(次)',
|
||||
'GPU 使用数(个)',
|
||||
'平均准确率(%)',
|
||||
'服务状态',
|
||||
'训练任务',
|
||||
'查看全部任务',
|
||||
]) {
|
||||
assert.ok(dashboardSource.includes(copy), `服务看板缺少关键内容:${copy}`)
|
||||
}
|
||||
|
||||
assert.match(dashboardSource, /yAxis:\s*\[[\s\S]*?次数 \/ GPU 数[\s\S]*?准确率/, '柱状图应使用双 Y 轴表达不同单位')
|
||||
assert.match(dashboardSource, /name:\s*['"]平均准确率(%)['"][\s\S]*?yAxisIndex:\s*1/, '准确率柱应绑定右侧百分比坐标轴')
|
||||
assert.match(dashboardSource, /router\.push\(['"]\/fine-tune['"]\)/, '查看全部任务应进入模型微调列表')
|
||||
assert.match(dashboardSource, /router\.push\(`\/training-log\/\$\{task\.id\}`\)/, '训练任务详情应进入训练日志页')
|
||||
assert.doesNotMatch(dashboardSource, /class=["']dashboard-heading["']/, '服务看板不应重复展示页面标题栏')
|
||||
assert.doesNotMatch(dashboardSource, /查看告警/, '服务看板不应保留冗余的顶部告警按钮')
|
||||
assert.match(dashboardSource, /\.dashboard-view\s*\{[\s\S]*?gap:\s*10px;/, '服务看板应使用紧凑的区块间距')
|
||||
assert.match(dashboardSource, /\.dashboard-middle\s*\{[\s\S]*?flex:\s*1 1 auto;[\s\S]*?min-height:\s*0;/, '中间区域应弹性占满剩余高度')
|
||||
assert.match(dashboardSource, /\.training-chart\s*\{[\s\S]*?flex:\s*1 1 auto;[\s\S]*?height:\s*auto;[\s\S]*?min-height:\s*230px;/, '训练统计图应随可用空间自动拉伸')
|
||||
assert.match(dashboardSource, /@media\s*\(max-height:\s*900px\)[\s\S]*?\.training-chart\s*\{[\s\S]*?min-height:\s*200px;/, '较矮桌面视口应保留图表最小可读高度')
|
||||
assert.match(dashboardSource, /\.service-table\s*\{[\s\S]*?grid-template-rows:[^;]*repeat\(4,\s*minmax\(48px,\s*1fr\)\)/, '服务状态行应随中间区域同步拉伸')
|
||||
assert.match(mainLayoutSource, /\.layout-content:has\(\.dashboard-view\)[\s\S]*?overflow-y:\s*hidden;/, '服务看板容器应避免产生页面纵向滚动条')
|
||||
assert.match(mainLayoutSource, /\.page-canvas\s*\{[\s\S]*?flex:\s*1 1 auto;[\s\S]*?overflow:\s*hidden;/, '服务看板页面画布应约束在可用视口内')
|
||||
|
||||
console.log('服务看板回归检查通过')
|
||||
39
frontend/scripts/regression-default-dashboard.mjs
Normal file
39
frontend/scripts/regression-default-dashboard.mjs
Normal file
@@ -0,0 +1,39 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const root = resolve(fileURLToPath(new URL('..', import.meta.url)))
|
||||
|
||||
function read(relativePath) {
|
||||
return readFileSync(resolve(root, relativePath), 'utf8')
|
||||
}
|
||||
|
||||
function assert(condition, message) {
|
||||
if (!condition) throw new Error(message)
|
||||
}
|
||||
|
||||
const router = read('src/router/index.ts')
|
||||
const login = read('src/views/login/LoginView.vue')
|
||||
const sidebar = read('src/components/AppSidebar.vue')
|
||||
|
||||
assert(
|
||||
router.includes("redirect: '/dashboard'"),
|
||||
'The authenticated root and fallback routes should default to 服务看板',
|
||||
)
|
||||
|
||||
assert(
|
||||
router.includes("next('/dashboard')"),
|
||||
'An authenticated user visiting the login page should enter 服务看板',
|
||||
)
|
||||
|
||||
assert(
|
||||
login.includes("router.push('/dashboard')"),
|
||||
'A successful login should navigate to 服务看板',
|
||||
)
|
||||
|
||||
assert(
|
||||
sidebar.includes("route.path.split('/')[1] || 'dashboard'"),
|
||||
'The sidebar fallback active item should be 服务看板',
|
||||
)
|
||||
|
||||
console.log('default-dashboard regression checks passed')
|
||||
Reference in New Issue
Block a user