1
This commit is contained in:
326
demo-project/_doc/权限菜单说明.md
Normal file
326
demo-project/_doc/权限菜单说明.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# 权限菜单处理说明
|
||||
|
||||
## 📊 当前情况
|
||||
|
||||
### 登录接口返回的数据
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "请求成功",
|
||||
"data": {
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"user": {
|
||||
"id": 1,
|
||||
"name": "zc",
|
||||
"roleId": 6
|
||||
},
|
||||
"authorityMenus": "[1,142,121,143,144,145,124,147,120,123,125,132,133,126,136,137,138,139,151,152,153,154,149,150,156,157,158,122,159,5,11,12,13,67,68,15]"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 问题分析
|
||||
|
||||
**登录接口返回的 `authorityMenus`**:
|
||||
- 类型:字符串
|
||||
- 内容:菜单 ID 数组 `"[1,142,121,...]"`
|
||||
- 作用:表示用户有权限访问的菜单 ID 列表
|
||||
|
||||
**框架期望的 `authorityMenus`**:
|
||||
- 类型:对象数组
|
||||
- 内容:完整的菜单对象,包含以下字段:
|
||||
```javascript
|
||||
{
|
||||
id: 1,
|
||||
name: "系统管理",
|
||||
path: "/system",
|
||||
component: "...",
|
||||
parent_id: 0,
|
||||
type: "菜单",
|
||||
is_show_menu: 1,
|
||||
children: [...]
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 解决方案
|
||||
|
||||
### 方案一:调用 authorityMenus 接口(当前实现)
|
||||
|
||||
登录成功后,调用 `/sys_user/authorityMenus` 接口获取完整的菜单对象数组。
|
||||
|
||||
**流程:**
|
||||
1. 用户登录 → 获取 token 和菜单 ID 列表
|
||||
2. 保存 token
|
||||
3. 调用 `authorityMenus` 接口 → 获取完整菜单对象数组
|
||||
4. 生成路由
|
||||
|
||||
**代码实现:**
|
||||
```javascript
|
||||
// src/store/user.js
|
||||
async handleLogin({ state, commit, dispatch }, { userFrom, Main, ParentView, Page404 }) {
|
||||
let res = await userServerInstance.login(userFrom)
|
||||
|
||||
let token = res.data.token
|
||||
let user = res.data.user
|
||||
|
||||
commit('setUserName', user.name.trim())
|
||||
commit('setToken', token)
|
||||
|
||||
// 调用 authorityMenus 接口获取完整菜单数据
|
||||
await dispatch('setAuthorityMenus', { Main, ParentView, Page404 })
|
||||
}
|
||||
```
|
||||
|
||||
**优点:**
|
||||
- 简单直接
|
||||
- 不需要修改后端接口
|
||||
|
||||
**缺点:**
|
||||
- 需要额外的 HTTP 请求
|
||||
- 如果 authorityMenus 接口失败,用户无法进入系统
|
||||
|
||||
### 方案二:后端直接返回完整菜单对象(推荐)
|
||||
|
||||
修改后端登录接口,直接返回完整的菜单对象数组,而不是菜单 ID 数组。
|
||||
|
||||
**修改后的返回数据:**
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "请求成功",
|
||||
"data": {
|
||||
"token": "...",
|
||||
"user": {...},
|
||||
"authorityMenus": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "系统管理",
|
||||
"path": "/system",
|
||||
"component": "Main",
|
||||
"parent_id": 0,
|
||||
"type": "菜单",
|
||||
"is_show_menu": 1,
|
||||
"children": [...]
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**优点:**
|
||||
- 减少 HTTP 请求
|
||||
- 登录更快
|
||||
- 数据一致性更好
|
||||
|
||||
**缺点:**
|
||||
- 需要修改后端代码
|
||||
|
||||
## 📝 当前实现
|
||||
|
||||
### 登录流程
|
||||
|
||||
1. **用户输入用户名密码**
|
||||
```javascript
|
||||
// src/views/login/login.vue
|
||||
handleSubmit({ userName, password }) {
|
||||
let userFrom = { name: userName, password: password }
|
||||
this.handleLogin({ userFrom, Main, ParentView, Page404 })
|
||||
}
|
||||
```
|
||||
|
||||
2. **调用登录接口**
|
||||
```javascript
|
||||
// src/store/user.js
|
||||
let res = await userServerInstance.login(userFrom)
|
||||
// 返回: { code: 0, data: { token, user, authorityMenus: "[1,2,3...]" } }
|
||||
```
|
||||
|
||||
3. **保存 token 和用户信息**
|
||||
```javascript
|
||||
commit('setUserName', user.name.trim())
|
||||
commit('setToken', token)
|
||||
```
|
||||
|
||||
4. **获取完整菜单数据**
|
||||
```javascript
|
||||
// 调用 /sys_user/authorityMenus 接口
|
||||
await dispatch('setAuthorityMenus', { Main, ParentView, Page404 })
|
||||
```
|
||||
|
||||
5. **处理菜单数据**
|
||||
```javascript
|
||||
// src/store/user.js - setAuthorityMenus
|
||||
let res = await userServerInstance.authorityMenus()
|
||||
// 期望返回: { code: 0, data: [{id, name, path, ...}, ...] }
|
||||
|
||||
let menus = res.data
|
||||
commit('setAuthorityMenus', JSON.stringify(menus))
|
||||
|
||||
// 生成路由
|
||||
let mainMenu = uiTool.getRoutes(Main, ParentView, Page404)
|
||||
commit('setMenuList', mainMenu.children)
|
||||
```
|
||||
|
||||
6. **刷新页面进入系统**
|
||||
```javascript
|
||||
window.location.reload()
|
||||
```
|
||||
|
||||
## ⚠️ 需要确认的事项
|
||||
|
||||
### 1. authorityMenus 接口返回的数据格式
|
||||
|
||||
请确认 `/sys_user/authorityMenus` 接口返回的数据格式:
|
||||
|
||||
**期望格式:**
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "请求成功",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "首页",
|
||||
"path": "/home",
|
||||
"component": "home/index",
|
||||
"parent_id": 0,
|
||||
"type": "页面",
|
||||
"is_show_menu": 1,
|
||||
"icon": "md-home",
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "系统管理",
|
||||
"path": "/system",
|
||||
"component": "",
|
||||
"parent_id": 0,
|
||||
"type": "菜单",
|
||||
"is_show_menu": 1,
|
||||
"icon": "md-settings",
|
||||
"sort": 2,
|
||||
"children": [
|
||||
{
|
||||
"id": 11,
|
||||
"name": "用户管理",
|
||||
"path": "/system/user",
|
||||
"component": "system/sys_user",
|
||||
"parent_id": 5,
|
||||
"type": "页面",
|
||||
"is_show_menu": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 菜单对象的必需字段
|
||||
|
||||
每个菜单对象需要包含以下字段:
|
||||
|
||||
| 字段 | 类型 | 说明 | 必需 |
|
||||
|------|------|------|------|
|
||||
| id | Number | 菜单 ID | ✅ |
|
||||
| name | String | 菜单名称 | ✅ |
|
||||
| path | String | 路由路径 | ✅ |
|
||||
| component | String | 组件路径 | ✅ |
|
||||
| parent_id | Number | 父菜单 ID(0 表示顶级菜单) | ✅ |
|
||||
| type | String | 类型:"菜单"、"页面"、"功能" | ✅ |
|
||||
| is_show_menu | Number | 是否显示在菜单中(1=显示,0=隐藏) | ✅ |
|
||||
| icon | String | 图标名称 | ❌ |
|
||||
| sort | Number | 排序 | ❌ |
|
||||
| children | Array | 子菜单 | ❌ |
|
||||
|
||||
## 🐛 调试方法
|
||||
|
||||
### 1. 查看 authorityMenus 接口返回
|
||||
|
||||
在浏览器控制台查看:
|
||||
```javascript
|
||||
// 登录成功后,查看控制台日志
|
||||
获取权限菜单返回: { code: 0, data: [...] }
|
||||
处理权限菜单: [...]
|
||||
生成的主菜单: { path: '/', children: [...] }
|
||||
```
|
||||
|
||||
### 2. 查看 localStorage
|
||||
|
||||
打开浏览器开发者工具 → Application → Local Storage:
|
||||
```javascript
|
||||
authorityMenus: "[{\"id\":1,\"name\":\"首页\",...}]"
|
||||
```
|
||||
|
||||
### 3. 查看网络请求
|
||||
|
||||
打开浏览器开发者工具 → Network:
|
||||
1. 查看 `/sys_user/login` 请求的响应
|
||||
2. 查看 `/sys_user/authorityMenus` 请求的响应
|
||||
|
||||
## 🎯 测试步骤
|
||||
|
||||
### 1. 测试登录
|
||||
```bash
|
||||
# 启动项目
|
||||
cd demo-project
|
||||
npm run dev
|
||||
|
||||
# 打开浏览器
|
||||
http://localhost:8080
|
||||
|
||||
# 输入用户名密码
|
||||
用户名: zc
|
||||
密码: ***
|
||||
|
||||
# 点击登录
|
||||
```
|
||||
|
||||
### 2. 查看控制台日志
|
||||
应该看到:
|
||||
```
|
||||
登录接口返回: { code: 0, data: { token, user, authorityMenus } }
|
||||
登录返回的菜单 IDs: "[1,142,121,...]"
|
||||
获取权限菜单返回: { code: 0, data: [...] }
|
||||
处理权限菜单: [...]
|
||||
生成的主菜单: { path: '/', children: [...] }
|
||||
```
|
||||
|
||||
### 3. 验证登录成功
|
||||
- ✅ 显示"登录成功!"提示
|
||||
- ✅ 页面刷新
|
||||
- ✅ 进入系统首页
|
||||
- ✅ 左侧显示菜单
|
||||
|
||||
## 💡 建议
|
||||
|
||||
### 短期方案(当前实现)
|
||||
保持现有实现,登录后调用 `authorityMenus` 接口获取完整菜单数据。
|
||||
|
||||
### 长期方案(推荐)
|
||||
建议后端修改登录接口,直接返回完整的菜单对象数组,减少 HTTP 请求,提升用户体验。
|
||||
|
||||
**修改建议:**
|
||||
```javascript
|
||||
// 后端登录接口返回
|
||||
{
|
||||
"code": 0,
|
||||
"message": "请求成功",
|
||||
"data": {
|
||||
"token": "...",
|
||||
"user": {...},
|
||||
"authorityMenus": [
|
||||
// 完整的菜单对象数组,而不是 ID 数组字符串
|
||||
{ id: 1, name: "首页", path: "/home", ... },
|
||||
{ id: 5, name: "系统管理", path: "/system", children: [...] }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这样前端就可以直接使用,不需要额外的 HTTP 请求。
|
||||
|
||||
---
|
||||
|
||||
**当前状态**:登录功能正常,需要确认 `authorityMenus` 接口返回的数据格式是否正确。
|
||||
|
||||
Reference in New Issue
Block a user