client.ts
1.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import axios, { AxiosError, AxiosResponse } from 'axios';
import { BizError } from './errors';
let getAccessToken: () => string | null = () => null;
/**
* 注册 token 提供者。Redux store 初始化后由 store/index.ts 调用,
* 把 store.getState().auth.accessToken 接进来。
* 避免直接 import store 形成循环依赖。
*/
export function registerAccessTokenProvider(fn: () => string | null) {
getAccessToken = fn;
}
export const apiClient = axios.create({
baseURL: (import.meta as any).env?.VITE_API_BASE_URL ?? '/api/v1',
timeout: 10000,
});
apiClient.interceptors.request.use((config) => {
const token = getAccessToken();
if (token) {
config.headers.set('Authorization', `Bearer ${token}`);
}
return config;
});
apiClient.interceptors.response.use(
(response: AxiosResponse) => {
const body = response.data;
if (body && typeof body === 'object' && 'code' in body) {
if (body.code === 200) {
return body.data;
}
throw new BizError(body.code, body.message ?? '业务错误', body.data);
}
return body;
},
(error: AxiosError) => {
if (error.response) {
const body = error.response.data as { code?: number; message?: string; data?: unknown } | undefined;
if (body && typeof body === 'object' && 'code' in body) {
throw new BizError(body.code!, body.message ?? '请求失败', body.data);
}
throw new BizError(error.response.status, error.response.statusText ?? 'HTTP error');
}
throw new BizError(-1, 'NETWORK');
},
);