OfficeSystem/store/user.js

201 lines
5.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}
})