import axios, { AxiosInstance, AxiosResponse, AxiosError, InternalAxiosRequestConfig, } from "axios"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { Platform } from 'react-native'; import { API_BASE_URL, API_TIMEOUT, DEFAULT_HEADERS, STORAGE_KEYS, } from "../../constants/config"; // import { Platform } from "react-native"; // 定义响应类型接口 export interface ApiResponse { data: T; status: number; statusText: string; headers: any; } // 定义错误类型接口 export interface ApiError { message: string; status?: number; data?: any; } // 扩展 AxiosRequestConfig 类型 interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig { retry?: number; retryDelay?: (retryCount: number) => number; } // 创建axios实例 const apiClient: AxiosInstance = axios.create({ baseURL: API_BASE_URL, timeout: API_TIMEOUT, headers: DEFAULT_HEADERS, httpsAgent: Platform.OS === 'android' ? { // 强制使用兼容的TLS参数 ciphers: [ 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256' ].join(':'), minVersion: 'TLSv1.2' } : undefined }); // 请求拦截器 apiClient.interceptors.request.use( async (config: InternalAxiosRequestConfig) => { const baseUrl = config.baseURL || ''; let fullUrl = baseUrl + config.url; if (config.params) { const params = new URLSearchParams(config.params); fullUrl += (fullUrl.includes('?') ? '&' : '?') + params.toString(); } // 根据平台设置请求方法大小写 if (config.method) { if (Platform.OS === 'ios') { // iOS使用小写方法 config.method = config.method.toLowerCase(); } else if (Platform.OS === 'android') { // Android使用大写方法 config.method = config.method.toUpperCase(); } } // console.log("环境:", __DEV__ ? "开发环境" : "生产环境"); // console.log("请求方法:", config.method); // console.log("完整URL:", fullUrl); // console.log("请求头:", config.headers); // console.log("请求参数:", config.params); // console.log("请求数据:", config.data); // 从AsyncStorage获取token const token = await AsyncStorage.getItem("token"); // 如果token存在,添加到请求头 if (token && config.headers) { config.headers.Authorization = `${token}`; } return config; }, (error: AxiosError) => { console.error("请求拦截器错误:", error); return Promise.reject(error); } ); // 响应拦截器 apiClient.interceptors.response.use( (response: AxiosResponse) => { // 成功响应处理 // console.log("响应成功:", { // status: response.status, // statusText: response.statusText, // headers: response.headers, // data: response.data, // }); return response; }, async (error: AxiosError) => { // 错误响应处理 const { response, config } = error; console.error("响应错误:", { url: config?.url, method: config?.method, message: error.message, code: error.code, stack: error.stack, }); // 处理网络错误 if (!response) { console.error("网络错误:", { message: error.message, code: error.code, stack: error.stack, }); // 如果是网络错误,尝试重试 const customConfig = config as CustomAxiosRequestConfig; if (customConfig && customConfig.retry) { customConfig.retry -= 1; if (customConfig.retry > 0) { const delay = customConfig.retryDelay ? customConfig.retryDelay(customConfig.retry) : 1000; console.log(`重试请求 (${customConfig.retry}): ${customConfig.url}`); await new Promise(resolve => setTimeout(resolve, delay)); return apiClient(customConfig); } } } // 处理401错误 (未授权) if (response && response.status === 401) { console.log("未授权错误,清除token"); await AsyncStorage.removeItem(STORAGE_KEYS.AUTH_TOKEN); } // 构建标准化的错误对象 const apiError: ApiError = { message: error.message || "网络请求失败", status: response?.status, data: response?.data, }; return Promise.reject(apiError); } ); // API方法封装 export const apiService = { // GET请求 async get(url: string, params?: any, config?: any): Promise { try { const customConfig: CustomAxiosRequestConfig = { ...config, retry: 3, retryDelay: (retryCount) => retryCount * 1000, }; const response = await apiClient.get(url, { params, ...customConfig }); return response.data; } catch (error) { throw error; } }, // POST请求 async post(url: string, data?: any, config?: any): Promise { try { const customConfig: CustomAxiosRequestConfig = { ...config, retry: 3, retryDelay: (retryCount) => retryCount * 1000, }; const response = await apiClient.post(url, data, customConfig); return response.data; } catch (error) { throw error; } }, // PUT请求 async put(url: string, data?: any, config?: any): Promise { try { const customConfig: CustomAxiosRequestConfig = { ...config, retry: 3, retryDelay: (retryCount) => retryCount * 1000, }; const response = await apiClient.put(url, data, customConfig); return response.data; } catch (error) { throw error; } }, // PATCH请求 async patch(url: string, data?: any, config?: any): Promise { try { const customConfig: CustomAxiosRequestConfig = { ...config, retry: 3, retryDelay: (retryCount) => retryCount * 1000, }; const response = await apiClient.patch(url, data, customConfig); return response.data; } catch (error) { throw error; } }, // DELETE请求 async delete(url: string, config?: any): Promise { try { const customConfig: CustomAxiosRequestConfig = { ...config, retry: 3, retryDelay: (retryCount) => retryCount * 1000, }; const response = await apiClient.delete(url, customConfig); return response.data; } catch (error) { throw error; } }, // 上传文件 async upload(url: string, formData: FormData, config?: any): Promise { try { const uploadConfig = { headers: { "Content-Type": "multipart/form-data", }, ...config, }; const response = await apiClient.post(url, formData, uploadConfig); return response.data; } catch (error) { throw error; } }, // 并发请求 async all(requests: Promise[]): Promise { try { return await Promise.all(requests); } catch (error) { throw error; } }, }; export default apiService;