Files
zkxw/web-admin/src/store/modules/user.ts
T

195 lines
5.3 KiB
TypeScript
Raw 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.
/**
* 用户状态管理模块
*
* 提供用户相关的状态管理
*
* ## 主要功能
*
* - 用户登录状态管理
* - 用户信息存储
* - 访问令牌和刷新令牌管理
* - 登出清理逻辑
*
* @module store/modules/user
*/
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { LanguageEnum } from '@/enums/appEnum'
import { router } from '@/router'
import { useWorktabStore } from './worktab'
import { AppRouteRecord } from '@/types/router'
import { setPageTitle } from '@/utils/router'
import { resetRouterState } from '@/router/guards/beforeEach'
import { useMenuStore } from './menu'
import { StorageConfig } from '@/utils/storage/storage-config'
/**
* 用户状态管理
* 管理用户登录状态、个人信息、令牌等
*/
export const useUserStore = defineStore(
'userStore',
() => {
// 登录状态
const isLogin = ref(false)
// 用户信息
const info = ref<Api.Auth.UserInfo>({} as Api.Auth.UserInfo)
// 访问令牌
const accessToken = ref('')
// 刷新令牌
const refreshToken = ref('')
/** 界面语言(與 vue-i18n、Element Plus 語系同步) */
const language = ref<LanguageEnum>(LanguageEnum.ZH)
/** 全局搜索最近访问记录(ArtGlobalSearch) */
const searchHistory = ref<AppRouteRecord[]>([])
/** 锁屏状态(ArtScreenLock) */
const isLock = ref(false)
/** 锁屏密码(AES 加密串) */
const lockPassword = ref('')
// 计算属性:获取用户信息
const getUserInfo = computed(() => info.value)
/**
* 设置用户信息
* @param newInfo 新的用户信息
*/
const setUserInfo = (newInfo: Partial<Api.Auth.UserInfo> & Record<string, any>) => {
info.value = {
...(info.value || {}),
...(newInfo || {}),
buttons: newInfo?.buttons ?? info.value?.buttons ?? [],
userName: newInfo?.userName ?? newInfo?.username ?? info.value?.userName ?? ''
} as Api.Auth.UserInfo
}
/**
* 设置登录状态
* @param status 登录状态
*/
const setLoginStatus = (status: boolean) => {
isLogin.value = status
}
/**
* 设置令牌
* @param newAccessToken 访问令牌
* @param newRefreshToken 刷新令牌(可选)
*/
const setToken = (newAccessToken: string, newRefreshToken?: string) => {
accessToken.value = newAccessToken
if (newRefreshToken) {
refreshToken.value = newRefreshToken
}
}
const setLanguage = (lang: LanguageEnum) => {
language.value = lang
}
const setSearchHistory = (list: AppRouteRecord[]) => {
searchHistory.value = list
}
const setLockStatus = (locked: boolean) => {
isLock.value = locked
}
const setLockPassword = (pwd: string) => {
lockPassword.value = pwd
}
/**
* 退出登录
* 清空所有用户相关状态并跳转到登录页
*/
const logOut = () => {
// 保存当前用户 ID,用于下次登录时判断是否为同一用户
const currentUserId = info.value.userId
if (currentUserId) {
localStorage.setItem(StorageConfig.LAST_USER_ID_KEY, String(currentUserId))
}
// 清空用户信息
info.value = {} as Api.Auth.UserInfo
// 重置登录状态
isLogin.value = false
// 清空访问令牌
accessToken.value = ''
// 清空刷新令牌
refreshToken.value = ''
searchHistory.value = []
isLock.value = false
lockPassword.value = ''
// 移除iframe路由缓存
sessionStorage.removeItem('iframeRoutes')
// 清空主页路径
useMenuStore().setHomePath('')
// 重置路由状态
resetRouterState(500)
// 跳转到登录页,携带当前路由作为 redirect 参数
const currentRoute = router.currentRoute.value
const redirect = currentRoute.path !== '/login' ? currentRoute.fullPath : undefined
router.push({
name: 'Login',
query: redirect ? { redirect } : undefined
})
}
/**
* 检查并清理工作台标签页
* 如果不是同一用户登录,清空工作台标签页
* 应在登录成功后调用
*/
const checkAndClearWorktabs = () => {
const lastUserId = localStorage.getItem(StorageConfig.LAST_USER_ID_KEY)
const currentUserId = info.value.userId
// 无法获取当前用户 ID,跳过检查
if (!currentUserId) return
// 首次登录或缓存已清除,保留现有标签页
if (!lastUserId) {
return
}
// 不同用户登录,清空工作台标签页
if (String(currentUserId) !== lastUserId) {
const worktabStore = useWorktabStore()
worktabStore.opened = []
worktabStore.keepAliveExclude = []
}
// 清除临时存储
localStorage.removeItem(StorageConfig.LAST_USER_ID_KEY)
}
return {
isLogin,
info,
accessToken,
refreshToken,
language,
searchHistory,
isLock,
lockPassword,
getUserInfo,
setUserInfo,
setLoginStatus,
setToken,
setLanguage,
setSearchHistory,
setLockStatus,
setLockPassword,
logOut,
checkAndClearWorktabs
}
},
{
persist: {
key: 'user',
storage: localStorage
}
}
)