wanshenmean
2026-03-06 a487bb99a6133fb044ce94f23f78ee89a2a6402d
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import { message } from 'ant-design-vue';
import { getToken, setToken, clearAuth } from './auth';
import router from '../router';
 
// 创建 axios 实例
const service: AxiosInstance = axios.create({
  baseURL: '/api',
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8',
  },
});
 
// 请求拦截器
service.interceptors.request.use(
  (config: any) => {
    // 添加 Token 到请求头
    const token = getToken();
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
 
    // 确保 POST 请求的数据被正确序列化为 JSON
    if (config.method === 'post' && config.data) {
      // 如果 data 不是 FormData,确保它是 JSON 字符串
      if (!(config.data instanceof FormData)) {
        config.headers['Content-Type'] = 'application/json;charset=UTF-8';
        // axios 会自动将对象转换为 JSON,但我们确保 Content-Type 正确
      }
    }
 
    // 开发环境下打印请求信息
    if (import.meta.env.DEV) {
      console.log('Request:', {
        url: config.url,
        method: config.method,
        data: config.data,
        headers: config.headers,
      });
    }
 
    return config;
  },
  (error: AxiosError) => {
    console.error('Request error:', error);
    return Promise.reject(error);
  }
);
 
// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    // 检查是否需要刷新 Token
    const expHeader = response.headers['widesea_exp'];
    if (expHeader === '1') {
      // Token 即将过期,刷新 Token
      refreshToken();
    }
 
    const res = response.data;
 
    // 如果响应状态不是 true,显示错误消息
    if (res.status === false) {
      message.error(res.message || '请求失败');
      return Promise.reject(new Error(res.message || '请求失败'));
    }
 
    return res;
  },
  (error: AxiosError) => {
    console.error('Response error:', error);
 
    if (error.response) {
      const status = error.response.status;
 
      switch (status) {
        case 401:
          // 未认证,清除 Token 并跳转到登录页
          message.error('登录已过期,请重新登录');
          clearAuth();
          router.push('/login');
          break;
        case 403:
          message.error('没有权限访问该资源');
          break;
        case 404:
          message.error('请求的资源不存在');
          break;
        case 500:
          message.error('服务器错误');
          break;
        default:
          message.error(error.message || '请求失败');
      }
    } else {
      message.error('网络错误,请检查网络连接');
    }
 
    return Promise.reject(error);
  }
);
 
/**
 * 刷新 Token
 */
async function refreshToken() {
  try {
    const token = getToken();
    if (!token) return;
 
    const response = await axios.post(
      '/api/User/replaceToken',
      { token },
      {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      }
    );
 
    if (response.data.status && response.data.data) {
      setToken(response.data.data);
    }
  } catch (error) {
    console.error('Token refresh failed:', error);
  }
}
 
export default service;