/** * API基础服务 */ // 默认API基础URL const API_BASE_URL = process.env.API_BASE_URL || 'http://localhost:8000'; /** * 通用API响应格式 */ export interface ApiResponse { status: 'success' | 'error'; data?: T; message?: string; error?: { code: string; details?: any; }; } /** * 分页请求参数 */ export interface PaginationParams { page: number; pageSize: number; } /** * 分页响应数据 */ export interface PaginatedResponse { items: T[]; totalItems: number; totalPages: number; currentPage: number; pageSize: number; } /** * 统一错误处理 */ export class ApiError extends Error { statusCode: number; errorCode: string; details?: any; constructor(message: string, statusCode: number, errorCode: string, details?: any) { super(message); this.name = 'ApiError'; this.statusCode = statusCode; this.errorCode = errorCode; this.details = details; } } /** * 构建请求URL */ export function buildUrl(path: string, params?: Record): string { const url = new URL(`${API_BASE_URL}${path}`); if (params) { Object.entries(params).forEach(([key, value]) => { if (value !== undefined && value !== null) { url.searchParams.append(key, String(value)); } }); } return url.toString(); } /** * 通用API请求函数 */ export async function apiRequest( url: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET', body?: any, headers?: Record ): Promise { const requestInit: RequestInit = { method, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', ...headers } }; if (body) { requestInit.body = JSON.stringify(body); } const response = await fetch(url, requestInit); // 获取响应数据 const data = await response.json() as ApiResponse; // 检查状态码 if (!response.ok) { throw new ApiError( data.message || '请求失败', response.status, data.error?.code || 'UNKNOWN_ERROR', data.error?.details ); } // 检查业务状态 if (data.status === 'error') { throw new ApiError( data.message || '请求失败', response.status, data.error?.code || 'BUSINESS_ERROR', data.error?.details ); } return data.data as T; }