修改登录退出逻辑
This commit is contained in:
@ -3,44 +3,85 @@ import { login } from '@/api/auth'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
// 1. State: 初始化时优先从 localStorage 获取,防止刷新丢失
|
||||
const token = ref(localStorage.getItem('token') || '')
|
||||
const role = ref(localStorage.getItem('role') || '') // 持久化角色
|
||||
const role = ref(localStorage.getItem('role') || '')
|
||||
const username = ref(localStorage.getItem('username') || '')
|
||||
|
||||
// 2. Actions
|
||||
// 登录逻辑
|
||||
const handleLogin = async (loginForm: any) => {
|
||||
try {
|
||||
const res = await login(loginForm)
|
||||
// res.data 结构: { access_token, user: { role, username, ... } }
|
||||
const data = res.data
|
||||
|
||||
// [调试日志] 查看实际返回的数据结构 (调试完成后可删除)
|
||||
console.log('Login API Response:', res)
|
||||
|
||||
// ============================================================
|
||||
// [关键修复] 兼容 Axios 拦截器的不同处理方式
|
||||
// 如果拦截器已经返回了 response.data,那么 res 本身就是数据对象
|
||||
// 如果拦截器返回的是原始 response,那么数据在 res.data 中
|
||||
// ============================================================
|
||||
const data = res.data || res
|
||||
|
||||
// 安全检查:确保 data 存在且包含 access_token
|
||||
if (!data || !data.access_token) {
|
||||
console.error('Login Error: 响应数据中缺少 access_token', data)
|
||||
return false
|
||||
}
|
||||
|
||||
// 更新 Pinia 状态 (内存)
|
||||
token.value = data.access_token
|
||||
role.value = data.user.role
|
||||
username.value = data.user.username
|
||||
|
||||
// 持久化存储 (简单处理,生产环境建议加密或仅存Token)
|
||||
// 处理用户信息 (确保后端返回结构中有 user 字段)
|
||||
if (data.user) {
|
||||
role.value = data.user.role || 'user' // 默认给个 user 角色防止空
|
||||
username.value = data.user.username || '用户'
|
||||
|
||||
// 持久化存储用户信息
|
||||
localStorage.setItem('role', role.value)
|
||||
localStorage.setItem('username', username.value)
|
||||
}
|
||||
|
||||
// 持久化存储 Token
|
||||
localStorage.setItem('token', data.access_token)
|
||||
localStorage.setItem('role', data.user.role)
|
||||
localStorage.setItem('username', data.user.username)
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.error('Login failed:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 退出逻辑
|
||||
const logout = () => {
|
||||
// 1. 清空 Pinia 状态 (内存)
|
||||
token.value = ''
|
||||
role.value = ''
|
||||
username.value = ''
|
||||
localStorage.clear()
|
||||
window.location.reload()
|
||||
|
||||
// 2. 清空 LocalStorage (硬盘)
|
||||
// 建议使用 removeItem 而不是 clear,避免误删该域名下其他非登录数据
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('role')
|
||||
localStorage.removeItem('username')
|
||||
|
||||
// 注意:这里不再执行 window.location.reload()
|
||||
// 而是把跳转控制权交给调用者 (如 App.vue 中的 router.push)
|
||||
}
|
||||
|
||||
// 辅助函数:判断当前用户是否拥有某些角色
|
||||
// 3. Getters / Helpers
|
||||
// 判断当前用户是否拥有某些角色
|
||||
const hasRole = (roles: string[]) => {
|
||||
return roles.includes(role.value)
|
||||
}
|
||||
|
||||
return { token, role, username, handleLogin, logout, hasRole }
|
||||
return {
|
||||
token,
|
||||
role,
|
||||
username,
|
||||
handleLogin,
|
||||
logout,
|
||||
hasRole
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user