import { defineStore } from 'pinia' import { ApiCode } from '@/config' import { fetchUserInfo, login, logoutRequest, type LoginBody } from '@/service/auth' // import { loginValid } from '@/service/auth' // 恢复二步登录时取消注释 import { syncTokenToHttpDefaults } from '@/service/http' import type { UserInfo } from '@/types/user' import { loggedIn } from '@/utils/auth' import { session } from '@/utils/session' import { usePermissionStore } from './permission' import { useVaultStore } from './vault' export const useAuthStore = defineStore('auth', { state: () => ({ token: null as string | null, user: null as UserInfo | null, expire: false, /** 防止多处同时触发 info 请求 */ userInfoRefreshInFlight: false, }), getters: { isLoggedIn: (s) => !!s.user && session.IsExist('user'), }, actions: { hydrateFromSession(): void { this.token = sessionStorage.getItem('access_token') const raw = session.Get('user', true) if (raw) { try { this.user = JSON.parse(raw) as UserInfo } catch { this.user = null } } else { this.user = null } // 动态侧栏:由后端 user.display 写入 permission store(恢复时取消注释) // if (this.user?.display) { // usePermissionStore().initFromUserDisplay(this.user.display) // } syncTokenToHttpDefaults() }, setAccessToken(token: string): void { this.token = token sessionStorage.setItem('access_token', token) syncTokenToHttpDefaults() }, setUserInfo(user: UserInfo): void { this.user = user session.Set('user', JSON.stringify(user), true) // if (user.display) { // usePermissionStore().initFromUserDisplay(user.display) // } }, setExpire(v: boolean): void { this.expire = v }, async fetchAndStoreUser(): Promise { try { const res = await fetchUserInfo() if (res.code === ApiCode.StatusOK && res.data) { this.setUserInfo(res.data as UserInfo) this.setExpire(false) return true } return false } catch { return false } }, /** * 全局静默同步用户信息。 * (恢复 display 驱动菜单时,setUserInfo 内 initFromUserDisplay 一并恢复。) */ async refreshUserInfoFromServer(): Promise { if (!sessionStorage.getItem('access_token')) return if (!loggedIn()) return if (this.userInfoRefreshInFlight) return this.userInfoRefreshInFlight = true try { await this.fetchAndStoreUser() } finally { this.userInfoRefreshInFlight = false } }, async doPasswordLogin(body: LoginBody): Promise { try { const res = await login(body) if (res.code === ApiCode.StatusOK && res.data) { this.setAccessToken(res.data as string) return await this.fetchAndStoreUser() } return false } catch { return false } }, /** 暂不使用:先 /user/login/valid 再弹二步;恢复时与 LoginView 二步流程一起启用 */ // async validateThenOpenSecondStep(loginName: string, password: string): Promise<1 | 0 | null> { // const res = await loginValid({ loginName, password }) // if (res.code === ApiCode.StatusOK && res.data !== undefined && res.data !== null) { // return res.data === 1 ? 1 : 0 // } // return null // }, async logout(): Promise { const res = await logoutRequest() if (res.code === ApiCode.StatusOK) { this.clearSession() return true } return false }, clearSession(): void { sessionStorage.clear() this.token = null this.user = null this.expire = false usePermissionStore().clear() useVaultStore().clear() syncTokenToHttpDefaults() }, }, })