| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- /**
- * 用户状态管理模块
- *
- * 提供用户相关的状态管理
- *
- * ## 主要功能
- *
- * - 用户登录状态管理
- * - 用户信息存储
- * - 访问令牌和刷新令牌管理
- * - 登出清理逻辑
- *
- * @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'
- import { fetchLogout } from '@/api/auth'
- /**
- * 用户状态管理
- * 管理用户登录状态、个人信息、令牌等
- */
- 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
- }
- /**
- * 退出登录
- * 通知后端撤销 Redis 会话,然后清空所有用户相关状态并跳转到登录页
- */
- const logOut = async () => {
- // 先通知后端撤销 Redis 会话(不等待结果,失败也不阻塞退出)
- if (accessToken.value) {
- fetchLogout().catch(() => {})
- }
- // 保存当前用户 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
- }
- }
- )
|