# 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”只能作为当前串流技术验证,不是最终产品登录流程。最终终端流程应恢复为: ```text 盒子开机 -> kiosk-shell 全屏终端登录/首配页 -> vdt-agent 注册并获取终端身份 -> 用户登录或终端绑定校验 -> 平台返回该用户可用的桌面列表及短期连接信息 -> 用户选择桌面 -> kiosk-shell 按 protocol=rdp|moonlight 启动会话 -> 断开后回桌面列表/登录页 ``` ## 2. Web 控制台 MVP 目标 第一版目标不是做漂亮的大屏,而是跑通一个可演示、可替换 UI、可接真实后端的后台系统: 1. 用户能登录和退出; 2. 根据角色控制菜单和按钮; 3. 管理员能查看终端、桌面、用户及绑定关系; 4. 能对终端下发命令、对桌面执行开关机/重置; 5. 能查看基础状态、操作结果和审计记录; 6. 后端未完成时使用 Mock API,后端接口上线后不改页面业务逻辑即可切换。 ## 3. 技术栈与工程结构 按定版文档执行:Vue 3 + Vite + TypeScript 严格模式 + Element Plus。 建议补充:Pinia(状态)、Vue Router、Axios、Vitest、Playwright、MSW(Mock API)。 ```text 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:核心演示闭环 1. 仪表盘:在线终端、活动会话、运行桌面、告警数量; 2. 终端管理:列表、搜索、状态筛选、详情、重启、重置会话; 3. 桌面管理:列表、状态筛选、开机、关机、重启、重置; 4. 用户与绑定:用户列表、用户详情、终端/桌面绑定与解绑; 5. 审计日志:操作者、动作、目标、结果、时间、请求 ID。 M1 完成后已经可以给项目经理演示完整业务流程。 ### M2:完整文档范围 - 桌面池:模板、容量、回收策略; - GPU 池:节点/PCI 地址/型号/状态/绑定桌面; - 监控:会话在线数、FPS、RTT、节点水位、告警; - OTA 中心:版本、批次、灰度比例、进度、失败终端; - CSV 用户/绑定批量导入向导; - 配置模板与配置版本下发。 ## 5. 登录与权限方案 ### 登录接口 ```http POST /api/v1/auth/login Content-Type: application/json { "username": "admin", "password": "******" } ``` 建议响应: ```json { "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 契约 文档已明确的接口优先沿用: ```text 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): ```text 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`;统一响应: ```json { "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` 单独提供: ```text POST /api/v1/terminal/session/login GET /api/v1/terminal/session/desktops POST /api/v1/terminal/session/connect-ticket ``` `connect-ticket` 返回短期、一次性连接信息: ```json { "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 应达到: 1. 三种角色都能登录,菜单/按钮权限正确; 2. 刷新页面仍能恢复会话,令牌过期自动回登录; 3. 终端、桌面、用户/绑定、审计五条流程可演示; 4. 命令有执行中与最终结果,不出现“点击无反馈”; 5. API 全走统一 SDK/适配层,无页面直连 Axios; 6. Vitest 覆盖 auth store、路由守卫、权限判断; 7. Playwright 覆盖登录、终端命令、桌面操作、用户绑定四条主路径; 8. `npm run lint`、`npm run typecheck`、`npm run test`、`npm run build` 全通过。 ## 11. 推荐实施顺序 ```text 第 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、测试保留。