/** * API 工具函数 * * 统一处理 API 请求和错误响应 * 提供类型安全的API请求封装 * 包括:错误响应解析、成功响应解析、统一请求函数、错误消息获取 * * @created 2025-01-XX(从各组件提取) * @utils */ import type { ApiErrorResponse, ApiSuccessResponse } from '../_components/types' /** * 安全地解析 API 错误响应 * @param response - fetch Response 对象 * @returns Promise */ export async function parseErrorResponse(response: Response): Promise { try { const data = await response.json() return (data as ApiErrorResponse) || { error: '请求失败' } } catch { // 如果响应不是 JSON,返回默认错误 return { error: `HTTP ${response.status}: ${response.statusText || '请求失败'}` } } } /** * 安全地解析 API 成功响应 * @param response - fetch Response 对象 * @returns Promise */ export async function parseSuccessResponse(response: Response): Promise { const data = await response.json() return data as T } /** * 统一的 API 请求函数,自动处理错误 * @param url - API 端点 * @param options - fetch 选项 * @returns Promise<{ success: true; data: T } | { success: false; error: string }> */ export async function apiRequest( url: string, options?: RequestInit ): Promise<{ success: true; data: T } | { success: false; error: string }> { try { const response = await fetch(url, options) if (!response.ok) { const errorData = await parseErrorResponse(response) return { success: false, error: errorData.error || `HTTP ${response.status}: ${response.statusText || '请求失败'}`, } } const data = await parseSuccessResponse(response) return { success: true, data, } } catch (error) { console.error('API request error:', error) const errorMessage = error instanceof Error ? error.message : '网络请求失败,请稍后重试' return { success: false, error: errorMessage, } } } /** * 获取错误消息的辅助函数 * @param error - 错误对象或错误响应 * @param defaultMessage - 默认错误消息 * @returns 错误消息字符串 */ export function getErrorMessage( error: unknown, defaultMessage: string = '操作失败' ): string { if (typeof error === 'string') { return error } if (error instanceof Error) { return error.message || defaultMessage } if (error && typeof error === 'object' && 'error' in error) { const apiError = error as ApiErrorResponse return apiError.error || defaultMessage } return defaultMessage }