user.ts
2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { defineStore } from 'pinia'
import { AuthApi } from '@/api/login'
import { clearToken, setToken } from '@/utils/auth'
import { usePermissionStore } from './permission'
import type { LoginReqVO, UserInfoVO } from '@/types'
/**
* 用户 store:token / 用户信息 / 角色 / 权限标识
*
* 说明:菜单与路由不在本 store 里,统一由 permission store 负责(二者职责分离)。
*/
export const useUserStore = defineStore('user', () => {
const userInfo = ref<UserInfoVO | null>(null)
const roles = ref<string[]>([])
const permissions = ref<string[]>([])
/** 是否已拉取过用户信息 */
const isUserInfoLoaded = ref(false)
const isSuperAdmin = computed(() => roles.value.includes('super_admin'))
/** 登录:只负责拿 token */
async function login(reqVO: LoginReqVO) {
const data = await AuthApi.login(reqVO)
setToken(data.accessToken, data.refreshToken, data.expiresTime)
return data
}
/**
* 获取用户信息 + 角色 + 权限 + 菜单(一次请求)
* 并把菜单交给 permission store 生成路由
*/
async function getInfo() {
const data = await AuthApi.getPermissionInfo()
userInfo.value = data.user
roles.value = data.roles || []
permissions.value = data.permissions || []
isUserInfoLoaded.value = true
usePermissionStore().generateRoutes(data.menus || [])
return data
}
/** 登出:调后端注销 token,本地状态无论如何都要清干净 */
async function logout() {
try {
await AuthApi.logout()
} catch (e) {
// 后端不可用也要允许前端登出
} finally {
resetState()
}
}
function resetState() {
clearToken()
userInfo.value = null
roles.value = []
permissions.value = []
isUserInfoLoaded.value = false
usePermissionStore().reset()
}
/** 是否拥有某个权限标识(如 'park:park-lot:create');超管恒为 true */
function hasPermission(permission: string | string[]): boolean {
if (isSuperAdmin.value) return true
if (!permission || (Array.isArray(permission) && permission.length === 0)) return true
const required = Array.isArray(permission) ? permission : [permission]
return required.some((p) => permissions.value.includes(p))
}
/** 是否拥有某个角色;超管恒为 true */
function hasRole(role: string | string[]): boolean {
if (isSuperAdmin.value) return true
const required = Array.isArray(role) ? role : [role]
return required.some((r) => roles.value.includes(r))
}
return {
userInfo,
roles,
permissions,
isUserInfoLoaded,
isSuperAdmin,
login,
getInfo,
logout,
resetState,
hasPermission,
hasRole
}
})