Files
art-design/src/store/modules/user copy.ts
T

213 lines
6.2 KiB
TypeScript
Raw Normal View History

2025-09-18 10:57:17 +08:00
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { LanguageEnum } from '@/enums/appEnum'
import { router } from '@/router'
import { useSettingStore } from './setting'
import { useWorktabStore } from './worktab'
import { AppRouteRecord } from '@/types/router'
import { setPageTitle } from '@/router/utils/utils'
import { resetRouterState } from '@/router/guards/beforeEach'
import { RoutesAlias } from '@/router/routesAlias'
import { UserService } from '@/api/usersApi' // 新增导入
let refreshTimeout: ReturnType<typeof setTimeout> | null = null // 定时器变量
// 用户
export const useUserStore = defineStore(
'userStore',
() => {
const language = ref(LanguageEnum.ZH)
const isLogin = ref(false)
const isLock = ref(false)
const lockPassword = ref('')
const info = ref<Partial<Api.User.UserInfo>>({})
const searchHistory = ref<AppRouteRecord[]>([])
const accessToken = ref('')
const refreshToken = ref('')
const companyid = ref('')
const companyabbr = ref('')
const systemsid = ref('')
const systemsabbr = ref('')
const home_page = ref('')
const loginType = ref<'feishu' | 'upwd'>('upwd')
const tokenExpireAt = ref<number>(0)
const getUserInfo = computed(() => info.value)
const getSettingState = computed(() => useSettingStore().$state)
const getWorktabState = computed(() => useWorktabStore().$state)
const setUserInfo = (newInfo: Api.User.UserInfo) => {
info.value = newInfo
}
const setLoginStatus = (status: boolean) => {
isLogin.value = status
}
const setLanguage = (lang: LanguageEnum) => {
setPageTitle(router.currentRoute.value)
language.value = lang
}
const setLoginType = (type: 'feishu' | 'upwd') => {
loginType.value = type
}
const setSearchHistory = (list: AppRouteRecord[]) => {
searchHistory.value = list
}
const setLockStatus = (status: boolean) => {
isLock.value = status
}
const setLockPassword = (password: string) => {
lockPassword.value = password
}
const setToken = (newAccessToken: string, newRefreshToken?: string, expiresIn?: number) => {
accessToken.value = newAccessToken
if (newRefreshToken) {
refreshToken.value = newRefreshToken
}
if (expiresIn) {
const expireAt = Date.now() + expiresIn * 1000
tokenExpireAt.value = expireAt
localStorage.setItem('token_expire_at', String(expireAt))
// 检查是否需要重新设置定时器
const currentLeftSeconds = Math.floor((expireAt - Date.now()) / 1000)
if (currentLeftSeconds > 0) {
scheduleTokenRefresh(currentLeftSeconds)
}
}
}
const setCompany = (id: string, abbr: string) => {
companyid.value = id
companyabbr.value = abbr
}
const setSystems = (id: string, abbr: string) => {
systemsid.value = id
systemsabbr.value = abbr
}
// 设置首页
const sethome_page = (page: string) => {
home_page.value = page
}
function restoreTokenTimer() {
const expireAt = Number(localStorage.getItem('token_expire_at') || '0')
if (accessToken.value && expireAt > Date.now()) {
const leftSeconds = Math.floor((expireAt - Date.now()) / 1000)
scheduleTokenRefresh(leftSeconds)
}
}
let isScheduled = false
function scheduleTokenRefresh(expiresIn: number) {
if (refreshTimeout) {
clearTimeout(refreshTimeout)
refreshTimeout = null
}
// 提前1分钟刷新
const refreshTime = (expiresIn - 60) * 1000
if (refreshTime > 0) {
if (!isScheduled) {
isScheduled = true
refreshTimeout = setTimeout(() => {
refreshTokenAction().finally(() => {
isScheduled = false // 重置标志位
})
}, refreshTime)
} else {
console.log('scheduleTokenRefresh is already scheduled, skipping...')
}
} else {
console.error('Invalid refreshTime:', refreshTime)
}
}
async function refreshTokenAction() {
try {
const { data } = await UserService.refreshToken({ refresh_token: refreshToken.value })
// 动态计算剩余时间
const currentTime = Date.now()
const expireAt = currentTime + data.expires_in * 1000
const leftSeconds = Math.floor((expireAt - currentTime) / 1000)
setToken(data.access_token, data.refresh_token, leftSeconds)
} catch (e) {
console.error('Token refresh failed:', e)
logOut()
}
}
const logOut = () => {
// 清空所有本地缓存
localStorage.clear()
sessionStorage.clear()
systemsabbr.value = ''
systemsid.value = ''
companyabbr.value = ''
companyid.value = ''
home_page.value = ''
info.value = {}
isLogin.value = false
isLock.value = false
lockPassword.value = ''
accessToken.value = ''
refreshToken.value = ''
if (refreshTimeout) clearTimeout(refreshTimeout) // 清理定时器
// 清理工作台标签页
useWorktabStore().clearAll()
// 清理sessionStorage中的用户信息缓存
sessionStorage.removeItem('lastUserInfo')
sessionStorage.removeItem('iframeRoutes')
// 重置路由状态
resetRouterState(router)
// 跳转到登录页
router.push(RoutesAlias.Login)
}
return {
language,
isLogin,
isLock,
lockPassword,
info,
companyid,
companyabbr,
systemsid,
systemsabbr,
home_page,
searchHistory,
loginType,
accessToken,
refreshToken,
tokenExpireAt,
getUserInfo,
getSettingState,
getWorktabState,
setUserInfo,
setLoginStatus,
setLanguage,
setSearchHistory,
setLockStatus,
setLockPassword,
setToken,
setCompany,
setSystems,
setLoginType,
sethome_page,
logOut,
restoreTokenTimer
}
},
{
persist: {
key: 'user',
storage: localStorage,
afterRestore: (ctx: { store: { restoreTokenTimer: () => void } }) => {
ctx.store.restoreTokenTimer()
}
} as any
}
)