Files

222 lines
12 KiB
Markdown
Raw Permalink 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.
# 00 总览:后台管理系统 Vue 化与 Flask 移除
## 1. 文档目的
本目录是后台管理系统 Vue 化、Java 收敛和 Flask 管理能力移除的唯一设计输入,供后续 step-2 按功能点拆分任务。
本次范围不是客户端前端重构。客户端工程 `frontend-vue/` 及其 `new_web_source/` 不属于本项目的后台前端产物。
## 2. 已确认决策
| 主题 | 决策 |
|---|---|
| 前端工程 | 独立 `admin-frontend-vue/` |
| UI | Vue 3 + TypeScript + Element Plus |
| 状态 | Pinia 只保存用户、菜单和全局应用状态;页面数据局部管理 |
| 路由 | Vue Router History;生产基准路径 `/admin-vue/` |
| 菜单 | Java 后端返回树形菜单;前端不写死菜单分组 |
| 权限粒度 | 仅菜单/页面级;不做按钮级权限 |
| 权限存储 | 继续复用 `columns``user_column_permission` |
| 权限 key 与 URL | 分离;`column_key` 是稳定权限标识,`route_path` 是 Vue 页面路径 |
| API | 保持 `/api/admin/*`;不新建 v2 API |
| 认证 | 复用现有同源 Cookie/Session;不引入 JWT |
| 后端 | Java 成为后台管理唯一后端;Flask 管理能力完全移除 |
| 版本接口 | Java 提供 `/api/version``/api/version/latest`,路径和字段不变 |
| 静态资源 | Nginx 独立目录托管,不打进 Java JAR |
| 入口 | `/admin` 重定向 `/admin-vue/` |
| 旧链接 | 不兼容旧 `#tab=xxx` 和旧后台路径 |
| 菜单迁移 | 通过 Flyway 正式迁移 |
| 首批 | 后台壳层、用户、菜单、数据权限分组 |
| 视觉 | 深色侧边栏 + 浅色内容区 |
## 3. 当前实现基线
### 3.1 旧后台前端
- 页面:`backend/web_source/admin.html`,包含 17 个面板、26 个弹窗和全部页面样式。
- 业务脚本:`backend/static/admin.js`,将请求、状态、DOM 渲染、权限和轮询集中在单个 IIFE。
- 横切交互:`backend/static/admin-interactions.js`,负责 loading、toast、confirm、键盘和按钮增强。
- Java 静态副本:`backend-java/src/main/resources/static/admin.html``static/admin.js`
### 3.2 现有后台 API
- Flask 管理蓝图:`backend/blueprints/admin_api.py`
- Java 管理控制器:`backend-java/src/main/java/com/nanri/aiimage/modules/admin/controller/AdminUserController.java``AdminConsoleController.java`
- Java 权限控制器:`backend-java/src/main/java/com/nanri/aiimage/modules/permission/controller/PermissionMenuController.java`
- 版本管理:`backend-java/src/main/java/com/nanri/aiimage/modules/softwareversion/controller/SoftwareVersionAdminController.java`
### 3.3 已有权限数据模型
- `columns`:菜单、分组和页面节点。
- `user_column_permission`:用户到菜单节点的直接授权。
- `PermissionMenuService`:负责有效权限展开、父子菜单和授权边界。
## 4. 目标架构
```text
Browser
├── /admin
│ └── 302 → /admin-vue/
└── /admin-vue/*
Nginx/OpenResty
├── /admin-vue/assets/* → 独立静态资源
├── /admin-vue/<route> → History fallback 到 index.html
└── /api/* → Java
├── Session/Auth
├── Admin APIs
├── Menu Tree API
├── Version Admin API
└── Public Version API
```
```text
admin-frontend-vue/
├── src/layout/ # AdminLayout、侧边栏、顶栏
├── src/router/ # History 路由和菜单守卫
├── src/stores/ # Pinia 用户/菜单状态
├── src/api/ # 后台 API 适配
├── src/pages/account/ # 首批账号权限模块
├── src/pages/asin/ # ASIN 数据中心
├── src/pages/shop/ # 店铺中心
├── src/pages/tasks/ # 任务和重复分析
├── src/pages/records/ # 历史、版本
└── dist/ # Nginx 发布目录
```
## 5. 精确依赖图:现状符号到目标符号
| 当前文件与符号 | 当前依赖 | 目标替代/消费者 |
|---|---|---|
| `backend/blueprints/main.py:admin_page` | `blueprints.admin_api._load_current_backend_menu_items``utils.render.render_html``web_source/admin.html` | 删除 Flask 页面职责;`AdminConsoleController.adminPage` 重定向 `/admin-vue/` |
| `backend/blueprints/main.py:serve_static` | `backend/static/*` | 删除后台静态托管职责;Nginx 托管 `admin-frontend-vue/dist` |
| `backend/blueprints/admin_api.py:get_admin_current_user` | Flask Session、当前用户查询 | `AdminConsoleController.currentUser` |
| `backend/blueprints/admin_api.py:get_admin_current_user_menus` | `_load_current_backend_menu_items`、Java 权限代理 | `AdminConsoleController.currentUserMenus` + `PermissionMenuService.getUserColumnPermissions` + 树构造器 |
| `backend/blueprints/admin_api.py:list_users` | Flask DB/Java 代理、`_ensure_backend_menu_access` | `AdminUserController.listUsers` + `AdminUserService.listUsers` |
| `backend/blueprints/admin_api.py:create_user/update_user/delete_user` | Flask 管理用户逻辑 | `AdminUserController.createUser/updateUser/deleteUser` |
| `backend/blueprints/admin_api.py` 的菜单 CRUD 路由 | Flask 权限代理 | `PermissionMenuController.listMenus/createMenu/updateMenu/deleteMenu/reorderColumns` |
| `backend/blueprints/version.py:api_version` | `APP_VERSION``APP_UPDATE_URL` | `PublicVersionController.currentVersion` |
| `backend/blueprints/version.py:api_version_latest` | `utils.db.get_db``web_config` | `PublicVersionController.latestVersion` + `SoftwareVersionService.latestSoftwareVersion` |
| `backend/web_source/admin.html``panel-users` | `admin.js:loadUsers`、DOM ID 约定 | `pages/account/UsersPage.vue` |
| `backend/web_source/admin.html``panel-columns` | `admin.js:loadColumns`、拖拽排序 | `pages/account/MenusPage.vue` + 菜单 API |
| `backend/web_source/admin.html``panel-group-manage` | `admin.js:loadShopManageGroups`、分组弹窗 | `pages/account/GroupsPage.vue` |
| `backend/static/admin.js:loadAdminCurrentUser` | `/api/admin/current-user` | `api/session.ts:fetchCurrentUser` + `stores/admin-session.ts:initialize` |
| `backend/static/admin.js:loadAdminMenus` | `/api/admin/current-user/menus``renderAdminTabs` | `api/session.ts:fetchAdminMenuTree` + `AdminLayout.vue` |
| `backend/static/admin.js:activateAdminTab` | `hideAllAdminPanels``runTabLoader` | `router/index.ts` + 路由级异步页面组件 |
| `backend/static/admin-interactions.js:showToast` | `adminToastRegion` | Element Plus `ElMessage` |
| `backend/static/admin-interactions.js:openConfirm` | `adminConfirmModal` | Element Plus `ElMessageBox` |
| `backend-java/.../AdminConsoleController.currentUser` | `AdminAuthSupport.requireAdminOrInternal` | 保留,作为 Vue Session 初始化接口 |
| `backend-java/.../AdminConsoleController.currentUserMenus` | `PermissionMenuService.getUserColumnPermissions` | 保留调用,增加树形组装;输出 `key/name/route/children` |
| `backend-java/.../PermissionMenuService.getUserColumnPermissions` | `columns``user_column_permission`、父子展开 | 保留为菜单权限唯一来源 |
| `backend-java/.../AdminUserController.listUsers` | `AdminUserService.listUsers` | Vue `UsersPage` API 适配层 |
| `backend-java/.../PermissionMenuController.listMenus` | `PermissionMenuService.list` | Vue `MenusPage` API 适配层 |
| `backend-java/.../SoftwareVersionAdminController` | `SoftwareVersionService``web_config` | Vue Records/Version 页面 |
| `frontend-vue/*` | 客户端 Vite 多页面工程 | 不依赖、不修改、不作为后台工程入口 |
## 6. 目标菜单数据契约
接口:`GET /api/admin/current-user/menus`
目标响应的 `items` 是树形数组。页面节点至少包含:
| 字段 | 来源 | 语义 |
|---|---|---|
| `key` | `columns.column_key` | 稳定菜单权限标识 |
| `name` | `columns.name` | 展示名称 |
| `route` | `columns.route_path` | Vue Router 页面路径,不包含 `/admin-vue` 基准前缀 |
| `children` | `columns.parent_id` | 子菜单;叶子页面可省略或为空数组 |
| `sort` | `columns.sort_order` | 仅用于后端排序,是否输出由最终 DTO 决定 |
不输出按钮级 `actions`,不新增操作权限表。
## 7. 实现顺序
1. 固化 Java 版本接口契约和菜单树 DTO。
2. 完成 Flyway 后台 route_path 迁移。
3. 完成后台前端壳层、Session、菜单守卫。
4. 完成账号与权限首批页面。
5. 完成版本/历史和低风险数据页面。
6. 完成 ASIN、店铺、任务、重复检查页面。
7. 做 Java API 对照、权限回归、客户端版本更新回归。
8. Nginx 发布 `/admin-vue/`,将 `/admin` 重定向到 Vue。
9. 删除 Flask 管理蓝图、旧 admin 模板和旧管理脚本。
10. 删除旧菜单响应、旧静态资源和迁移期间兼容代码。
## 8. 迁移边界
本次必须保留:
- `/api/version`
- `/api/version/latest`
- `/api/admin/*` 的业务 API 路径和业务响应语义。
- Cookie/Session 登录态。
- `columns``user_column_permission` 的数据库模型。
本次最终删除:
- Flask 管理页面路由。
- Flask 管理 API 蓝图。
- Flask 管理后台静态资源。
-`admin.html``admin.js``admin-interactions.js`
- 客户端请求不到的 Flask 版本蓝图(版本能力已迁移 Java)。
## 10. 模块职责
本总览模块负责定义后台前端、Java API、权限存储、公开版本接口、静态部署和 Flask 删除之间的边界;不直接实现业务页面。
## 11. 依赖关系
所有模块依赖 `00-overview.md` 的技术选型和发布边界;页面模块依赖壳层与 Session 菜单模块;Java 菜单、版本和部署模块是最终切换的后端前置条件。
## 12. 核心接口
核心外部接口包括 `/admin``/admin-vue/``/api/admin/current-user``/api/admin/current-user/menus``/api/version``/api/version/latest`;各接口的原实现到目标实现映射见第 5 节和对应独立 spec。
## 13. 内部结构
总体系由独立后台前端、Java 管理 API、权限数据库、公开版本服务和 Nginx 发布层组成,结构图见第 4 节。
## 14. 类型映射
总体系的关键类型映射为:`column_key → menu key``route_path → Vue route``PermissionMenuItemVo[] → AdminMenuNode[]``web_config version/file_url → PublicVersionResponse`
## 15. 迁移/实现注意事项
本总览约束所有子 spec 不得引入客户端前端依赖、按钮级权限、JWT、旧 hash 兼容或 Flask 管理长期兼容分支;未在本总览批准的跨模块变更必须先更新决策和对应 spec。
## 9. 主要风险与验收标准
### P0:客户端更新接口中断
证据:Flask `version.py` 当前提供 `/api/version/latest`,客户端已有固定调用。
验收:Java 接口在 Flask 停止后仍返回同路径、同字段、同空数据语义;至少完成真实 HTTP 回归。
### P0:菜单权限树错误导致后台不可用或越权展示
证据:当前权限展开依赖 `PermissionMenuService``user_column_permission`
验收:超级管理员、管理员、普通账号、无菜单权限账号分别验证菜单树和路由守卫;页面 API 仍由后端鉴权。
### P1History 刷新 404
证据:Vue Router 使用 History,生产由 Nginx fallback。
验收:直接访问并刷新 `/admin-vue/account/users``/admin-vue/account/menus`;不存在的静态资源必须返回 404 而不是 HTML。
### P1:路由迁移破坏权限关系
证据:现有后端大量使用旧 `column_key`,而新版 URL 需要重组。
验收:Flyway 只改变 `route_path`,旧 `column_key` 授权关系保持可解析;菜单 key 与 route 独立测试。
### P2:前端首屏包过大
证据:Element Plus 和后台所有模块会产生较大 bundle。
验收:页面组件按路由异步加载;首批页面不得把所有业务模块静态导入首屏。