6.9 KiB
6.9 KiB
登录功能修复说明
🔧 修复的问题
问题描述
登录时出现错误:Cannot read properties of undefined (reading 'message')
根本原因
登录接口返回的数据结构与代码中期望的不一致。
📊 数据结构分析
后端返回的数据结构
{
"code": 0,
"message": "请求成功",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"name": "zc",
"password": "d3df61764ee9a26091f714b88958caef",
"roleId": 6,
"create_time": "2022-10-24 05:45:40",
"last_modify_time": "2025-09-12 06:48:54"
},
"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]"
}
}
HTTP 工具类的处理流程
-
axios 响应拦截器(
src/utils/http.js第 55-69 行)instance.interceptors.response.use( response => { if (response.status === 200) { if (response.data && response.data.code === 0) { return response // 返回整个 response 对象 } else { // code 不为 0,拒绝 return Promise.reject(response.data.message) } } } ) -
http.post 方法(
src/utils/http.js第 176-191 行)async post(url, param, config) { let instance = this.getHttpInstance(config) let promise = new Promise((resolve, reject) => { instance.post(url, param).then(response => { resolve(response.data) // 返回 response.data }) }) return promise } -
最终在 user.js 中得到的数据结构
let res = await userServerInstance.login(userFrom) // res 的结构是: // { // code: 0, // message: "请求成功", // data: { token, user, authorityMenus } // }
✅ 修复方案
1. 修复 src/store/user.js 中的 handleLogin 方法
修复前:
let res = await userServerInstance.login(userFrom)
let token = res.data.token // ❌ 错误:res.data 是整个数据对象
let user = res.data.user
修复后:
let res = await userServerInstance.login(userFrom)
// 检查返回数据结构
if (res.code !== 0) {
throw new Error(res.message || '登录失败')
}
// 实际数据在 res.data 中
let token = res.data.token // ✅ 正确
let user = res.data.user // ✅ 正确
let authorityMenus = res.data.authorityMenus // ✅ 正确
2. 修复 src/store/user.js 中的 setAuthorityMenus 方法
修复前:
let res = await userServerInstance.authorityMenus()
let authorityMenus = res.data // ❌ 可能不正确
修复后:
let res = await userServerInstance.authorityMenus()
// res 的结构是 { code, message, data }
if (res && res.code === 0 && res.data) {
menus = res.data // ✅ 正确获取数据
}
3. 增强错误处理
在 src/views/login/login.vue 中:
async handleSubmit({ userName, password }) {
try {
let userFrom = { name: userName, password: password }
await this.handleLogin({
userFrom,
Main,
ParentView,
Page404
})
this.$Message.success('登录成功!')
window.location.reload()
} catch (error) {
console.error('登录失败:', error)
// 处理不同类型的错误
let errorMsg = '登录失败,请检查用户名和密码'
if (error) {
if (typeof error === 'string') {
errorMsg = error
} else if (error.message) {
errorMsg = error.message
} else if (error.data && error.data.message) {
errorMsg = error.data.message
}
}
this.$Message.error(errorMsg)
}
}
🎯 登录流程
完整的登录流程
-
用户输入用户名和密码
- 组件:
src/components/login-form/login-form.vue - 触发事件:
on-success-valid
- 组件:
-
登录页面处理
- 组件:
src/views/login/login.vue - 调用:
handleLoginaction
- 组件:
-
Vuex Action 处理
- 文件:
src/store/user.js - 方法:
handleLogin - 步骤:
- 调用登录接口
- 保存 token 和用户名
- 处理权限菜单
- 生成路由
- 文件:
-
HTTP 请求
- 文件:
src/api/system/userServer.js - 接口:
POST /sys_user/login - 参数:
{ name, password }
- 文件:
-
登录成功后
- 显示成功提示
- 刷新页面
- 自动跳转到首页
📝 测试步骤
1. 启动项目
cd demo-project
npm run dev
2. 打开浏览器
访问:http://localhost:8080
3. 输入登录信息
- 用户名:
zc(或其他有效用户名) - 密码:对应的密码
4. 查看控制台日志
应该能看到以下日志:
登录接口返回: { code: 0, message: "请求成功", data: {...} }
处理权限菜单: [1,142,121,...]
生成的主菜单: { path: '/', children: [...] }
✅ Demo 项目启动成功!
5. 验证登录成功
- ✅ 显示"登录成功!"提示
- ✅ 页面刷新
- ✅ 跳转到系统首页
- ✅ 显示用户名和菜单
🐛 调试技巧
查看登录请求
- 打开浏览器开发者工具(F12)
- 切换到 Network 标签
- 输入用户名密码,点击登录
- 查看
/sys_user/login请求 - 检查 Response 数据结构
查看 Vuex 状态
- 安装 Vue DevTools 浏览器插件
- 打开 Vue DevTools
- 切换到 Vuex 标签
- 查看
user模块的状态:token:应该有值userName:应该是登录的用户名authorityMenus:应该是权限菜单数组
查看 localStorage
- 打开浏览器开发者工具(F12)
- 切换到 Application 标签
- 展开 Local Storage
- 查看存储的数据:
demo_token:token 值userName:用户名authorityMenus:权限菜单 JSON 字符串
⚠️ 注意事项
1. authorityMenus 的数据格式
后端返回的 authorityMenus 是一个 字符串:
"authorityMenus": "[1,142,121,143,...]"
代码会自动解析这个字符串为数组。
2. 权限菜单的处理
- 登录接口返回的
authorityMenus是菜单 ID 数组 - 需要根据这些 ID 从菜单配置中生成实际的路由
- 使用
uiTool.getRoutes()方法生成路由
3. Token 的使用
- Token 保存在 Vuex store 和 localStorage 中
- 每次 HTTP 请求都会自动带上 token(在请求头
admin-token中) - Token 失效时会自动跳转到登录页
🎉 修复完成
现在登录功能应该可以正常工作了!
验证清单
- ✅ 登录接口正确调用
- ✅ Token 正确保存
- ✅ 用户信息正确保存
- ✅ 权限菜单正确处理
- ✅ 登录成功后正确跳转
- ✅ 错误处理完善
如果还有问题,请查看浏览器控制台的错误信息和网络请求详情。