/** * 用户认证状态管理 */ import { defineStore } from 'pinia'; import { ref, computed } from 'vue'; import type { UserInfo } from '@/types/chat'; // 开发环境默认跳过登录校验,避免频繁登录打断调试 const DEV_AUTH_BYPASS = import.meta.env.DEV; // MARK: dev 默认 token(当 URL 无 token 参数时使用) const DEV_DEFAULT_TOKEN = ''; const DEV_BYPASS_USER: UserInfo = { id: 'dev-user', username: 'dev-user', nickname: '开发环境用户', }; // 认证接口返回格式 interface AuthResponse { status: number; message: string; data: { token: string; userInfo: { userId: number | string; userName?: string; realName?: string; email?: string; userIcon?: string; [key: string]: unknown; }; [key: string]: unknown; } | null; } // 认证接口 const AUTH_BASE_URL = (import.meta.env.VITE_AUTH_BASE_URL || '').replace(/\/$/, ''); const AUTH_CHECK_URL = `${AUTH_BASE_URL}/newapi/api/login/validateToken`; const AUTH_TOKEN_STORAGE_KEY = 'DEV_DEFAULT_TOKEN'; export const useAuthStore = defineStore('auth', () => { // 状态 const token = ref(null); const user = ref(null); const isInitialized = ref(false); // 计算属性 const isAuthenticated = computed(() => DEV_AUTH_BYPASS || !!token.value); const userId = computed(() => user.value?.username || null); // username 用于 OSS 路径和数据库 user_id /** * 验证 token 并获取用户信息 */ async function checkToken(tokenToCheck: string): Promise { try { const response = await fetch(AUTH_CHECK_URL, { method: 'POST', headers: { authorization: tokenToCheck, }, }); if (!response.ok) { return null; } const data: AuthResponse = await response.json(); if (data.status === 1000 && data.data?.userInfo) { const { userInfo } = data.data; return { ...userInfo, id: String(userInfo.userId), username: userInfo.userName, nickname: userInfo.realName, email: userInfo.email, avatar: userInfo.userIcon, }; } else { window.$toast?.('[Auth] Token 验证失败:Token无效'); } return null; } catch (error) { console.error('[Auth] Token 验证失败:', error); return null; } } /** * 初始化 - 从 URL 参数获取 token,验证后设置用户信息 */ async function init() { const searchParams = new URLSearchParams(window.location.search); const urlToken = searchParams.get('token'); // 获取 token:URL > localStorage > 默认值 const tokenValue = urlToken || localStorage.getItem(AUTH_TOKEN_STORAGE_KEY) || DEV_DEFAULT_TOKEN; if (DEV_AUTH_BYPASS && !tokenValue) { token.value = null; user.value = DEV_BYPASS_USER; isInitialized.value = true; return; } if (!tokenValue) { isInitialized.value = true; window.$toast?.('未登录,请先登录', 'error'); return; } // 验证 token const userInfo = await checkToken(tokenValue); if (userInfo) { token.value = tokenValue; user.value = userInfo; } else { // 验证失败,清空 token.value = null; user.value = null; } isInitialized.value = true; } /** * 设置用户信息 */ function setUser(userInfo: UserInfo) { user.value = userInfo; } /** * 获取认证 header */ function getAuthHeader(): Record { if (token.value) { return { Authorization: `Bearer ${token.value}` }; } return {}; } return { // 状态 token, user, isAuthenticated, userId, isInitialized, // 方法 setUser, getAuthHeader, init, }; });