import { computed, ref } from 'vue' import { defineStore } from 'pinia' import { getCurrentUser, login as loginRequest, logout as logoutRequest } from '@/api/auth' import type { AuthenticatedUser, LoginRequest, LoginResponse } from '@/types/auth' import { clearAuthStorage, readStoredAuthSession, saveAuthSession } from '@/utils/auth-storage' const dataScopeLabels: Record = { ALL: '全院', CAMPUS: '院区', DEPARTMENT: '科室', READ_ONLY_ALL: '全院只读', } function getUserContext(user: AuthenticatedUser | null) { return user ? `${dataScopeLabels[user.dataScope]}数据范围` : '医签通用户' } export const useLoginStore = defineStore('login', () => { const storedSession = readStoredAuthSession() const token = ref(storedSession?.token ?? '') const expiresAt = ref(storedSession?.expiresAt ?? '') const user = ref(storedSession?.user ?? null) const currentUserReady = ref(false) let currentUserRequest: Promise | null = null const isLoggedIn = computed(() => Boolean(token.value)) const userName = computed(() => user.value?.displayName || user.value?.username || '医护用户') const department = computed(() => getUserContext(user.value)) function hasPermission(required: string | string[]) { const requiredPermissions = Array.isArray(required) ? required : [required] if (!requiredPermissions.length) { return true } const permissions = user.value?.permissions ?? [] return requiredPermissions.every( (permission) => permissions.includes(permission) || permissions.includes('*'), ) } function setSession(session: LoginResponse) { saveAuthSession(session) token.value = session.token expiresAt.value = session.expiresAt user.value = session.user currentUserReady.value = false } function setCurrentUser(nextUser: AuthenticatedUser) { user.value = nextUser if (token.value) { saveAuthSession({ token: token.value, expiresAt: expiresAt.value, user: nextUser, }) } } function clearSession() { clearAuthStorage() token.value = '' expiresAt.value = '' user.value = null currentUserReady.value = false currentUserRequest = null } async function login(payload: LoginRequest) { const session = await loginRequest(payload) setSession(session) return session } async function refreshCurrentUser() { const currentUser = await getCurrentUser() setCurrentUser(currentUser) return currentUser } async function ensureCurrentUser() { if (!token.value) { return null } if (currentUserReady.value && user.value) { return user.value } if (!currentUserRequest) { currentUserRequest = refreshCurrentUser() .then((currentUser) => { currentUserReady.value = true return currentUser }) .catch((error: unknown) => { currentUserReady.value = false throw error }) .finally(() => { currentUserRequest = null }) } return currentUserRequest } async function logout() { try { await logoutRequest() } finally { clearSession() } } return { token, expiresAt, user, isLoggedIn, userName, department, login, refreshCurrentUser, ensureCurrentUser, hasPermission, logout, clearSession, } })