request.ts
2.35 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// REQ-USR-004: 统一 Axios 实例 + Result 拆包 + 错误拦截(docs/04 § 2.3 / § 2.4)
import axios, {
AxiosError,
type AxiosInstance,
type InternalAxiosRequestConfig,
} from 'axios';
/** token 持久化键名(D6,跨 task 引用此常量,不写字面量) */
export const TOKEN_STORAGE_KEY = 'xly_erp_token';
/** 网络 / 超时 / 5xx 无可用业务码时的统一标识 */
export const NETWORK_ERROR_CODE = -1;
/** 后端统一响应体 Result<T>(docs/04 § 1.4) */
export interface Result<T = unknown> {
code: number;
message: string;
data: T;
}
/** 业务 / 网络错误,携带后端业务码供页面分流文案 */
export class ApiError extends Error {
code: number;
constructor(code: number, message: string) {
super(message);
this.name = 'ApiError';
this.code = code;
}
}
const request: AxiosInstance = axios.create({
baseURL: '/api',
timeout: 15000,
headers: { 'Content-Type': 'application/json' },
});
// 请求拦截器:已登录态注入 Authorization;登录 / 版本端点无 token 时自然跳过
request.interceptors.request.use((config: InternalAxiosRequestConfig) => {
const token = localStorage.getItem(TOKEN_STORAGE_KEY);
if (token) {
config.headers.set('Authorization', `Bearer ${token}`);
}
return config;
});
// 响应拦截器:拆 Result。code=0 取 data;非 0 抛 ApiError;无响应(网络/超时/5xx)兜底
request.interceptors.response.use(
(response) => {
const body = response.data as Result;
if (body && typeof body === 'object' && 'code' in body) {
if (body.code === 0) {
return body.data;
}
return Promise.reject(new ApiError(body.code, body.message || '请求失败'));
}
// 非 Result 结构(理论上不应出现),原样返回 data
return response.data;
},
(error: AxiosError) => {
// 已是 ApiError 直接透传(极少数情况)
if (error instanceof ApiError) {
return Promise.reject(error);
}
const body = error.response?.data as Result | undefined;
if (body && typeof body === 'object' && 'code' in body) {
return Promise.reject(new ApiError(body.code, body.message || '请求失败'));
}
// 无响应:网络异常 / 超时 / 5xx 无 Result 体
return Promise.reject(new ApiError(NETWORK_ERROR_CODE, '网络异常,请稍后重试'));
},
);
export default request;