import supabase from './supabase'; // Define response type for API export interface ApiResponse { success: boolean; data?: T; error?: string; message?: string; } /** * 通用的LIMQ API请求函数,包含重试机制和错误处理 */ export async function limqRequest( endpoint: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET', data?: Record, options?: { retryCount?: number; retryDelay?: number; timeout?: number; } ): Promise> { // 默认配置 const retryCount = options?.retryCount ?? 2; // 默认重试2次 const retryDelay = options?.retryDelay ?? 1000; // 默认延迟1秒 const timeout = options?.timeout ?? 10000; // 默认超时10秒 let lastError: Error | null = null; let currentRetry = 0; // 创建延迟函数 const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); // 重试循环 while (currentRetry <= retryCount) { try { console.log(`[API] ${method} ${endpoint} 尝试 ${currentRetry + 1}/${retryCount + 1}`); // 获取会话 const { data: { session } } = await supabase.auth.getSession(); // 检查会话是否存在 if (!session) { console.error(`[API] 未找到活跃会话,用户需要登录`); if (currentRetry < retryCount) { currentRetry++; console.log(`[API] 等待 ${retryDelay}ms 后重试获取会话...`); await delay(retryDelay); continue; } return { success: false, error: '需要登录才能访问API' }; } // 获取API基础URL const baseUrl = process.env.NEXT_PUBLIC_LIMQ_API; if (!baseUrl) { throw new Error('API URL未配置'); } const url = `${baseUrl}${endpoint.startsWith('/') ? endpoint : '/' + endpoint}`; console.log(`[API] 请求URL: ${url}`); // 构建请求选项 const fetchOptions: RequestInit = { method, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${session.access_token}` }, mode: 'cors' }; if (data && (method === 'POST' || method === 'PUT')) { fetchOptions.body = JSON.stringify(data); console.log(`[API] 请求数据:`, data); } // 添加超时控制 const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeout); fetchOptions.signal = controller.signal; // 发送请求 const response = await fetch(url, fetchOptions); clearTimeout(timeoutId); // 清除超时控制 // 处理响应 if (!response.ok) { const errorData = await response.json().catch(() => null); console.error(`[API] 请求失败: ${response.status} ${response.statusText}`, errorData); // 对于认证错误,尝试重试 if ((response.status === 401 || response.status === 403) && currentRetry < retryCount) { currentRetry++; console.log(`[API] 认证错误,等待 ${retryDelay}ms 后重试...`); await delay(retryDelay); continue; } throw new Error(errorData?.error || `请求失败: ${response.status}`); } // 成功响应 const responseData = await response.json(); console.log(`[API] ${method} ${endpoint} 成功`); return responseData; } catch (error) { lastError = error instanceof Error ? error : new Error(String(error)); console.error(`[API] 请求出错:`, lastError); // 对于超时和网络错误,尝试重试 if (currentRetry < retryCount && (error instanceof DOMException && error.name === 'AbortError' || error instanceof TypeError && error.message.includes('network'))) { currentRetry++; console.log(`[API] 网络错误,等待 ${retryDelay}ms 后重试...`); await delay(retryDelay); continue; } // 已达到最大重试次数或不是网络错误 break; } } // 所有重试均失败 console.error(`[API] ${method} ${endpoint} 失败,已重试 ${currentRetry} 次`); return { success: false, error: lastError?.message || '请求失败,请稍后重试' }; }