201 lines
5.2 KiB
JavaScript
201 lines
5.2 KiB
JavaScript
import { defineStore } from 'pinia'
|
||
import { ADMIN_ROLES, normalizePermissions } from '@/utils/permission'
|
||
|
||
/**
|
||
* 用户信息 Store
|
||
* 用于管理用户登录状态、token等信息
|
||
*/
|
||
export const useUserStore = defineStore('user', {
|
||
state: () => {
|
||
const storedPrivateView = uni.getStorageSync('privateView')
|
||
const normalizePrivateView = () => {
|
||
if (typeof storedPrivateView === 'boolean') return storedPrivateView
|
||
if (storedPrivateView === '' || storedPrivateView === undefined || storedPrivateView === null) {
|
||
return false
|
||
}
|
||
return !!storedPrivateView
|
||
}
|
||
|
||
return {
|
||
// 用户 token
|
||
token: uni.getStorageSync('token') || '',
|
||
// 用户信息
|
||
userInfo: uni.getStorageSync('userInfo') || null,
|
||
// token 过期时间(可选)
|
||
tokenExpireTime: uni.getStorageSync('tokenExpireTime') || null,
|
||
// 是否启用私有视角
|
||
privateView: normalizePrivateView()
|
||
}
|
||
},
|
||
|
||
getters: {
|
||
/**
|
||
* 判断是否已登录
|
||
*/
|
||
isLogin: (state) => {
|
||
return !!state.token
|
||
},
|
||
|
||
/**
|
||
* 获取用户 token
|
||
*/
|
||
getToken: (state) => {
|
||
return state.token
|
||
},
|
||
|
||
/**
|
||
* 获取用户信息
|
||
*/
|
||
getUserInfo: (state) => {
|
||
return state.userInfo
|
||
},
|
||
|
||
/**
|
||
* 获取私有视角设置
|
||
*/
|
||
getPrivateView: (state) => {
|
||
return state.privateView
|
||
},
|
||
|
||
/**
|
||
* 获取用户角色列表
|
||
*/
|
||
getRoles: (state) => {
|
||
return Array.isArray(state.userInfo?.roles) ? state.userInfo.roles : []
|
||
},
|
||
|
||
/**
|
||
* 是否拥有管理员角色
|
||
*/
|
||
isAdmin: (state) => {
|
||
const roles = Array.isArray(state.userInfo?.roles) ? state.userInfo.roles : []
|
||
return roles.some((role) => ADMIN_ROLES.includes(role))
|
||
},
|
||
|
||
/**
|
||
* 获取权限列表
|
||
*/
|
||
getPermissions: (state) => {
|
||
return normalizePermissions(state.userInfo?.permissions)
|
||
},
|
||
|
||
/**
|
||
* 判断是否拥有指定权限
|
||
* 支持字符串、数组或以逗号分隔的字符串
|
||
* @param {string|string[]} requiredPermissions
|
||
* @param {object} options - { requireAll?: boolean }
|
||
*/
|
||
hasPermission: (state) => (requiredPermissions, options = {}) => {
|
||
const permissionsToCheck = (() => {
|
||
if (!requiredPermissions) return []
|
||
if (Array.isArray(requiredPermissions)) {
|
||
return requiredPermissions.filter(Boolean)
|
||
}
|
||
if (typeof requiredPermissions === 'string') {
|
||
return requiredPermissions
|
||
.split(',')
|
||
.map((perm) => perm.trim())
|
||
.filter(Boolean)
|
||
}
|
||
return []
|
||
})()
|
||
|
||
if (permissionsToCheck.length === 0) return false
|
||
if (Array.isArray(state.userInfo?.roles) && state.userInfo.roles.some((role) => ADMIN_ROLES.includes(role))) {
|
||
return true
|
||
}
|
||
|
||
const userPermissions = normalizePermissions(state.userInfo?.permissions)
|
||
if (userPermissions.length === 0) return false
|
||
|
||
const requireAll = options.requireAll || options.all
|
||
return requireAll
|
||
? permissionsToCheck.every((permission) => userPermissions.includes(permission))
|
||
: permissionsToCheck.some((permission) => userPermissions.includes(permission))
|
||
},
|
||
|
||
/**
|
||
* 判断 token 是否过期(如果设置了过期时间)
|
||
*/
|
||
isTokenExpired: (state) => {
|
||
if (!state.tokenExpireTime) return false
|
||
return Date.now() > state.tokenExpireTime
|
||
}
|
||
},
|
||
|
||
actions: {
|
||
/**
|
||
* 设置 token
|
||
* @param {string} token - 用户 token
|
||
* @param {number} expireTime - 过期时间(可选,时间戳)
|
||
*/
|
||
setToken(token, expireTime = null) {
|
||
this.token = token
|
||
this.tokenExpireTime = expireTime
|
||
|
||
// 同步到本地存储
|
||
uni.setStorageSync('token', token)
|
||
if (expireTime) {
|
||
uni.setStorageSync('tokenExpireTime', expireTime)
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 设置用户信息
|
||
* @param {object} userInfo - 用户信息对象
|
||
*/
|
||
setUserInfo(userInfo) {
|
||
this.userInfo = userInfo
|
||
uni.setStorageSync('userInfo', userInfo)
|
||
},
|
||
|
||
/**
|
||
* 登录
|
||
* @param {string} token - 用户 token
|
||
* @param {object} userInfo - 用户信息(可选)
|
||
* @param {number} expireTime - 过期时间(可选)
|
||
*/
|
||
login(token, userInfo = null, expireTime = null) {
|
||
this.setToken(token, expireTime)
|
||
if (userInfo) {
|
||
this.setUserInfo(userInfo)
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 退出登录
|
||
*/
|
||
logout() {
|
||
this.token = ''
|
||
this.userInfo = null
|
||
this.tokenExpireTime = null
|
||
this.privateView = false
|
||
|
||
// 清除本地存储
|
||
uni.removeStorageSync('token')
|
||
uni.removeStorageSync('userInfo')
|
||
uni.removeStorageSync('tokenExpireTime')
|
||
uni.removeStorageSync('privateView')
|
||
},
|
||
|
||
/**
|
||
* 更新 token(用于 token 刷新)
|
||
* @param {string} token - 新的 token
|
||
* @param {number} expireTime - 过期时间(可选)
|
||
*/
|
||
updateToken(token, expireTime = null) {
|
||
this.setToken(token, expireTime)
|
||
},
|
||
|
||
/**
|
||
* 设置私有视角
|
||
* @param {boolean} value
|
||
*/
|
||
setPrivateView(value) {
|
||
this.privateView = value
|
||
uni.setStorageSync('privateView', value)
|
||
}
|
||
}
|
||
})
|
||
|