|
|
@@ -1,48 +1,147 @@
|
|
|
-// @/utils/request.ts
|
|
|
-import axios, { type AxiosRequestConfig, type AxiosResponse, isAxiosError } from "axios";
|
|
|
-import router from '@/router';
|
|
|
-import { useTokenStore } from '@/stores/mytoken';
|
|
|
-
|
|
|
-const requestAdmin = axios.create({
|
|
|
- baseURL: import.meta.env.VITE_API_URL,
|
|
|
- timeout: 10000,
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'application/json',
|
|
|
- },
|
|
|
+// src/utils/request.ts
|
|
|
+import axios from 'axios';
|
|
|
+import type {
|
|
|
+ AxiosInstance,
|
|
|
+ AxiosRequestConfig,
|
|
|
+ AxiosResponse,
|
|
|
+ AxiosError,
|
|
|
+ InternalAxiosRequestConfig,
|
|
|
+ AxiosRequestHeaders
|
|
|
+} from 'axios';
|
|
|
+
|
|
|
+// 检测当前环境
|
|
|
+const isDevelopment = import.meta.env.MODE === 'development';
|
|
|
+
|
|
|
+// 定义接口
|
|
|
+interface CustomAxiosInstance extends AxiosInstance {
|
|
|
+ (config: AxiosRequestConfig): Promise<any>;
|
|
|
+}
|
|
|
+
|
|
|
+// 创建API客户端
|
|
|
+export const api5000: CustomAxiosInstance = axios.create({
|
|
|
+ baseURL: isDevelopment
|
|
|
+ ? 'http://localhost:5000'
|
|
|
+ : 'https://www.soilgd.com:5000',
|
|
|
+ timeout: 100000,
|
|
|
+ withCredentials: false // 关键修改:除非需要cookie,否则设为false
|
|
|
+});
|
|
|
+
|
|
|
+export const api8000: CustomAxiosInstance = axios.create({
|
|
|
+ baseURL: isDevelopment
|
|
|
+ ? 'http://localhost:8000'
|
|
|
+ : 'https://www.soilgd.com:8000',
|
|
|
+ timeout: 100000,
|
|
|
+ withCredentials: true
|
|
|
+});
|
|
|
+
|
|
|
+export const apiMain: CustomAxiosInstance = axios.create({
|
|
|
+ baseURL: isDevelopment
|
|
|
+ ? 'http://localhost'
|
|
|
+ : 'https://www.soilgd.com',
|
|
|
+ timeout: 100000,
|
|
|
+ withCredentials: true
|
|
|
});
|
|
|
|
|
|
-requestAdmin.interceptors.request.use(
|
|
|
- (config) => {
|
|
|
- console.log('Starting Request', config);
|
|
|
- return config;
|
|
|
- },
|
|
|
- (error: unknown) => {
|
|
|
- console.error('Request error:', error);
|
|
|
- return Promise.reject(error);
|
|
|
- }
|
|
|
-);
|
|
|
-
|
|
|
-requestAdmin.interceptors.response.use(
|
|
|
- (response: AxiosResponse) => response,
|
|
|
- async (error: unknown) => {
|
|
|
- if (isAxiosError(error)) {
|
|
|
- console.error('Response error:', error.message);
|
|
|
- if (error.response && error.response.status === 401) {
|
|
|
- const tokenStore = useTokenStore();
|
|
|
- tokenStore.clearToken();
|
|
|
- router.push('/login');
|
|
|
+
|
|
|
+// 检查是否为GeoJSON响应
|
|
|
+function isGeoJSONResponse(response: AxiosResponse): boolean {
|
|
|
+ const contentType = response.headers['content-type'] || '';
|
|
|
+ return (
|
|
|
+ contentType.includes('application/geo+json') ||
|
|
|
+ (contentType.includes('application/json') &&
|
|
|
+ (response.data?.type === 'FeatureCollection' ||
|
|
|
+ response.data?.type === 'Feature'))
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const setupInterceptors = (instance: CustomAxiosInstance) => {
|
|
|
+ // 请求拦截器
|
|
|
+ instance.interceptors.request.use(
|
|
|
+ (config: InternalAxiosRequestConfig) => {
|
|
|
+ const token = localStorage.getItem('token');
|
|
|
+ if (token) {
|
|
|
+ // 使用新的headers API
|
|
|
+ if (!config.headers) {
|
|
|
+ config.headers = new axios.AxiosHeaders();
|
|
|
+ }
|
|
|
+ config.headers.set('Authorization', `Bearer ${token}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 为GeoJSON请求设置Accept头
|
|
|
+ if (config.url?.match(/\/geojson|\/vector/i)) {
|
|
|
+ if (!config.headers) {
|
|
|
+ config.headers = new axios.AxiosHeaders();
|
|
|
+ }
|
|
|
+ config.headers.set('Accept', 'application/geo+json, application/json');
|
|
|
+
|
|
|
+ // 为GeoJSON请求设置更长的超时时间
|
|
|
+ if (!config.timeout || config.timeout < 180000) {
|
|
|
+ config.timeout = 180000; // 3分钟
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return config;
|
|
|
+ },
|
|
|
+ (error: AxiosError) => Promise.reject(error)
|
|
|
+ );
|
|
|
+
|
|
|
+ // 响应拦截器
|
|
|
+ instance.interceptors.response.use(
|
|
|
+ (response: AxiosResponse) => {
|
|
|
+ // 根据响应类型和内容类型决定如何处理
|
|
|
+ const contentType = response.headers['content-type'] || '';
|
|
|
+ const isBlob = response.config.responseType === 'blob';
|
|
|
+ const isImage = contentType.includes('image/');
|
|
|
+ const isJSON = contentType.includes('application/json');
|
|
|
+
|
|
|
+ console.log('响应处理:', {
|
|
|
+ url: response.config.url,
|
|
|
+ responseType: response.config.responseType,
|
|
|
+ contentType,
|
|
|
+ isBlob,
|
|
|
+ isImage,
|
|
|
+ isJSON
|
|
|
+ });
|
|
|
+
|
|
|
+ // 1. 处理二进制响应(图片/文件下载)
|
|
|
+ if (isBlob || isImage) {
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 处理GeoJSON响应(新增部分)
|
|
|
+ if (isGeoJSONResponse(response)) {
|
|
|
+ console.log('检测到GeoJSON响应,返回完整响应对象');
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 处理普通JSON响应
|
|
|
+ if (isJSON) {
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 其他类型响应
|
|
|
+ return response;
|
|
|
+ },
|
|
|
+ (error: AxiosError) => {
|
|
|
+ if (error.response?.status === 401) {
|
|
|
+ localStorage.removeItem('token');
|
|
|
+ window.location.href = '/login';
|
|
|
}
|
|
|
- } else {
|
|
|
- console.error('Non-Axios error:', error);
|
|
|
+ return Promise.reject(error);
|
|
|
}
|
|
|
- return Promise.reject(error);
|
|
|
- }
|
|
|
-);
|
|
|
+ );
|
|
|
|
|
|
-console.log('Base URL:', requestAdmin.defaults.baseURL);
|
|
|
+ return instance;
|
|
|
+};
|
|
|
|
|
|
-// ✅ 改为默认导出
|
|
|
-export default requestAdmin; // 👈 修改这里
|
|
|
+// 设置拦截器
|
|
|
+setupInterceptors(api5000);
|
|
|
+setupInterceptors(api8000);
|
|
|
+setupInterceptors(apiMain);
|
|
|
|
|
|
-// ❌ 移除或注释掉原来的命名导出
|
|
|
-// export { requestAdmin };
|
|
|
+// 导出所有API客户端
|
|
|
+export default {
|
|
|
+ api5000,
|
|
|
+ api8000,
|
|
|
+ apiMain
|
|
|
+};
|