3.4 KiB
3.4 KiB
02 登录态、菜单树与菜单级权限
模块职责
负责后台 Vue 启动时的当前用户加载、菜单树加载、Cookie/Session 复用、路由级菜单权限判断、退出登录和未登录处理。本模块只处理菜单/页面级权限,不处理按钮级权限。
依赖关系
上游:Java AdminAuthSupport、AdminConsoleController.currentUser、AdminConsoleController.currentUserMenus、PermissionMenuService.getUserColumnPermissions。
下游:AdminLayout、Vue Router 守卫、所有页面权限元数据。
数据表:columns、user_column_permission、users。
核心接口:原实现 → 目标实现
| 接口/符号 | 原实现 | 目标实现 |
|---|---|---|
| 当前用户 | Flask get_admin_current_user 或 Java AdminConsoleController.currentUser |
Java GET /api/admin/current-user,维持 {item} 语义 |
| 菜单 | Flask get_admin_current_user_menus 返回扁平项;Java同样返回扁平项 |
Java GET /api/admin/current-user/menus 返回树形 items |
| 登出 | admin.js 直接 fetch /api/admin/logout |
api/session.ts:logout,由 Pinia action 调用 |
| 权限展开 | Flask _effective_permission_sets 或 Java PermissionMenuService |
统一由 Java PermissionMenuService 完成 |
| 前端权限 | hasAdminTabAccess、applyTabAccess |
Router guard 比较 route.meta.menuKey 和菜单树 key |
目标菜单契约
菜单节点:
key:稳定的columns.column_key。name:展示名称。route:相对于/admin-vue/的页面路径,例如account/users。children:分组节点和页面节点的层级。sort:后端排序字段;前端按后端顺序展示,不二次重排。
分组节点可以没有 route;页面节点必须有 route 才能进入页面。
内部结构
admin-session store
├── user
├── menuTree
├── initialized
├── loading
└── error
初始化顺序
1. GET /api/admin/current-user
2. GET /api/admin/current-user/menus
3. 保存用户和菜单树
4. Router guard 校验目标页面
5. 无目标路径时进入第一个可见页面
Cookie 规则:
- 请求使用同源 Cookie/Session。
- 前端不保存密码、JWT 或长期敏感凭证。
- Axios
withCredentials必须开启。 - 401 统一跳转
/login,并携带当前目标路径作为 redirect 信息;是否实际接受 redirect 参数由登录模块决定。
类型映射
| 原字段 | 目标字段 |
|---|---|
route_path |
route |
column_key |
key |
parent_id |
children 关系 |
adminCurrentUsername |
AdminUser.username |
currentUserRole |
AdminUser.role |
adminTabs |
AdminMenuNode[] |
迁移/实现注意事项
- 后端必须先过滤当前用户的有效菜单,再组装树,不能把全量菜单发给前端后让前端过滤。
- 超级管理员可以获得全部 admin 菜单,但仍应通过同一树形 DTO 返回。
- 页面权限只控制菜单可见性和路由进入;具体 API 继续由 Java 后端鉴权。
- 不新增按钮级
actions字段,不新增 action 权限表。 - 不保留
X-Admin-Menu-Format双格式,不根据 User-Agent、查询参数或调用方返回不同菜单结构。 column_key继续作为稳定权限 key,Flyway 只迁移route_path,避免现有 Java 业务权限常量失效。- 菜单树为空时必须区分“权限为空”和“接口失败”,不能把接口失败误显示为无权限。