# 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` 才能进入页面。 ## 内部结构 ```text 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[]` | ## 迁移/实现注意事项 1. 后端必须先过滤当前用户的有效菜单,再组装树,不能把全量菜单发给前端后让前端过滤。 2. 超级管理员可以获得全部 admin 菜单,但仍应通过同一树形 DTO 返回。 3. 页面权限只控制菜单可见性和路由进入;具体 API 继续由 Java 后端鉴权。 4. 不新增按钮级 `actions` 字段,不新增 action 权限表。 5. 不保留 `X-Admin-Menu-Format` 双格式,不根据 User-Agent、查询参数或调用方返回不同菜单结构。 6. `column_key` 继续作为稳定权限 key,Flyway 只迁移 `route_path`,避免现有 Java 业务权限常量失效。 7. 菜单树为空时必须区分“权限为空”和“接口失败”,不能把接口失败误显示为无权限。