Files
WonderQ-Project/docs/superpowers/specs/2026-08-26-admin-vue-formalization-design.md
T
duanshuwen efab6d1398 feat(admin): 新增全套运营管理功能,修复核心路由bug及后端seed问题
修复Vue Admin布局中RouterView未绑定唯一key的问题,解决RBAC系统资源页面切换后内容不刷新的ISSUE-001故障,新增routeViewKey工具函数区分路由实例
完善路由配置,新增admin空路径路由,修复路由命名空路径告警
新增媒体管理、运维发布/重置页面,补全全站路由注册与动态路由过滤逻辑
新增玩法、线索、管家、系统资源管理的全套工具函数、业务组件及单元测试用例
修复后端app/seed.py中媒体资源重复检测未考虑会话内pending资源的bug,新增对应测试验证修复逻辑
修正alembic迁移版本0015的依赖关系,删除废弃的旧迁移文件
优化后端系统接口的字典序列化逻辑,简化重复代码
添加QA验收报告与相关测试截图,完善项目测试覆盖
2026-08-26 18:48:48 +08:00

221 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WonderQ Admin Vue 正式化与三端联调设计规格
## 1. 文档状态
- 日期:2026-08-26
- 状态:待用户评审
- 适用范围:WonderQ-Admin、WonderQ-Admin-UI-Vue、WonderQ-Admin-UI、WonderQ-MiniAPP 的本阶段正式化工作
- 目标:在保留 React 过渡端的前提下,补齐 Vue 管理端未覆盖的首页 CRUD,完成管理员会话踢下线、显式 403、五级数据范围与正式反向代理验收。
本阶段不删除 React,不切换生产默认入口,不处理 OSS/媒体上传验收。媒体上传仍作为最后一项验收内容。
## 2. 当前基线与缺口
现有后端已经提供以下首页管理接口,但 Vue 管理端尚未接入:
| 功能组 | 接口前缀 | Vue 现状 | React 现状 |
| --- | --- | --- | --- |
| 体验内容 | `/api/admin/home/experiences` | 未接入 | 已有列表、创建、编辑、删除、排序 |
| 团建内容 | `/api/admin/home/team-buildings` | 未接入 | 已有列表、创建、编辑、删除、排序 |
| 野奢档案 | `/api/admin/home/wild-archives` | 未接入 | 已有列表、创建、编辑、删除、排序 |
| 玩法推荐 | `/api/admin/home/play-recommendations` | 未接入 | 已有列表、创建、编辑、删除、排序 |
现有 Vue 首页只覆盖站点配置模块,不能据此判断旧 React 业务已经全部迁移。
当前还存在以下验收缺口:
1. Redis 会话只支持当前会话退出,没有按用户撤销全部会话的管理能力。
2. Vue 路由权限失败会落到 Not Found,API 客户端也没有统一的 403 反馈路径。
3. 五级数据范围已有后端基础模型与角色编辑入口,但缺少覆盖五种范围的完整自动化矩阵和非超级管理员真实验收记录。
4. React 与 Vue 目前没有统一的生产反向代理入口;React 仍按根路径构建,不能直接挂载到 `/admin-legacy/`。
## 3. 目标架构
```text
浏览器
├─ /admin/ -> Vue3 静态资源,正式管理端
├─ /admin-legacy/ -> React 静态资源,过渡管理端
└─ /api/ -> FastAPI,保持现有 Public API 与 Admin API
FastAPI
├─ PostgreSQL:业务数据、RBAC、审计
└─ Redis:管理员会话、会话索引、权限菜单缓存、限流
```
Vue 继续使用预注册组件加载动态菜单,不允许由后端返回任意前端组件路径。React 保持原有 API 响应格式和登录字段兼容,直到正式删除闸门满足并得到用户确认。
## 4. 分阶段实施设计
### 阶段一:四组首页 CRUD 垂直切片
每个功能组都同时完成 API 客户端、Vue 页面、权限按钮、错误态与测试,不先做一个只读总览页。
#### 4.1 API 与数据契约
在 Vue API 层增加四组资源的类型和请求函数,沿用后端既有路径、字段、`{code,msg,data}` 包裹和排序语义:
- `GET /api/admin/home/experiences`
- `POST /api/admin/home/experiences`
- `PATCH /api/admin/home/experiences/{id}`
- `DELETE /api/admin/home/experiences/{id}`
- `POST /api/admin/home/experiences/reorder`
- `GET/POST/PATCH/DELETE/POST /reorder` 对应 `team-buildings`
- `GET/POST/PATCH/DELETE/POST /reorder` 对应 `wild-archives`
- `GET/POST/PATCH/DELETE/POST /reorder` 对应 `play-recommendations`
实际字段以现有后端 schema 和 `docs/home-api.md` 为准;如果发现契约缺失,先补文档,再同步 TypeScript 类型和后端测试,不擅自改动旧字段名。
#### 4.2 Vue 页面拆分
不继续把四组业务逻辑堆进 `HomePage.vue`。按资源拆出可维护的页面或业务组件,并复用列表、编辑表单、排序操作、确认弹窗和权限按钮组件。每组至少覆盖:
- 列表加载、空态、错误态、重试;
- 新建、编辑、删除及提交中禁用态;
- 排序保存与失败回滚提示;
- 图片/链接/状态等现有字段的校验和展示;
- `home:*` 权限码控制按钮显示与接口 403 反馈;
- 桌面端和窄屏布局。
验收以 React 页面和后端路由为基线逐项核对,不因 Vue 页面视觉重排而遗漏业务字段或操作。
### 阶段二:踢下线
#### 4.3 Redis 会话索引
在现有会话存储基础上增加按管理员用户索引的 Redis Set,索引只保存随机会话 ID,不保存明文 Refresh Token。创建、刷新轮换、主动退出、过期清理和批量撤销都必须维护索引;Redis 不可用时不得绕过会话校验。
会话存储协议增加:
- 按用户列出会话 ID;
- 按用户撤销全部会话;
- 清理已不存在或已撤销的索引项。
不新增数据库表,不把 Refresh Token 写入 PostgreSQL,不在日志中记录 Token 或其完整哈希。
#### 4.4 管理接口与 UI
新增:
`POST /api/admin/system/users/{user_id}/sessions/revoke`
要求:
- 权限码:`system:user:update`;
- 只能由具备该按钮权限且通过数据范围校验的管理员调用;
- 默认撤销目标用户的全部管理员会话;
- 禁止通过该接口撤销当前操作会话,避免误操作造成管理流程中断;
- 目标用户不存在、无数据范围权限或 Redis 不可用时返回明确错误,不返回内部异常;
- 写入审计日志,记录操作者、目标用户、撤销数量和结果,不记录 Token;
- Vue 用户管理页提供按钮、确认提示、提交中状态和成功/失败反馈;
- 被踢出的浏览器在下一次 API 请求或刷新时收到 401,并回到登录页。
### 阶段三:显式 403
新增 Vue `ForbiddenPage.vue` 和 `/forbidden` 路由。路由守卫在用户已登录但无菜单/页面权限时进入 403 页面;未登录仍进入登录页,未知路径继续进入 Not Found。
API 客户端对 403 不刷新 Token、不清除有效登录态,统一转换为可识别的权限错误。页面层显示“无权限”与返回上一页/首页操作;按钮级权限仍由现有权限指令控制,但后端 403 始终视为最终边界。
至少验证:
- 无页面权限访问页面 URL;
- 有页面权限但无按钮权限;
- 直接调用被禁止的 Admin API;
- 401 与 403 不混淆;
- 刷新后权限缓存和动态路由行为一致。
### 阶段四:五级数据范围
保留现有范围编码和角色编辑能力,补充自动化测试和真实验收,不另造一套权限模型。五种范围必须分别验证:
1. 全部:可见全部归属资源;
2. 当前部门:只见当前部门资源;
3. 当前部门及子部门:可见当前部门和后代部门资源;
4. 自定义部门:只见角色明确配置的部门资源;
5. 本人:只见创建人/负责人为自己的资源。
测试使用至少两个部门、一个子部门、两个管理员和跨部门资源,覆盖列表、详情、更新、删除/状态写入等接口。每个切片都检查数据范围过滤在服务端生效,不能只依赖前端隐藏行。
权限或部门变更后必须使权限菜单缓存和相关数据范围缓存失效。Redis 不可用时拒绝需要会话或权限缓存的请求,不降级为全量数据。
### 阶段五:Docker 与正式反向代理
新增部署级 Nginx 配置和 Vue 静态镜像入口,统一提供:
- `/admin/`:Vue 正式管理端,使用 Vue 的 `/admin/` base;
- `/admin-legacy/`:React 过渡端,React 构建必须使用 `/admin-legacy/` base;
- `/api/`:反向代理到 FastAPI;
- 两个前端入口都支持 SPA history fallback,但不能把 `/api/` 错误回退到 `index.html`。
React 通过构建环境或独立 legacy 构建配置注入 base,不改变现有开发端口和 API 合同。正式代理切换采用可回滚配置:先同时发布两个入口,再切换默认链接到 `/admin/`;切换期间 `/admin-legacy/` 保持可访问。
Docker 验收包括前端镜像构建、PostgreSQL/Redis/API 启动、Alembic 升级、健康检查、两个管理入口、API 代理和刷新深链路。生产环境变量、密钥和现有部署配置不写入仓库或文档示例。
## 5. 文档同步
实现前或接口确认时同步以下契约文档:
- `docs/home-api.md`:四组首页 CRUD 的 Vue 对接字段、排序和错误语义;
- `docs/admin-api-requirements.md`:踢下线、403、数据范围和响应契约;
- `docs/integration-workflow.md`:三端启动、正式代理和验收顺序;
- `docs/admin-business-function-matrix.md`:每个垂直切片的迁移、测试和人工验收记录。
不修改 `docs/public-api.md`,除非实际发现 Public API 字段发生兼容性变化。MiniAPP 本阶段只做契约回归检查,不整体重写。
## 6. 测试与验收闸门
采用测试先行和垂直切片交付。每一片先增加会失败的测试,再写实现,最后运行与影响范围匹配的验证。
### 后端
- 四组 CRUD 的鉴权、参数校验、响应格式、排序和审计测试;
- 会话创建、刷新轮换、退出、按用户踢下线、重复撤销、Redis 不可用测试;
- 401/403 区分测试;
- 五级数据范围的跨部门/子部门/本人矩阵测试;
- 旧 React 登录字段、Public API、既有 Admin API 兼容测试;
- Alembic 空库初始化、现有数据库升级与 Docker 健康检查。
### Vue 与 React
- Vue TypeScript 检查、单元测试和生产构建;
- 四组首页 CRUD 的列表、表单、删除、排序、错误态和按钮权限;
- Vue 刷新、退出、踢下线、403、动态菜单;
- React 原有构建和登录刷新回归;
- 正式代理下 `/admin/`、`/admin-legacy/`、深链刷新和 `/api/` 转发。
### 人工验收顺序
1. 四组首页 CRUD;
2. 踢下线与 403;
3. 五级数据范围;
4. Docker/Redis/正式反向代理;
5. Public API 与 MiniAPP 回归;
6. 最后单独验收 OSS/媒体上传。
每个阶段完成后记录实际命令、结果、失败项和人工操作证据。任何一项未通过都不能把 Vue 标记为正式替代端。
## 7. 回滚与删除闸门
- 四组业务切片异常时,可保持 React 入口继续承载原页面,Vue 只回滚对应菜单/路由,不回滚数据库既有业务数据。
- 反向代理异常时保留 `/admin-legacy/`,恢复默认入口到 legacy 配置即可回退。
- 会话索引异常时拒绝管理请求并修复 Redis 索引,不允许切换到绕过会话校验的降级模式。
- 本阶段不删除 React 源码、依赖、构建入口或 legacy 代理。
只有同时满足以下条件,并由用户明确确认,才启动 React 删除阶段:
1. Vue 覆盖功能矩阵全部业务能力;
2. Public API 和现有 Admin API 无回归;
3. 角色、菜单、按钮权限、五级数据范围测试通过;
4. 登录刷新、退出、踢下线、Redis 异常通过;
5. Docker 和正式反向代理通过;
6. OSS/媒体上传通过;
7. 用户完成人工验收并明确确认删除旧 React。
## 8. 非目标
- 不整体重写 MiniAPP;
- 不引入 RuoYi 的代码生成、定时任务、监控、表单设计器等非核心模块;
- 不直接删除或重置业务数据;
- 不恢复 Alembic 已清理的无用 schema;
- 不把媒体上传提前到本阶段的首页 CRUD 验收之前;
- 不在本规格确认前改动生产环境变量、密钥和部署数据。