Files
admin_core/demo-project/登录功能修复说明.md
张成 845658f193 1
2025-10-08 18:53:38 +08:00

6.9 KiB
Raw Blame History

登录功能修复说明

🔧 修复的问题

问题描述

登录时出现错误: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 工具类的处理流程

  1. 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)
          }
        }
      }
    )
    
  2. 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
    }
    
  3. 最终在 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)
  }
}

🎯 登录流程

完整的登录流程

  1. 用户输入用户名和密码

    • 组件:src/components/login-form/login-form.vue
    • 触发事件:on-success-valid
  2. 登录页面处理

    • 组件:src/views/login/login.vue
    • 调用:handleLogin action
  3. Vuex Action 处理

    • 文件:src/store/user.js
    • 方法:handleLogin
    • 步骤:
      1. 调用登录接口
      2. 保存 token 和用户名
      3. 处理权限菜单
      4. 生成路由
  4. HTTP 请求

    • 文件:src/api/system/userServer.js
    • 接口:POST /sys_user/login
    • 参数:{ name, password }
  5. 登录成功后

    • 显示成功提示
    • 刷新页面
    • 自动跳转到首页

📝 测试步骤

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. 验证登录成功

  • 显示"登录成功!"提示
  • 页面刷新
  • 跳转到系统首页
  • 显示用户名和菜单

🐛 调试技巧

查看登录请求

  1. 打开浏览器开发者工具F12
  2. 切换到 Network 标签
  3. 输入用户名密码,点击登录
  4. 查看 /sys_user/login 请求
  5. 检查 Response 数据结构

查看 Vuex 状态

  1. 安装 Vue DevTools 浏览器插件
  2. 打开 Vue DevTools
  3. 切换到 Vuex 标签
  4. 查看 user 模块的状态:
    • token:应该有值
    • userName:应该是登录的用户名
    • authorityMenus:应该是权限菜单数组

查看 localStorage

  1. 打开浏览器开发者工具F12
  2. 切换到 Application 标签
  3. 展开 Local Storage
  4. 查看存储的数据:
    • demo_tokentoken 值
    • 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 正确保存
  • 用户信息正确保存
  • 权限菜单正确处理
  • 登录成功后正确跳转
  • 错误处理完善

如果还有问题,请查看浏览器控制台的错误信息和网络请求详情。