import axios from 'axios' import { ApiResponseError, unwrapApiResponse, unwrapNullableApiResponse, } from '@/utils/api-response' import { request } from '@/utils/request' import type { AuthenticatedUser, CaptchaResponse, CurrentAuthorization, CurrentUserResponse, LoginRequest, LoginResponse, PasswordChangeRequest, ProfileUpdateRequest, } from '@/types/auth' import type { ApiResponse } from '@/types/common' export { ApiResponseError } from '@/utils/api-response' export async function getCaptcha(): Promise { const response = await request.get>('/v1/auth/captcha') return unwrapApiResponse(response) } function normalizePermissions(value: unknown): string[] { if (Array.isArray(value)) { return value.filter((item): item is string => typeof item === 'string') } if (typeof value === 'string') { try { const parsed = JSON.parse(value) as unknown return Array.isArray(parsed) ? parsed.filter((item): item is string => typeof item === 'string') : [] } catch { return [] } } return [] } function normalizeAuthenticatedUser(user: AuthenticatedUser): AuthenticatedUser { return { ...user, permissions: normalizePermissions(user.permissions), } } export async function login(payload: LoginRequest): Promise { const response = await request.post>('/v1/auth/login', payload) const session = unwrapApiResponse(response) if (!session.token || !session.user) { throw new Error('登录接口响应缺少 token 或用户信息') } const normalizedSession: LoginResponse = { ...session, expiresAt: session.expiresAt || '', user: normalizeAuthenticatedUser(session.user), } return normalizedSession } export async function getCurrentUser(): Promise { const response = await request.get>('/v1/auth/me') const user = unwrapApiResponse(response) return { ...user, permissions: normalizePermissions(user.permissions), } } export async function getCurrentAuthorization(): Promise { const response = await request.get>('/v1/authorization/me') return unwrapApiResponse(response) } export async function logout(): Promise { const response = await request.post>>('/v1/auth/logout') unwrapApiResponse(response) } export async function changePassword(payload: PasswordChangeRequest): Promise { const response = await request.post>('/v1/auth/password/change', payload) unwrapNullableApiResponse(response) } export function getAuthErrorMessage(error: unknown) { if (error instanceof ApiResponseError) { return error.message } if (axios.isAxiosError(error)) { if (!error.response) { return '无法连接登录服务,请检查网络或接口地址' } if (error.response.status === 401) { return '账号或密码错误' } return `登录失败(HTTP ${error.response.status})` } if (error instanceof Error && error.message) { return error.message } return '登录失败,请稍后重试' } export async function updateProfile(payload: ProfileUpdateRequest): Promise { const response = await request.request>({ url: '/v1/auth/me', method: 'PATCH', data: payload, }) return unwrapApiResponse(response) }