You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
3.7 KiB

import axios, { AxiosInstance, AxiosResponse, AxiosError, InternalAxiosRequestConfig } from 'axios';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { API_BASE_URL, API_TIMEOUT, DEFAULT_HEADERS, STORAGE_KEYS } from '../../constants/config';
// 定义响应类型接口
export interface ApiResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: any;
}
// 定义错误类型接口
export interface ApiError {
message: string;
status?: number;
data?: any;
}
// 创建axios实例
const apiClient: AxiosInstance = axios.create({
baseURL: API_BASE_URL,
timeout: API_TIMEOUT,
headers: DEFAULT_HEADERS,
});
// 请求拦截器
apiClient.interceptors.request.use(
async (config: InternalAxiosRequestConfig) => {
// 从AsyncStorage获取token
const token = await AsyncStorage.getItem(STORAGE_KEYS.AUTH_TOKEN);
// 如果token存在,添加到请求头
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error: AxiosError) => {
return Promise.reject(error);
}
);
// 响应拦截器
apiClient.interceptors.response.use(
(response: AxiosResponse) => {
// 成功响应处理
return response;
},
async (error: AxiosError<any>) => {
// 错误响应处理
const { response } = error;
// 处理401错误 (未授权)
if (response && response.status === 401) {
// 清除存储的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<T>(url: string, params?: any, config?: any): Promise<T> {
try {
const response = await apiClient.get<T>(url, { params, ...config });
return response.data;
} catch (error) {
throw error;
}
},
// POST请求
async post<T>(url: string, data?: any, config?: any): Promise<T> {
try {
const response = await apiClient.post<T>(url, data, config);
return response.data;
} catch (error) {
throw error;
}
},
// PUT请求
async put<T>(url: string, data?: any, config?: any): Promise<T> {
try {
const response = await apiClient.put<T>(url, data, config);
return response.data;
} catch (error) {
throw error;
}
},
// PATCH请求
async patch<T>(url: string, data?: any, config?: any): Promise<T> {
try {
const response = await apiClient.patch<T>(url, data, config);
return response.data;
} catch (error) {
throw error;
}
},
// DELETE请求
async delete<T>(url: string, config?: any): Promise<T> {
try {
const response = await apiClient.delete<T>(url, config);
return response.data;
} catch (error) {
throw error;
}
},
// 上传文件
async upload<T>(url: string, formData: FormData, config?: any): Promise<T> {
try {
const uploadConfig = {
headers: {
'Content-Type': 'multipart/form-data',
},
...config,
};
const response = await apiClient.post<T>(url, formData, uploadConfig);
return response.data;
} catch (error) {
throw error;
}
},
// 并发请求
async all<T>(requests: Promise<any>[]): Promise<T[]> {
try {
return await Promise.all(requests);
} catch (error) {
throw error;
}
}
};
export default apiService;