|
|
|
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) => {
|
|
|
|
const fullUrl = `${config.baseURL}${config.url}`;
|
|
|
|
console.log("完整请求地址:", fullUrl); // 例如: https://api.example.com/api/user
|
|
|
|
|
|
|
|
// 从AsyncStorage获取token
|
|
|
|
const token = await AsyncStorage.getItem("token");
|
|
|
|
// 如果token存在,添加到请求头
|
|
|
|
if (token && config.headers) {
|
|
|
|
config.headers.Authorization = `${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;
|