完善平台角色菜单树与授权登录导航
This commit is contained in:
@@ -76,6 +76,8 @@
|
||||
- 登录成功返回 JWT、账户 `identity`、显示名称和角色编码。
|
||||
- `Authorization` 请求头当前直接传 JWT 原始值,不使用 `Bearer` 前缀。
|
||||
- 已登录账户可查看个人资料、角色和菜单编码。
|
||||
- 登录后优先恢复当前角色有权访问的历史叶子页;历史地址无权或不存在时,按服务端菜单顺序进入首个可访问叶子页,不将父级分组或隐藏详情页作为默认落点。
|
||||
- 已认证账户未分配任何业务菜单时,展示“尚未分配菜单权限”引导页并提供重新加载权限和退出登录,不回退为 404。
|
||||
- 修改密码必须校验当前密码,新密码不少于 6 位。
|
||||
- 系统启动时幂等创建 `root` 管理账户;root 初始密码优先读取环境变量 `HEQI_PLATFORM_ROOT_PASSWORD`。
|
||||
|
||||
@@ -83,6 +85,10 @@
|
||||
|
||||
- `root` 角色拥有全部平台菜单能力。
|
||||
- 非 root 账户必须关联处于启用状态的平台角色,并按角色菜单逐请求鉴权。
|
||||
- 已认证平台账户可读取当前角色自己的授权菜单树;该基础能力不等同于平台菜单配置权限,不得借此读取菜单详情或执行菜单写操作。
|
||||
- 角色菜单使用父子树分配:父菜单仅承担导航分组和全选、全清,部分子菜单选中时显示半选;服务端只持久化有效叶子菜单,允许清空角色全部菜单权限。
|
||||
- 菜单搜索和已选内容使用“父菜单 / 子菜单”完整路径,避免同名业务菜单产生歧义。
|
||||
- 角色权限调整后,服务端从下一次请求开始按新权限鉴权;已登录账户可通过重新加载权限或重新登录刷新前端导航。
|
||||
- 创建工作人员、安装人员、配送人员和运维人员是相互独立的菜单能力。
|
||||
- 工作人员资质权限跟随所属人员角色,不能凭任一人员菜单访问其他类型人员资质。
|
||||
- 创建配送订单使用独立的 `gasorder_create` 权限,不因拥有订单列表权限自动获得。
|
||||
|
||||
41
docs/操作日志_平台角色菜单树与授权导航修复_20260817.md
Normal file
41
docs/操作日志_平台角色菜单树与授权导航修复_20260817.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# 操作日志:平台角色菜单树与授权导航修复
|
||||
|
||||
操作时间:2026-08-17
|
||||
操作类型:修改
|
||||
影响模块:平台总后台角色菜单、平台账号登录导航、服务端菜单鉴权
|
||||
|
||||
## 操作前状态
|
||||
|
||||
- 角色菜单使用扁平多选框,父菜单与叶子菜单看似可以独立选择。
|
||||
- 服务端实际只保存叶子菜单,导致父菜单勾选不落库、子菜单选中时父菜单不显示半选。
|
||||
- 普通账号取得个人菜单编码后仍需读取 `/platform_menu`,但该请求又要求“平台菜单”业务权限,形成权限死循环并错误进入无权限页。
|
||||
|
||||
## 具体操作
|
||||
|
||||
- 新增专用角色菜单树,父菜单支持全选、全清和半选展示,子菜单显示完整路径。
|
||||
- 表单只提交叶子菜单;允许清空全部权限,并在提交前二次警告。
|
||||
- 放行已认证平台账号读取当前角色自己的菜单列表,响应继续按角色过滤;菜单详情和写操作不放宽。
|
||||
- 服务端忽略具有子菜单的导航父节点,同时保留无子菜单顶级页面作为有效业务权限。
|
||||
- 补充后端访问规则测试和前端静态契约检查。
|
||||
|
||||
## 行为变化
|
||||
|
||||
- 修改前:父子菜单状态不一致,普通业务角色可能已分配权限但无法加载导航。
|
||||
- 修改后:父菜单只表达叶子权限的聚合状态;普通账号可加载自己的授权导航,未授权兄弟菜单仍不可见、不可访问。
|
||||
|
||||
## 风险评估
|
||||
|
||||
- 不修改数据库结构和公共写接口,历史叶子数据继续兼容。
|
||||
- `GET /platform_menu` 仅放宽为“读取自身授权导航”,服务端仍根据 JWT 角色过滤,不开放详情和写权限。
|
||||
- 清空权限会使该角色账号无法进入业务页,前端已增加明确确认提示。
|
||||
|
||||
## 验证结果
|
||||
|
||||
- 后端 `go test ./internal/logic/platform/platform ./internal/logic/platform ./internal/routers`:通过。
|
||||
- 前端 `pnpm run menu-permission-tree:check`:通过。
|
||||
- 前端 `pnpm run auth-landing:check`:通过。
|
||||
- 前端 `pnpm run type:check`:通过。
|
||||
- 前端 `pnpm run build`:通过。
|
||||
- Codex 浏览器人工验证:父级半选、全选、全清、完整路径搜索和清空权限二次确认均通过;测试过程已取消弹窗,未写入角色权限。
|
||||
- 浏览器复验修正了菜单数据返回前数组未初始化的瞬时 Vue 警告;修正后无新增控制台警告。
|
||||
- 当前平台账户列表没有普通角色账号,因此未创建临时数据,也未执行普通账号真实登录;该链路由后端授权测试和前端登录落点检查覆盖。
|
||||
51
docs/操作日志_平台账户登录后误入404修复_20260817.md
Normal file
51
docs/操作日志_平台账户登录后误入404修复_20260817.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 平台账户登录后误入 404 修复操作日志
|
||||
|
||||
操作时间:2026-08-17
|
||||
操作类型:修改、扩展
|
||||
影响模块:平台总后台 / 认证 / 角色菜单 / 前端路由
|
||||
|
||||
## 操作前状态
|
||||
|
||||
- 所有账号登录成功后均固定进入 `dashboard-overview`。
|
||||
- 非 root 角色未分配数据概览时,路由守卫正确拒绝访问,但页面错误显示英文 404。
|
||||
- 完全没有菜单的账号没有可恢复引导。
|
||||
|
||||
## 具体操作
|
||||
|
||||
1. 登录成功后先加载个人资料与当前角色菜单。
|
||||
2. 只恢复有权且可直接落地的历史叶子路由。
|
||||
3. 历史地址不可用时,进入已授权菜单树中的首个可见叶子页。
|
||||
4. 新增“尚未分配菜单权限”页,支持重新加载和退出。
|
||||
5. 增加可执行的登录落点回归脚本。
|
||||
|
||||
## 操作后状态
|
||||
|
||||
- root 仍按菜单顺序进入数据概览。
|
||||
- 非 root 账号进入自身首个授权业务页。
|
||||
- 无权历史地址不会绕过鉴权,也不再导致登录后 404。
|
||||
- 零菜单账号获得明确中文说明和恢复入口。
|
||||
|
||||
## 代码变更
|
||||
|
||||
- `frontend/platform_admin/src/router/authorized-landing.ts`
|
||||
- `frontend/platform_admin/src/router/routes/base.ts`
|
||||
- `frontend/platform_admin/src/router/index.ts`
|
||||
- `frontend/platform_admin/src/router/constants.ts`
|
||||
- `frontend/platform_admin/src/views/login/components/login-form.vue`
|
||||
- `frontend/platform_admin/src/views/no-permission/index.vue`
|
||||
- `frontend/platform_admin/scripts/check-authorized-login-landing.mjs`
|
||||
- `frontend/platform_admin/package.json`
|
||||
|
||||
## 验证结果
|
||||
|
||||
- `pnpm auth-landing:check`:通过,覆盖有权历史页、无权历史页、父级分组和零菜单四条路径。
|
||||
- `pnpm contract:check`:通过,48 个资源契约正常。
|
||||
- `pnpm resource-display-contracts:check`:通过。
|
||||
- `pnpm type:check`:通过。
|
||||
- `pnpm build`:通过,新增权限引导页已生成独立产物。
|
||||
- Biome 定向检查退出码为 0;Vue 模板引用仍有工具级未使用警告,本次新页面组件名已显式声明。
|
||||
|
||||
## 风险评估
|
||||
|
||||
- 不修改登录接口、令牌格式、角色菜单表或后端鉴权,公共接口保持兼容。
|
||||
- 登录阶段增加一次已有资料请求,用于在跳转前取得真实菜单权限。
|
||||
36
docs/项目文档_平台账户授权登录落点_v1.0.md
Normal file
36
docs/项目文档_平台账户授权登录落点_v1.0.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# 项目文档:平台账户授权登录落点 v1.0
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
平台总后台使用 Vue 3、Vue Router、Pinia 和 Arco Design Vue。本功能使非 root 账号在登录后进入角色实际获授权的首个业务页,不再默认强制进入数据概览。
|
||||
|
||||
## 2. 目录结构
|
||||
|
||||
```text
|
||||
frontend/platform_admin/
|
||||
├── src/router/authorized-landing.ts # 授权历史地址和首个叶子菜单选择
|
||||
├── src/router/routes/base.ts # 零菜单权限页路由
|
||||
├── src/router/constants.ts # 权限守卫允许的引导页
|
||||
├── src/views/login/components/login-form.vue # 登录后加载资料并选择落点
|
||||
├── src/views/no-permission/index.vue # 尚未分配菜单权限引导
|
||||
└── scripts/check-authorized-login-landing.mjs # 登录落点回归检查
|
||||
```
|
||||
|
||||
## 3. 核心规则
|
||||
|
||||
1. 登录成功后立即读取当前账号资料和服务端菜单。
|
||||
2. 登录前历史地址是有权叶子页时恢复该地址。
|
||||
3. 历史地址无权、不存在或是父级分组时,从服务端已过滤菜单树中选择首个非隐藏叶子页。
|
||||
4. 角色没有任何可访问菜单时进入独立 403 引导页,可在 root 分配权限后重新加载,也可退出登录。
|
||||
5. 直接猜测未授权业务地址仍由前后端权限守卫拒绝,登录落点不扩大角色权限。
|
||||
|
||||
## 4. 变更记录
|
||||
|
||||
- v1.0:新增授权登录落点解析、历史地址安全恢复和零菜单权限引导页。
|
||||
- 不修改 JWT、平台角色数据、菜单分配接口和后端鉴权中间件。
|
||||
|
||||
## 5. 维护指南
|
||||
|
||||
- 新增一级菜单时必须保持服务端排序、前端路由 `menuCode` 和叶子页名称一致。
|
||||
- 不得将父级路由的硬编码重定向作为非 root 默认首页。
|
||||
- 调整登录或菜单时至少执行 `pnpm auth-landing:check`、`pnpm type:check` 和 `pnpm build`。
|
||||
Reference in New Issue
Block a user