// services/http.ts
import axios, {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
AxiosError,
} from 'axios';
import { BaseResponse, RequestConfig } from '../types/http';
import { Alert, DeviceEventEmitter } from 'react-native';
import LocalStorage from '@/service/LocalStorage.ts';
import { tokenType } from '@/types/auth.ts';
import AuthService from '@/service/AuthService';
import { config } from './config';
import AuthStorageService from '@/service/AuthStorageService';
class HttpService {
private authStorage = AuthStorageService.getInstance();
private static instance: HttpService;
private axiosInstance: AxiosInstance;
private baseURL: string = 'http://cwsw.xathinksoft.com:30000'; // 替换为你的API基础地址
private isRefreshing = false; // 是否正在重新登录
private failedQueue: Array<{
resolve: (value: any) => void;
reject: (error: any) => void;
}> = []; // 请求队列
private constructor() {
this.axiosInstance = axios.create({
baseURL: this.baseURL,
timeout: 10000000 * 60, // 60秒超时
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
this.setupInterceptors();
}
public static getInstance(): HttpService {
if (!HttpService.instance) {
HttpService.instance = new HttpService();
}
return HttpService.instance;
}
// 设置拦截器
private setupInterceptors(): void {
// 请求拦截器
this.axiosInstance.interceptors.request.use(
// @ts-ignore
async (config: AxiosRequestConfig) => {
// 可以在这里添加全局请求逻辑,例如添加token
const token: tokenType | null = await LocalStorage.getItem<tokenType>(
'token',
);
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token?.access_token}`
}
// 如果需要显示加载提示
if ((config as RequestConfig).showLoading) {
// 这里可以添加加载提示逻辑
console.log('显示加载提示');
}
return config;
},
(error: AxiosError) => {
return Promise.reject(error);
},
);
// 响应拦截器
this.axiosInstance.interceptors.response.use(
(response: AxiosResponse<any>) => {
console.log('响应拦截器', response);
// 隐藏加载提示
if ((response.config as RequestConfig).showLoading) {
console.log('隐藏加载提示');
}
if (response.data?.code === 600) {
// navigator.navigate('Login');
return this.handleTokenExpired(response);
}
if (response.data && typeof response.data.success !== 'undefined') {
// 处理响应数据
if (response.data.success) {
return response.data;
} else {
// 业务逻辑错误
this.handleBusinessError(
response.data,
response.config as RequestConfig,
);
return Promise.reject(response.data);
}
}
return response.data;
},
(error: AxiosError) => {
console.log('响应拦截器', error);
// 隐藏加载提示
if (error.config && (error.config as RequestConfig).showLoading) {
console.log('隐藏加载提示');
}
// 处理HTTP错误
this.handleHttpError(error, error.config as RequestConfig);
return Promise.reject(error);
},
);
}
// 处理 Token 过期
private async handleTokenExpired(response: AxiosResponse): Promise<any> {
const originalRequest = response.config as any;
// 如果正在重新登录,将请求加入队列
if (this.isRefreshing) {
return new Promise((resolve, reject) => {
this.failedQueue.push({ resolve, reject });
})
.then((newToken) => {
if (originalRequest.headers) {
originalRequest.headers.Authorization = `Bearer ${newToken}`;
}
return this.axiosInstance(originalRequest);
})
.catch((err) => {
return Promise.reject(err);
});
}
this.isRefreshing = true;
try {
// 调用登录接口刷新 Token
const newToken = await this.refreshTokenByLogin();
console.log('✅ Token 刷新成功');
// 更新原始请求的 Authorization header
if (originalRequest.headers) {
originalRequest.headers.Authorization = `Bearer ${newToken}`;
}
// 重试原始请求
const retryResponse = await this.axiosInstance(originalRequest);
// 处理队列中的请求
this.processQueue(null, newToken);
console.log('retryResponse', retryResponse)
return retryResponse;
} catch (error) {
// 重新登录失败
this.processQueue(error, null);
await this.handleLoginFailed();
return Promise.reject(response.data);
} finally {
this.isRefreshing = false;
this.failedQueue = [];
}
}
// 通过登录接口刷新 Token
private async refreshTokenByLogin(): Promise<string> {
try {
// 获取保存的登录凭据
const credentials = AuthService.getCurrentUser();
if (!credentials) {
throw new Error('没有找到登录信息');
}
console.log('44444444🔄 自动重新登录中...', credentials);
// 调用登录接口
const loginResponse = await http.get(
`${config.loginApi}?loginName=${credentials.LoginName}&password=${credentials.Phone}&tenant=cw1203`,
);
console.log('loginResponse', loginResponse)
if (loginResponse.Status && loginResponse.Data) {
await this.authStorage.saveLoginResponse(loginResponse.Data);
await LocalStorage.setItem<tokenType>('token', loginResponse.Data.Token);
return loginResponse?.Data?.Token?.access_token;
} else {
throw new Error(loginResponse.data.message || '登录失败');
}
} catch (error: any) {
console.error('❌ 自动重新登录失败:', error);
throw new Error(`自动重新登录失败: ${error.message}`);
}
}
// 处理请求队列
private processQueue(error: any, token: string | null): void {
this.failedQueue.forEach(({ resolve, reject }) => {
if (error) {
reject(error);
} else {
resolve(token);
}
});
}
// 处理登录失败
private async handleLoginFailed(): Promise<void> {
console.log('❌ 自动重新登录失败,需要手动登录');
// 清除本地存储的认证信息
await LocalStorage.removeItem('token');
// 发出全局事件,通知需要手动登录
DeviceEventEmitter.emit('LOGIN_REQUIRED', {
message: '登录已过期,请重新登录',
timestamp: Date.now(),
});
}
// 处理业务逻辑错误
private handleBusinessError(
errorData: BaseResponse,
config?: RequestConfig,
): void {
const { showError = true, customErrorHandler } = config || {};
if (customErrorHandler) {
customErrorHandler(errorData);
return;
}
if (showError) {
Alert.alert('操作失败', errorData.message || '未知错误');
}
}
// 处理HTTP错误
private handleHttpError(error: AxiosError, config?: RequestConfig): void {
const { showError = true, customErrorHandler } = config || {};
if (customErrorHandler) {
customErrorHandler(error);
return;
}
if (!showError) return;
let errorMessage = '网络请求失败';
if (error.response) {
// 服务器返回了响应,但状态码不在2xx范围内
switch (error.response.status) {
case 401:
errorMessage = '未授权,请重新登录';
// 可以在这里处理token过期逻辑
break;
case 403:
errorMessage = '拒绝访问';
break;
case 404:
errorMessage = '请求的资源不存在';
break;
case 500:
errorMessage = '服务器错误';
break;
default:
errorMessage = `服务器错误: ${error.response.status}`;
}
} else if (error.request) {
// 请求已发出,但没有收到响应
errorMessage = '网络连接超时,请检查网络设置';
} else {
// 请求配置出错
errorMessage = '请求配置错误';
}
Alert.alert('错误', errorMessage);
}
// 通用请求方法
public async request<T = any>(config: RequestConfig): Promise<T> {
try {
return await this.axiosInstance.request(config);
} catch (error) {
throw error;
}
}
// GET请求
public async get<T = any>(
url: string,
params?: any,
config?: Omit<RequestConfig, 'url' | 'params' | 'method'>,
): Promise<T> {
return this.request<T>({
url,
method: 'GET',
params,
...config,
});
}
// POST请求
public async post<T = any>(
url: string,
data?: any,
config?: Omit<RequestConfig, 'url' | 'data' | 'method'>,
): Promise<T> {
return this.request<T>({
url,
method: 'POST',
data,
...config,
});
}
// PUT请求
public async put<T = any>(
url: string,
data?: any,
config?: Omit<RequestConfig, 'url' | 'data' | 'method'>,
): Promise<T> {
return this.request<T>({
url,
method: 'PUT',
data,
...config,
});
}
// DELETE请求
public async delete<T = any>(
url: string,
params?: any,
config?: Omit<RequestConfig, 'url' | 'params' | 'method'>,
): Promise<T> {
return this.request<T>({
url,
method: 'DELETE',
params,
...config,
});
}
// PATCH请求
public async patch<T = any>(
url: string,
data?: any,
config?: Omit<RequestConfig, 'url' | 'data' | 'method'>,
): Promise<T> {
return this.request<T>({
url,
method: 'PATCH',
data,
...config,
});
}
}
export const http = HttpService.getInstance();
按上面的写了 发现 没获取到数据(上面已经是正确的代码)

最后调试发现是:

最开始代码写的是 return retryResponse.data
因为这里已经返回的是 retryResponse.data 的数据, 直接return retryResponse即可
改为调试的结果为: ---就不会报错了

遇见问题不要怕 ,耐心分析