9.9 KiB
VDI Web 管理控制台 MVP 实施方案
版本:v0.1(功能先行,UI 稿待项目经理提供)
日期:2026-10-28
依据:VDI云桌面软件开发方案(1).docx第 2、4、5 节及VDI云桌面完整方案-云管端.docx管理平台模块表。
1. 先明确两个“登录”
本项目有两个不同的界面,必须分开:
| 界面 | 使用者 | 运行位置 | 职责 |
|---|---|---|---|
| 终端 kiosk-shell | 云桌面最终用户 | RK3528 盒子本地全屏 | 首配、设备绑定、用户登录、选择/进入被授权桌面、会话状态 |
| Web 管理控制台 console | 超级管理员、运维、只读人员 | PC 浏览器 | 终端、桌面池、用户绑定、GPU、监控、OTA、审计管理 |
正式文档中的 console/ 指第二项。它不应运行在盒子上,也不应直接发起 RDP/Moonlight;它通过平台 API 管理资源和下发策略。
“盒子开机直连 Moonlight”只能作为当前串流技术验证,不是最终产品登录流程。最终终端流程应恢复为:
盒子开机
-> kiosk-shell 全屏终端登录/首配页
-> vdt-agent 注册并获取终端身份
-> 用户登录或终端绑定校验
-> 平台返回该用户可用的桌面列表及短期连接信息
-> 用户选择桌面
-> kiosk-shell 按 protocol=rdp|moonlight 启动会话
-> 断开后回桌面列表/登录页
2. Web 控制台 MVP 目标
第一版目标不是做漂亮的大屏,而是跑通一个可演示、可替换 UI、可接真实后端的后台系统:
- 用户能登录和退出;
- 根据角色控制菜单和按钮;
- 管理员能查看终端、桌面、用户及绑定关系;
- 能对终端下发命令、对桌面执行开关机/重置;
- 能查看基础状态、操作结果和审计记录;
- 后端未完成时使用 Mock API,后端接口上线后不改页面业务逻辑即可切换。
3. 技术栈与工程结构
按定版文档执行:Vue 3 + Vite + TypeScript 严格模式 + Element Plus。
建议补充:Pinia(状态)、Vue Router、Axios、Vitest、Playwright、MSW(Mock API)。
console/
├─ src/
│ ├─ api/ # OpenAPI 生成 SDK 的薄封装
│ ├─ assets/
│ ├─ components/ # 领域无关组件
│ ├─ layouts/ # 登录布局、控制台布局
│ ├─ mocks/ # MSW handlers 与演示数据
│ ├─ router/ # 路由、鉴权守卫、RBAC meta
│ ├─ stores/ # auth、app、notification
│ ├─ types/ # 页面 ViewModel;API 类型由生成器管理
│ ├─ views/
│ │ ├─ login/
│ │ ├─ dashboard/
│ │ ├─ terminals/
│ │ ├─ desktops/
│ │ ├─ users/
│ │ ├─ gpu/
│ │ ├─ monitoring/
│ │ ├─ ota/
│ │ └─ audit/
│ ├─ App.vue
│ └─ main.ts
├─ e2e/
├─ public/
├─ .env.development
├─ .env.mock
├─ package.json
└─ vite.config.ts
约束:页面不能直接拼 URL 或写 Axios;所有网络调用只经过 api/。这样 Mock 与真实后端可无感切换。
4. 页面与优先级
M0:登录与应用框架
- 登录页:用户名、密码、登录按钮、错误状态、加载状态;
- 控制台壳:侧边导航、顶部栏、面包屑、当前账号、退出;
- 401 自动清理会话并回登录;
- 403 权限提示;
- 路由级 RBAC:
super_admin、operator、viewer; - 开发环境使用 Mock 登录,生产环境只调用真实 API。
M1:核心演示闭环
- 仪表盘:在线终端、活动会话、运行桌面、告警数量;
- 终端管理:列表、搜索、状态筛选、详情、重启、重置会话;
- 桌面管理:列表、状态筛选、开机、关机、重启、重置;
- 用户与绑定:用户列表、用户详情、终端/桌面绑定与解绑;
- 审计日志:操作者、动作、目标、结果、时间、请求 ID。
M1 完成后已经可以给项目经理演示完整业务流程。
M2:完整文档范围
- 桌面池:模板、容量、回收策略;
- GPU 池:节点/PCI 地址/型号/状态/绑定桌面;
- 监控:会话在线数、FPS、RTT、节点水位、告警;
- OTA 中心:版本、批次、灰度比例、进度、失败终端;
- CSV 用户/绑定批量导入向导;
- 配置模板与配置版本下发。
5. 登录与权限方案
登录接口
POST /api/v1/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "******"
}
建议响应:
{
"accessToken": "jwt",
"expiresIn": 3600,
"user": {
"id": "usr_001",
"username": "admin",
"displayName": "系统管理员",
"role": "super_admin"
}
}
建议第一版 access token 仅存内存;刷新 token 使用 HttpOnly + Secure + SameSite Cookie。若后端尚未支持 refresh,MVP 可暂存 sessionStorage,但不要长期使用 localStorage 保存高权限令牌。
权限矩阵
| 能力 | super_admin | operator | viewer |
|---|---|---|---|
| 查看所有页面 | 是 | 是 | 是 |
| 终端远程命令 | 是 | 是 | 否 |
| 桌面生命周期操作 | 是 | 是 | 否 |
| 用户/绑定修改 | 是 | 否 | 否 |
| GPU 绑定 | 是 | 否 | 否 |
| OTA 发布/灰度 | 是 | 是 | 否 |
| 只读监控/审计 | 是 | 是 | 是 |
前端 RBAC 只是交互约束,真正授权必须由 api-gateway 再验证,不能只隐藏按钮。
6. 第一版 API 契约
文档已明确的接口优先沿用:
POST /api/v1/auth/login
GET /api/v1/users
POST /api/v1/desktop/assign
POST /api/v1/pool/{id}/action
GET /api/v1/gpu/cards
POST /api/v1/gpu/bind
GET /api/v1/monitor/query
为控制台 MVP 补齐建议接口(需后端确认并写入 OpenAPI):
GET /api/v1/auth/me
POST /api/v1/auth/logout
GET /api/v1/terminals
GET /api/v1/terminals/{id}
POST /api/v1/terminals/{id}/commands
GET /api/v1/desktops
GET /api/v1/desktops/{id}
POST /api/v1/desktops/{id}/actions
GET /api/v1/bindings
DELETE /api/v1/bindings/{id}
GET /api/v1/audit-logs
所有列表统一查询参数:page、pageSize、keyword、status、sort;统一响应:
{
"items": [],
"page": 1,
"pageSize": 20,
"total": 0,
"requestId": "req_xxx"
}
所有命令型接口必须返回 commandId,页面展示“已提交”,再轮询或通过 WebSocket/MQTT 网关显示最终结果,不能把 HTTP 200 当作设备已经执行成功。
7. Mock 先行策略
后端还没完成时,前端不应硬编码页面数据。使用 MSW 模拟真实 HTTP:
- 固定 3 个测试账号,对应三角色;
- 终端包含在线/离线/会话中/升级中;
- 桌面包含运行/停止/错误/任务中;
- 所有命令先进入
pending,1–3 秒后变成success或failed; - 登录失败、401、403、网络超时、空列表都要有测试场景;
VITE_API_MODE=mock|real切换数据源。
项目经理 UI 稿到后,Mock 数据仍然可用于逐页视觉验收。
8. 与终端登录流程的接口边界
管理员 Web 控制台不直接把 VM 密码写进终端,也不让终端调用 Proxmox API。
建议终端用户登录流程由 auth-svc 单独提供:
POST /api/v1/terminal/session/login
GET /api/v1/terminal/session/desktops
POST /api/v1/terminal/session/connect-ticket
connect-ticket 返回短期、一次性连接信息:
{
"desktopId": "desk_001",
"protocol": "moonlight",
"endpoint": "192.168.1.70",
"app": "Desktop",
"display": { "width": 1920, "height": 1080, "fps": 60 },
"ticket": "short-lived-token",
"expiresAt": "2026-10-28T16:30:00+08:00"
}
这部分不是 console/ 页面,但必须和 Web 控制台的“用户/终端/桌面绑定”共享同一套后端数据。
9. UI 稿到来前的页面设计原则
第一版只做稳定工作台,不做营销式页面:
- 左侧导航 + 顶部工具栏 + 主内容区;
- 列表优先,详情使用独立页或抽屉;
- 状态使用图标/标签,不依赖单一颜色;
- 危险操作二次确认;
- 所有异步操作显示提交、执行中、成功、失败四态;
- 页面级空态、错误态、无权限态必须完整;
- 颜色、字号、间距集中为设计 token,避免 UI 稿到后逐页改 CSS;
- 表格列、筛选区、表单字段以配置驱动,减少视觉改版成本。
10. 验收标准
M1 应达到:
- 三种角色都能登录,菜单/按钮权限正确;
- 刷新页面仍能恢复会话,令牌过期自动回登录;
- 终端、桌面、用户/绑定、审计五条流程可演示;
- 命令有执行中与最终结果,不出现“点击无反馈”;
- API 全走统一 SDK/适配层,无页面直连 Axios;
- Vitest 覆盖 auth store、路由守卫、权限判断;
- Playwright 覆盖登录、终端命令、桌面操作、用户绑定四条主路径;
npm run lint、npm run typecheck、npm run test、npm run build全通过。
11. 推荐实施顺序
第 1 步:初始化 console 工程、路由、布局、设计 token
第 2 步:OpenAPI 初稿 + API SDK 生成 + MSW Mock
第 3 步:登录、会话恢复、RBAC、错误处理
第 4 步:终端管理 + 桌面管理
第 5 步:用户与绑定 + 审计日志
第 6 步:仪表盘聚合数据
第 7 步:Playwright E2E 与生产构建
第 8 步:项目经理 UI 稿到后替换视觉层
第 9 步:接真实 Go API,关闭 Mock
12. 当前决策建议
- 现在先开发
console/的 M0 + M1,不等 UI 稿; - 同时为
terminal/kiosk-shell恢复“登录/桌面列表后连接”的产品流程,不再把开机直连 Moonlight 当最终形态; - Web 控制台第一版只接 Mock,API 契约先和后端负责人确认;
- Moonlight/RDP 统一抽象成终端连接票据的
protocol字段,Web 控制台只管理策略,不直接操控串流客户端; - UI 稿到后只调整布局组件与 design tokens,业务路由、权限、API、测试保留。