节点在线、应用在线、配置在线使用令牌查询
大石头 authored at 2021-12-16 19:49:30
31.08 KiB
Stardust
# 星尘看板设计稿 > 版本:v1.2 · 2026-10-31(MVC StarWeb 落地,补充实现记录与设计调整) > 实现目标:MVC StarWeb(`Stardust.Web`,已落地,见 §16);Vue 版 StarWeb(`Stardust.Web.Vue`)后续按同一设计稿迁移 > 视觉基准:[设计令牌](/NewLife/Stardust/Blob/master/Doc/Dashboard/../../Stardust.Web.Vue/src/design-system/tokens.css) · 星尘设计系统(明暗双主题,默认跟随系统) 本目录是星尘平台**分层看板**的设计蓝本,包含 5 个可交互 HTML 原型与本文档。MVC 控制台(`Stardust.Web`)已于 2026-10-31 完成落地,路由、数据来源与设计调整见 §16。 --- ## 1. 目标与范围 ### 1.1 要解决的问题 现有 StarWeb 只有一个「控制台概览」聚合页,缺少分层视角: - 进入某个应用时,看不到该应用的在线状态、错误、慢端点、实例健康与最近变更; - 进入某个项目时,应用与节点分散在不同列表页,无法一屏判断项目健康; - 运维排查节点问题时,需要同时看资源时序、网络质量、进程与部署情况; - 平台管理员缺少全局视角,且现有列表接口没有数据级项目隔离。 ### 1.2 设计目标 | 目标 | 说明 | |------|------| | 分层回答 | 系统 → 项目 → 应用 / 节点,每一层只回答该层最关心的问题 | | 3 秒结论 | 顶部 KPI 先给结论,主图解释原因,右侧事件流提示变化 | | 状态先行 | 在线 / 告警 / 离线三态贯穿所有卡片、图表与列表 | | 权限即范围 | 每页标注可见项目范围;无授权不留空图表,给出申请入口 | | 可直接落地 | 所有视觉值来自 `--sd-*` 令牌,组件与 StarWeb 现有 GlassCard / KpiStat 对齐 | ### 1.3 非目标 - 不修改 `Stardust.Web`(MVC 控制台)任何功能; - 不在本目录实现真实数据接入; - 不定义新的后端协议细节(仅给出 scope 契约建议,见 §7.2)。 --- ## 2. 设计总览 ### 2.1 四层信息架构 | 层级 | 看板 | 入口 | 回答的问题 | 主要下钻 | |:----:|------|------|------------|---------| | L0 | 系统级看板 | 侧栏「系统」 | 平台整体好不好?哪个项目/应用最差? | 项目看板、应用看板 | | L1 | 项目看板 | 系统看板项目行 / 项目列表 | 这个项目下的应用和节点现在怎么样? | 应用看板、节点看板 | | L2 | 应用看板 | 项目应用卡 / 应用列表 | 应用是否在线?有没有报错?慢在哪?实例健康吗? | 节点看板、调用链、跟踪统计 | | L2 | 节点看板 | 项目节点行 / 实例表 | 这台机器健康吗?谁在吃资源?最近做过什么? | 应用看板、指令记录 | | — | 大屏模式 | 系统看板「投屏」 | 无人值守时,一屏轮播全局态势 | — | ### 2.2 统一骨架 ``` ┌────────────────────────────────────────────────────────────────────────┐ │ 顶栏:品牌 · 项目上下文 · 可见范围徽标 · 时钟 / 刷新 / 账号 │ ├────────────────────────────────────────────────────────────────────────┤ │ 作用域栏:面包屑 · 页面标题 / 状态 · 时间范围 · 自动刷新 · 投屏 · 主操作 │ ├────────────────────────────────────────────────────────────────────────┤ │ KPI 条(6 卡):结论数字 + 环比 + 迷你趋势 │ ├───────────────────────────────────────────────┬────────────────────────┤ │ 主区:趋势 / 矩阵 / 列表(24 栅格,14px gutter)│ 事件栏(可折叠) │ ├───────────────────────────────────────────────┴────────────────────────┤ │ 页脚:数据来源 · 最后更新时间 · 下钻提示 │ └────────────────────────────────────────────────────────────────────────┘ ``` - 侧栏沿用 StarWeb 56px 图标导航(原型中为 60px,实现时以现有布局为准)。 - 卡片统一为玻璃拟态:`backdrop-filter: blur(14px)` + 1px 边框 + 16px 圆角 + 蓝调阴影。 - 页面宽度上限 1680px,超宽屏留白,避免大屏拉伸导致信息密度过低。 ### 2.3 栅格与断点 | 断点 | 主区栅格 | KPI | 说明 | |------|----------|-----|------| | ≥ 1360px | 24 列 | 6 列 | 完整双栏 + 事件栏 | | 1100–1359px | 12 列 | 3 列 | 卡片两两合并,事件栏移至底部 | | < 1100px | 2 列 | 2 列 | 单列滚动,保留 KPI 与主图 | | < 720px | 1 列 | 1 列 | 移动端仅保证可读 | --- ## 3. 设计语言 ### 3.1 色彩 | 令牌 | 暗色 | 浅色 | 用途 | |------|------|------|------| | `--sd-color-brand` | `#6673FF` | `#4F5BE8` | 主操作、活动态、品牌 | | `--sd-color-brand-2` | `#8C5CF5` | `#7A46E0` | 渐变末端、应用拓扑节点 | | `--sd-color-accent` | `#6FE3EC` | `#0E8F9B` | 强调、焦点、星尘青 | | `--sd-color-online` | `#43E8A3` | `#0B9A66` | 在线 / 成功 / 正常 | | `--sd-color-alert` | `#FFC208` | `#B45309` | 告警 / 接近阈值 | | `--sd-color-offline` | `#FF4545` | `#D92D20` | 离线 / 错误 / 超限 | | `--sd-bg-page` | `#16202A` | `#F2F5FA` | 页面底色 | | `--sd-bg-surface` | `#1F2A33` | `#FFFFFF` | 卡片 / 侧栏表面 | | `--sd-bg-elevated` | `#26333F` | `#FFFFFF` | 悬浮层 / 抽屉 | | `--sd-text-primary` | `#E6EDF3` | `#16202A` | 主文本 | | `--sd-text-secondary` | `#8A97A6` | `#5C6B7A` | 次要文本 | - 原型与实现都只能引用变量,禁止在页面内硬编码十六进制色值; - 浅色令牌是本次设计稿的扩展(官方 `tokens.css` 目前只有暗色),实现时建议把 `[data-theme="light"]` 块合并回上游,保持单一事实源; - 图表(canvas)无法读取 CSS 变量,`assets/charts.js` 维护 **暗色 / 浅色双调色板**,按 `<html data-theme>` 选择;主题切换后需重建图表(原型用重载,见 §15)。 ### 3.2 字体与数字 - 正文:`Inter / PingFang SC / Microsoft YaHei`,正文 14px、辅助 11–12px; - 数字:`font-variant-numeric: tabular-nums`,KPI 29–30px,大屏 `clamp(24px, 2.35vw, 44px)`; - 代码 / 标识:`JetBrains Mono / Consolas`,用于 IP、AppId、traceId、版本号。 ### 3.3 卡片与状态 - 卡片头:3px 品牌渐变竖条 + 13px 半粗标题 + 右侧提示 / 链接; - 状态药丸:色值 12% 透明度底 + 6px 圆点,在线状态加呼吸动画; - 水位条:正常绿 / 警戒黄(≥65%)/ 危险红(≥80%),项目节点资源统一使用; - 空态:图标 + 一句原因 + 下一步操作,不出现空白图表。 --- ## 4. 各看板信息架构 ### 4.1 系统级看板(`system.html`) | 区块 | 栅格 | 内容 | 交互 | |------|:----:|------|------| | 作用域栏 | 24 | 标题、整体状态、覆盖项目/应用/节点数 | 时间范围、自动刷新、投屏 | | KPI × 6 | 24 | 项目(可见)、在线应用、节点在线、今日请求、P95、错误率 | 项目卡显示可见数量 | | 全局吞吐与质量 | 16 | 请求量面积 + 错误率折线(双轴),24h / 7d | 时间切换 | | 集群健康 | 8 | 在线/告警/离线环 + 离线与告警 Top3 | 点击进节点 | | 项目健康矩阵 | 8 | 项目 × 应用/节点/错误率/告警/健康度 | 点击项目行下钻 | | Top 应用 | 8 | QPS / 错误率 / 耗时三视图横向条形 | 点击进应用 | | 服务拓扑 | 8 | ECharts graph,节点大小 = QPS | 点击下钻 | | 机房资源水位 | 16 | 南京/上海/广州/北京 CPU/内存/磁盘分组柱 | hover 查看 | | 实时事件 | 8 | 告警、部署、上下线、配置变更时间流 | 点击查看详情 | **权限表现**:右上角「可见 3 / 12 个项目」;受限时隐藏未授权项目行并给出提示条;无授权时整页空态 + 申请按钮。 ### 4.2 项目看板(`project.html`) | 区块 | 栅格 | 内容 | |------|:----:|------| | 项目头 | 24 | 名称、负责人、成员数、创建时间、项目 ID、数据范围、快捷操作 | | KPI × 6 | 24 | 在线应用、节点在线、服务实例、今日请求、P95、活跃告警 | | 应用矩阵 | 16 | 每个应用一张卡:状态、实例、QPS、错误率、sparkline、版本与耗时 | | 节点资源 | 8 | 节点名/机房/IP、状态、CPU/内存/磁盘水位 | | 项目拓扑 | 12 | 项目 → 应用 → 节点三层关系,连线宽度 = 实例数 | | 最近部署 | 6 | 应用、版本、节点数、耗时、状态 | | 当前告警 | 6 | 本项目的告警列表,未确认优先 | **空态**:项目未接入应用时,应用矩阵替换为 `AddStardust("appId")` 代码块与创建入口。 ### 4.3 应用看板(`app.html`) | 区块 | 栅格 | 内容 | |------|:----:|------| | 应用头 | 24 | 显示名 / AppId、所属项目、分类、版本与编译时间、在线状态、实例数、快捷操作 | | KPI × 6 | 24 | 当前 QPS、平均耗时、P95、错误率、在线实例、注册服务 | | 请求量与错误率趋势 | 16 | 24h 分钟粒度 / 7d 小时粒度,双轴 | | 实例健康 | 8 | 6/6 环图 + 平均在线时长/版本分布 + 实例表(节点、版本、在线、CPU/内存、状态) | | 端点 Top | 8 | 耗时 / 错误率 / 调用量三视图,点击进跟踪统计 | | 错误分布 | 8 | 状态码/异常类型环图 + 占比 + 最新错误样本(traceId 深链) | | 运行时性能 | 8 | CPU、内存、托管堆、线程、TCP、GC 六项指标 + 阈值色 | | 依赖服务 | 12 | 出站服务、存储、缓存的 QPS / 耗时 / 错误率 | | 最近变更 | 6 | 部署、配置、回滚时间线 | | 最新告警 | 6 | 本应用相关告警 | ### 4.4 节点看板(`node.html`,单节点) | 区块 | 栅格 | 内容 | |------|:----:|------| | 节点头 | 24 | 名称、IP、OS/架构、机房、运行时长、Agent 版本、操作 | | KPI × 6 | 24 | CPU、内存、磁盘、系统负载、温度、网络吞吐 | | 资源时序 | 16 | CPU / 内存 / 磁盘三线,1h / 24h / 7d | | 健康评分 | 8 | CPU / 内存 / 磁盘 / 网络 / 温度 / 稳定性六维雷达 | | 网络质量 | 8 | 内网 / 外网评分仪表 + 网关/DNS/服务器延迟与丢包 | | 磁盘分区 | 8 | `/data`、`/`、`/var/log` 水位与「预计写满天数」 | | 进程 Top | 8 | 按 CPU / 内存排序前 6 进程 | | 已部署应用 | 12 | 应用、版本、部署时间、端口、运行状态;附磁盘 I/O、IOPS、TCP 统计 | | 操作历史 | 6 | 远程命令、升级、重启、峰值告警时间线 | | 节点告警 | 6 | 本节点告警 | **离线态**:顶部横幅提示离线时长与最后上报时间,KPI 置灰、图表降透明度,仍保留最后一次快照。 ### 4.5 大屏模式(`wallboard.html`) - 16:9 铺满,无侧栏与顶栏,字号使用 `clamp()` 适配 1920×1080 与 2560×1440; - 布局:左列 3 张指标卡、中列大图 + 项目健康、右列事件 / Top 应用 / 机房资源; - 每 12s 轮播 4 个视角:总览吞吐 → 项目健康 → 机房资源 → 告警分布; - 底部进度条 + 圆点可点击切换,空格暂停;中心标题与图例随视角切换。 --- ## 5. 组件清单(StarWeb 实现建议) | 组件 | 说明 | 复用来源 | |------|------|---------| | `DashboardShell` | 顶栏 + 作用域栏 + 内容区 + 页脚 | 现有 StardustLayout | | `ScopeBar` | 面包屑、标题、状态、时间范围、刷新、投屏 | 新建 | | `ScopeBadge` | 可见项目范围徽标 + 项目选择抽屉 | 新建(TopBar 项目选择器扩展) | | `KpiTile` | 标签、主数字、单位、环比、sparkline、阈值色 | 扩展 KpiStat | | `GlassCard` | 玻璃卡片与标题条 | 直接复用 | | `TrendPanel` | ECharts 折线/面积图,统一轴与提示样式 | 扩展 EChart.vue | | `GaugeRing` / `HealthRadar` | 环图与雷达 | ECharts 封装 | | `HealthMatrix` | 项目/节点健康表格 + 水位条 | 新建 | | `EventFeed` | 告警/事件时间流,支持 2 行截断 | 新建 | | `AppCard` | 项目看板应用卡 | 新建 | | `NodeResourceBar` | CPU/内存/磁盘三段水位 | 新建 | | `EmptyState` | 无数据 / 无权限 / 接入引导 | 新建 | | `Skeleton` | 首屏骨架屏 | 新建 | --- ## 6. 数据映射(现有 WebApi) | 看板区块 | 接口 | 关键字段 | 建议刷新 | |----------|------|----------|:--------:| | 项目信息 | `/Platform/GalaxyProject` | name、managerId、nodes、apps、enable | 5 min | | 项目成员 | `/Platform/ProjectUser` | projectId、userId | 手动 | | 应用信息 | `/Registry/App` | name、displayName、category、version、compile、enable | 5 min | | 应用在线实例 | `/Registry/AppOnline` | appName、nodeName、clientId、version | 30 s | | 注册服务 | `/Registry/AppService` | appId、serviceId、client | 60 s | | 分钟级吞吐/耗时 | `/Monitors/AppMinuteStat` | total、errors、errorRate、cost、maxCost | 60 s | | 日级汇总 | `/Monitors/AppDayStat` | statDate、total、ringRate、apis、https、dbs | 5 min | | 端点与链路统计 | `/Monitors/TraceHourStat`、`/Monitors/TraceItem` | name、total、errors、cost、maxCost | 60 s | | 错误样本 | `/Monitors/TraceData` | traceId、name、cost、error | 60 s | | 运行时性能 | `/Monitors/AppMeter`(应用性能) | cpuUsage、memory、threads、heapSize、gcCount、connections | 30 s | | 节点实时 | `/Nodes/NodeOnline` | cpuRate、memory、diskIops、temperature、网络评分、tcpConnections | 30 s | | 节点时序 | `/Nodes/NodeStat`、`/Nodes/NodeData` | cpuRate、memory、freeSpace、iops | 60 s | | 节点基本信息 | `/Nodes/Node` | name、ip、os、location、uptime、version | 5 min | | 节点已部署应用 | `/Deployment/AppDeployNode` | appId、version、status、deployTime | 60 s | | 部署记录 | `/Deployment/AppDeploy`、`/Deployment/AppPipelineRun` | version、nodeCount、status、cost | 60 s | | 告警 | `/Monitors/AlarmRecord`、`/Monitors/AlarmHistory` | level、app、node、message、status | 30 s | > 分钟级与小时级统计为预聚合表,看板不直接扫描原始追踪数据;24h 图取 1 分钟/5 分钟粒度,7d 图取小时粒度,避免一次拉取过量点。 --- ## 7. 权限与数据范围 ### 7.1 现状(必须正视) 《[架构审查与权限分析](/NewLife/Stardust/Blob/master/Doc/Dashboard/../架构审查与权限分析.md)》第五节结论:当前只有**功能级权限**(`[EntityAuthorize]`),**没有数据级 `[DataPermission]`**;`ProjectUser`(项目成员)表未被任何业务查询使用;约 77% 的明细与时序表没有 `ProjectId`,只能经 `AppId` / `NodeId` 间接关联;Vue 前台没有项目作用域概念。 因此看板不能只在界面上"藏数据"——必须在服务端按当前用户可见项目过滤,否则受限账号仍可通过接口看到全量数据。 ### 7.2 建议的 scope 契约 ```http GET /api/dashboard/scope { "userId": 1024, "isAdmin": false, "projectIds": [1, 2, 3], "totalProjects": 12, "visibleProjects": 3, "generatedAt": "2026-10-30T14:20:00+08:00" } ``` - 所有看板接口(或统一的查询过滤器)接收/注入 `projectIds`: - 有 `ProjectId` 的表:直接 `ProjectId IN (...)`; - 无 `ProjectId` 的表:通过 `AppId` / `NodeId` 子查询间接过滤; - 管理员(`isAdmin`)返回全部项目,前端仍显示「全部 12 个项目」; - 前端在 Pinia 保存 scope,所有请求自动携带;URL 中的 `projectId` 只作为筛选,不作为权限依据; - 下钻详情(应用、节点)必须先校验所属项目在 scope 内,否则返回 403 并跳转无权限页; - 大屏与导出接口同样应用 scope,不能因为是"只读"而绕过。 ### 7.3 三态设计 | 状态 | 触发 | 表现 | |------|------|------| | 全量 | 管理员 / 全部项目可见 | 徽标「全部 12 个项目」,正常展示 | | 受限 | 仅部分项目可见 | 徽标「可见 3 / 12 个项目」+ 黄色提示条;隐藏未授权项目行;KPI 只统计可见范围 | | 无授权 | 未加入任何项目 | 整页空态,说明原因并给出申请入口;不渲染任何图表 | 评审时可通过 `?scope=limited` / `?scope=none` 直接查看后两态。 --- ## 8. 交互规范 1. **时间范围**:`1 小时 / 24 小时 / 7 天` 分段控件;切换只影响趋势图与 Top 列表,不刷新整页。 2. **自动刷新**:30s(实时指标)/ 60s(统计)/ 5min(元数据);页面失焦时暂停,按钮显示倒计时。 3. **下钻**:卡片、表格行、拓扑节点均可点击;下钻路径写入 URL(`/stardust/dashboard/app/:id?projectId=2&range=24h`),支持分享与浏览器后退。 4. **空态**: - 无数据:说明原因 + 接入引导(SDK 代码块); - 无权限:申请入口; - 加载失败:错误摘要 + 重试按钮; - 首屏:骨架屏,刷新时保留旧数据 + 按钮转圈(沿用现有概览页做法)。 5. **大屏**:空格暂停/继续轮播;点击指示条切换视角;`Esc` 退出全屏。 --- ## 9. 响应式与性能 - 图表统一使用 `EChart.vue` 封装,`resize` 由容器 ResizeObserver 触发; - 24h 曲线按 1 分钟粒度最多 1440 点,前端降采样到 200–300 点绘制; - 首屏并行请求:scope、项目、应用、节点、聚合统计; - 拓扑图节点超过 200 个时改为按项目聚合,避免力导向卡顿; - 大屏隐藏侧栏与顶栏,减少一层布局计算;`prefers-reduced-motion` 下关闭轮播与呼吸动画。 --- ## 10. StarWeb 落地建议 ### 10.1 路由 | 路由 | 页面 | 说明 | |------|------|------| | `/stardust/dashboard/system` | 系统级看板 | 兼容根路径重定向 | | `/stardust/dashboard/project/:id` | 项目看板 | `id` 为 GalaxyProject.Id | | `/stardust/dashboard/app/:id` | 应用看板 | `id` 为 App.Id | | `/stardust/dashboard/node/:id` | 节点看板 | `id` 为 Node.Id | | `/stardust/wallboard` | 大屏模式 | 独立布局,不加载侧栏 / 顶栏 | ### 10.2 目录与模型 ``` apps/stardust/src/views/Dashboard/ ├── System/index.vue ├── Project/index.vue ├── App/index.vue ├── Node/index.vue ├── Wallboard/index.vue ├── components/ # KpiTile / HealthMatrix / EventFeed / AppCard ... └── models/ # 纯函数:聚合、派生、格式化(可单测) ``` - 沿用 `views/Stardust/overview.model.ts` 的做法:把 KPI 聚合、健康分段、事件派生、相对时间等抽成纯函数,用 Vitest 覆盖; - 组件内不直接拼接接口参数,统一走 `api/dashboard.ts`; - 颜色只用 `--el-*` / `--sd-*` 令牌,图表主题集中在一处导出。 ### 10.3 测试 - 单元测试:KPI 聚合(空数组、全离线、部分告警)、健康度计算、时间范围格式化; - 组件测试:KPI 阈值色、空态、权限徽标; - E2E(Playwright):4 个看板加载、受限态隐藏未授权项目、无授权空态、下钻跳转、大屏轮播与暂停。 --- ## 11. 分期建议 | 阶段 | 内容 | 依赖 | |------|------|------| | P0 | scope 接口 + 系统级看板 + 项目看板 | 服务端项目过滤(§7.2) | | P1 | 应用看板 + 节点看板 | 统计接口字段补齐(P95、错误样本) | | P2 | 大屏模式 + 视角轮播 | P0/P1 完成 | | P3 | 自定义看板(拖拽卡片、保存布局) | 视需求再评估,不提前设计 | --- ## 12. 文件清单 | 文件 | 说明 | |------|------| | `index.html` | 设计总览:画廊、原则、令牌、状态演示 | | `system.html` | L0 系统级看板 | | `project.html` | L1 项目看板 | | `app.html` | L2 应用看板 | | `node.html` | L2 单节点看板 | | `wallboard.html` | 16:9 大屏模式 | | `assets/tokens.css` | 与官方 tokens 同源的设计令牌(含浅色主题扩展) | | `assets/dashboard.css` | 骨架、卡片、KPI、表格、事件流、主题切换、大屏样式 | | `assets/theme.js` | 主题三态(跟随系统 / 浅色 / 深色)、持久化与切换控件 | | `assets/mock.js` | 统一假数据、三态切换、sparkline 工具 | | `assets/charts.js` | ECharts 暗色 / 浅色双调色板与图表构造器 | ## 13. 评审方式 直接用浏览器打开 `index.html` 即可;ECharts 走 CDN,离线时图表降级为提示,KPI 与布局不受影响。 - 主题:右上角(大屏在头部)三态切换;默认「跟随系统」,选择记忆在 `localStorage['sd-theme']` - 三态:`system.html?scope=limited`、`system.html?scope=none` - 空态:`project.html?state=empty` - 离线态:`node.html?state=offline` ## 14. 与旧稿的关系 `Doc/Design/*.html` 是早期 Bootstrap 浅色示意稿,用于快速表达页面结构;本目录以 StarWeb 真实设计系统(明暗双主题、玻璃卡片、星尘渐变)为准,后续实现、评审与视觉验收均以本目录为准。 --- ## 15. 明暗主题与「跟随系统」 ### 15.1 三态与默认值 | 模式 | 值 | 行为 | |------|----|------| | 跟随系统 | `auto`(默认) | 读取 `prefers-color-scheme`,系统切换时自动跟随 | | 浅色 | `light` | 锁定浅色 | | 深色 | `dark` | 锁定深色 | - 选择写入 `localStorage['sd-theme']`; - 落地在 `<html data-theme="light|dark" data-theme-mode="auto|light|dark">`; - 首屏在 `<head>` 内联脚本中先行应用,避免闪白/闪黑; - 切换控件为三枚图标(显示器 / 太阳 / 月亮),系统看板在顶栏右侧,大屏在标题右侧,总览页在右上角。 ### 15.2 浅色主题设计要点 - 页面底色改为冷灰蓝 `#F2F5FA`,卡片纯白 + 更浅的灰蓝阴影,去掉暗色辉光; - 星点背景降为淡紫蓝细点,保留「星尘」气质但不抢内容; - 语义色整体加深(在线 `#0B9A66`、告警 `#B45309`、离线 `#D92D20`),保证白底对比度; - 大屏保持同样的信息层次:数字不再发光,改为深色高对比数字 + 细边框卡片; - 顶栏、侧栏、表格、空态、状态药丸全部通过同名变量自动适配,页面无需写两套样式。 ### 15.3 StarWeb 实现建议 1. 现在 `src/main.ts` 强制 `document.documentElement.classList.add('dark')`,需移除并改为主题 store; 2. Element Plus 的暗色依赖 `html.dark`,建议同时维护 `data-theme`(业务令牌)与 `dark` class(Element),二者由同一状态驱动; 3. `auto` 模式监听 `window.matchMedia('(prefers-color-scheme: dark)')`,系统变化时只更新状态、不刷新页面; 4. ECharts 使用双调色板:监听主题变化后 `setOption` 重绘(不要像原型一样 reload);小屏/大屏图表共用同一套主题函数; 5. 大屏默认「跟随系统」,值守时可锁定深色;切换入口放在大屏头部,避免投屏时误触; 6. 测试补充:三模式切换、系统主题变化、`localStorage` 持久化、图表颜色随主题重绘、浅色下对比度(WCAG AA)。 ## 16. MVC StarWeb 落地记录(2026-10-31) 按「先能用手」的目标,看板优先在 MVC 控制台 `Stardust.Web`(StarWeb 程序集)落地,设计稿的视觉语言、卡片结构、图表语义保持不变;Vue 版后续按同一节迁移。 ### 16.1 路由 | 路由 | 页面 | 说明 | |------|------|------| | `/` | 系统级看板 | 站点根路径即看板;登录成功后默认落地此处 | | `/Dashboard` | 跳转 | 默认进系统级看板 | | `/Dashboard/System` | 系统级看板 | 与 `/` 同一页面,菜单与面包屑使用该地址 | | `/Dashboard/Project/{id?}` | 项目看板 | 无 `id` 时为项目选择页 `/Dashboard/Projects` | | `/Dashboard/App/{id?}` | 应用看板 | 无 `id` 时为应用选择页 `/Dashboard/Apps` | | `/Dashboard/Node/{id?}` | 节点看板 | 无 `id` 时为节点选择页 `/Dashboard/Nodes` | | `/Dashboard/Wallboard` | 大屏模式 | 16:9 全屏、四视角轮播 | | `/Dashboard/Data` | 数据接口 | 返回当前页 JSON,供 30 秒轮询与前端二次开发 | 后台入口:看板左侧栏底部「后台」图标跳转 `/Admin`。魔方管理后台首页保持原生工作台(`Cube.StartPage` = `/Admin/Index/Dashboard`),不嵌入看板;登录成功后通过 `LoginLandingMiddleware` 把魔方固定的 `/Admin` 跳转改写为 `/`(带返回地址时不改写)。 反向入口:后台左侧「平台管理 → 看板中心」打开 `/Dashboard`,看板页面在框架内检测到被后台嵌套时跳转到顶层,直接以整页呈现(`_Layout_Dashboard` 首屏脚本)。 看板控制器位于主程序集而非区域,Cube 菜单扫描不会自动生成;`Startup.EnsureDashboardMenu` 在 `UseCube` 之后补挂「平台管理 → 看板中心」,并最多等待 10 秒以避开启动竞态。 ### 16.2 数据来源 全部来自现有实体,未新建表;缺聚合口径时在对应 Biz 文件补分组查询(`AppMinuteStat.SearchGroupApp/SearchGroupTime`、`AppDayStat.SearchGroupApp/SearchGroupDate`、`TraceHourStat.SearchGroupName`、`AlarmRecord.SearchGroupCategory`): | 看板区块 | 数据来源 | |----------|----------| | 吞吐/错误/耗时 | `AppMinuteStat`(分钟聚合,跨应用分表合并) | | 项目健康矩阵、Top 应用 | `AppMinuteStat` + `App` + `AppDayStat` | | 实例/节点在线 | `AppOnline`、`NodeOnline`(`StardustData` 连接) | | 资源水位、磁盘、进程 | `NodeData` + `Node` | | 端点 Top、错误分布 | `TraceHourStat`(按名称/错误分组) | | 告警与事件 | `AlarmRecord` + `AlarmGroup`(按项目归属过滤)、`App`/`Node` 变更 | | 依赖拓扑 | `App` → `AppOnline` → `Node` 三级关系推导,无独立依赖表 | ### 16.3 设计调整(以真实数据为准) 原型中的部分指标在现有数据里没有对应字段,落地时按「有数据才画、没有就换口径」处理: | 原型 | 落地做法 | 原因 | |------|----------|------| | P95/P99 耗时 | 改为平均耗时 + 最大耗时 | `AppMinuteStat` 只有 Cost/Avg,无分位口径 | | 错误类型分布 | 改为错误端点分布(按接口名分组) | 无错误码/异常类型聚合表 | | 进程 Top | 改为「进程守护」列表(受管进程 + 状态) | 采集侧只上报受管进程 | | 磁盘「预计写满」 | 有历史容量时估算,无则不显示该列 | 多数环境只上报一次容量 | | 服务拓扑 | 改为「项目 → 应用 → 节点」部署拓扑 | 无 RPC 调用链数据 | | 机房维度 | 无机房字段时按项目分组 | `Node` 无机房字段 | | 节点健康雷达 | 用 CPU/内存/磁盘/网络/在线率合成 | 无独立评分源,按权重合成 | | 健康评分口径 | 使用率 50% 以内不扣分,超过后每百分点扣 2 分;温度 65℃ 起扣;稳定分从 60 起算 | 线性扣分会让正常节点(40%~60%)被判「较差」,失去参考意义 | | 趋势尾桶 | 剔除尚未走完的当前桶 | 当前桶只积累了几十秒数据,曲线末端会突然跌到 0,看起来像故障 | | 大屏迷你趋势 | 按 36 点分桶平均;节点在线率取近 24 小时每小时采样 | 原始分钟级曲线在迷你图上噪声过大 | | 应用「最近变更」 | 只保留发布与生命周期动作(上线/下线/注册/重启/超时等),同一动作只留最新一条 | `AppHistory` 混有 WebSocket、心跳、鉴权等运行日志,直接展示会刷屏 | | 错误分布 | 环形图下方补端点图例(次数 + 占比) | 原型只有图,落地后无图例无法读数 | ### 16.4 数据范围(严格隔离) - 系统角色(`Role.IsSystem`)可见全部项目与未归属数据; - 普通用户按 `ProjectUser` 授权行过滤,所有聚合 SQL 都带项目条件; - 无任何授权项目时整页空态(`Mode = none`),不泄露项目名与统计; - 项目/应用/节点选择页同样只列出授权范围内的对象。 ### 16.5 实现要点 - 服务端渲染 + `dashboard.js` 增强:主题三态(亮/暗/跟随系统)不刷新页面,切换后重绘 ECharts;30 秒轮询 `/Dashboard/Data` 局部刷新(401 自动回登录页); - 设计令牌与卡片样式直接复用本目录的 `tokens.css` / `dashboard.css`,避免第二套视觉; - 数据查询统一走 `DashboardService`,带 10 秒进程内缓存,避免轮询打爆数据库; - 覆盖测试:`Stardust.Tests/Dashboard/DashboardMathTests.cs`(口径与算法)+ `Stardust.E2ETests/Tests/DashboardPageTests.cs`(五个页面加载与数据接口)。 ### 16.6 卡片下钻与布局个性化(2026-10-31 增强) **下钻链接**:链接统一由 `DashboardLinks` 生成,避免视图硬编码。 - KPI 卡:整卡可点,落到对应列表/看板; - 图表卡:卡片头「查看明细/全部」,图表数据项支持点击下钻; - 表格卡:保留行点击,新增键盘可达(`data-href` + Enter/Space); - 事件流:告警 → 告警详情,应用/部署/节点事件 → 对应看板; - 大屏:卡片头「详情」、项目行、Top 应用、事件行均可点。 链接只携带实体过滤条件,不携带看板时间范围,避免分享链接时时间窗口漂移。 **布局个性化**:每张卡片有稳定 `data-card` 标识,顶栏「布局」打开右侧抽屉。 | 能力 | 说明 | |------|------| | 显隐 | 按卡片勾选,KPI 与内容卡均支持 | | 排序 | 上下移动或拖拽,只在同一网格内排序 | | 宽度 | 6/8/12/16/24 栏预设,仅 ≥1360px 生效,窄屏沿用原响应式规则 | | 高度 | 标准/加高,图表与可滚动表格生效 | | 保存 | `localStorage['sd-dashboard-layout:v1:<page>:<userId>']`,按页面 + 用户隔离 | | 恢复 | 抽屉内「恢复默认」清除当前页面配置并刷新 | 大屏不做卡片尺寸调整,提供「视角设置」:勾选参与轮播的视角、轮播间隔(12/30/60 秒),保存于 `localStorage['sd-wallboard-settings:v1']`。 ### 16.7 告警确认与静默(2026-10-31 增强) `AlarmRecord` 新增三个扩展字段: | 字段 | 说明 | |------|------| | `AckTime` | 确认时间 | | `AckUser` | 确认人 | | `SilenceTime` | 静默截止时间 | 行为约定: - **确认**:记录确认人与时间,不改变 Alarming/Recovered 状态,不单独停止通知; - **静默**:静默期内不再发送该报警记录的外部通知,可选 1 小时/24 小时/7 天;报警恢复通知仍发送; - 静默只作用于当前报警记录;恢复后再次触发会生成新记录,需重新静默; - 权限:登录 + `Monitors/AlarmRecord` 的 `PermissionFlags.Update` + 看板项目范围校验; - 接口:`POST /Dashboard/Alarm/Ack`、`POST /Dashboard/Alarm/Silence`,带防伪令牌; - 通知抑制点:`RobotHelper.SendAlarmWithRecord` 发送前检查 `AlarmRecord.CanNotify`,静默时只更新内容/持续时长,不增加通知次数; - 测试:`Stardust.ServerTests/Monitors/AlarmLifecycleTests.cs` 覆盖字段落库、通知判定与静默抑制;`DashboardPageTests.AlarmActions_AckAndSilence` 覆盖页面确认/静默与落库。