import { defineStore } from 'pinia' import type { UserOrg } from '@/api/user' import type { AuthTokenPayload } from '@/utils/auth-token' import { resolvePermissions, resolvePrimaryRoleId, type PermissionCode, } from '@/config/permissions' const LEGACY_TOKEN_KEYS = ['token', 'refresh_token', 'user'] /** 用户登录态在本地存储中的 key,由 pinia-plugin-persistedstate 使用。 */ const AUTH_PERSIST_KEY = 'mini2_user_auth' /** * 用户状态 Store * * 使用 Composition API 风格(setup 语法)定义。 * 登录信息通过 pinia-plugin-persistedstate 保存到本地,刷新页面后可继续使用。 */ export const useUserStore = defineStore( 'user', () => { // -------------------------------- State -------------------------------- /** 登录凭证,登录成功后由后端返回,后续请求通过请求头携带 */ const token = ref('') const refreshToken = ref('') const username = ref('') const realName = ref('') const organizationName = ref('') /** 登录接口原始返回信息,已在保存前去除敏感字段。 */ const authPayload = ref(null) /** 当前登录机构,登录后取机构列表第一条。 */ const loginOrg = ref(null) /** 登录接口返回的角色标识及其对应的前端功能权限。 */ const roleIds = computed(() => { const value = authPayload.value?.principal?.roleIds return Array.isArray(value) ? value.filter((roleId): roleId is string => typeof roleId === 'string' && Boolean(roleId)) : [] }) /** 多角色场景下按角色优先级选出的默认角色。 */ const primaryRoleId = computed(() => resolvePrimaryRoleId(roleIds.value)) const permissions = computed(() => resolvePermissions(roleIds.value)) clearLegacyStoredTokens() // ------------------------------ Actions -------------------------------- /** * 设置 token * 登录成功或刷新 token 成功后调用。 */ function setToken(value: string) { token.value = value } function setRefreshToken(value: string) { refreshToken.value = value } function setAuthTokens( accessToken: string, newRefreshToken?: string, payload?: AuthTokenPayload, ) { setToken(accessToken) if (newRefreshToken) { setRefreshToken(newRefreshToken) } if (payload) { authPayload.value = payload } } function setUserInfo(info: { username?: string realName?: string organizationName?: string }) { username.value = info.username || username.value realName.value = info.realName || realName.value organizationName.value = info.organizationName || organizationName.value } function setAuthPayload(payload: AuthTokenPayload | null) { authPayload.value = payload } function setLoginOrg(org: UserOrg) { loginOrg.value = org organizationName.value = org.orgCnAbre || organizationName.value } function hasPermission(permission: PermissionCode) { return permissions.value.includes(permission) } /** * 清空 token * 退出登录或刷新 token 失败时调用。 */ function clearToken() { token.value = '' refreshToken.value = '' username.value = '' realName.value = '' organizationName.value = '' authPayload.value = null loginOrg.value = null } // ----------------------------- Return ---------------------------------- return { token, refreshToken, username, realName, organizationName, authPayload, loginOrg, roleIds, primaryRoleId, permissions, setToken, setRefreshToken, setAuthTokens, setUserInfo, setAuthPayload, setLoginOrg, hasPermission, clearToken, } }, { persist: { key: AUTH_PERSIST_KEY, pick: [ 'token', 'refreshToken', 'username', 'realName', 'organizationName', 'authPayload', 'loginOrg', ], }, }, ) function clearLegacyStoredTokens() { LEGACY_TOKEN_KEYS.forEach((key) => localStorage.removeItem(key)) }