Files
TERES_web_frontend/src/utils/request.ts
guangfei.zhao 7384ae36d0 feat(knowledge): add knowledge base detail page components and hooks
refactor(knowledge): restructure knowledge detail page with new components
feat(components): add FileUploadDialog for file upload functionality
feat(hooks): implement document management hooks for CRUD operations
2025-10-14 15:42:40 +08:00

174 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Authorization } from '@/constants/authorization';
import type { ResponseType } from '@/interfaces/database/base';
import i18n from '@/locales';
import axios from 'axios';
import type { AxiosRequestConfig, AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { snackbar, notification } from '@/utils/snackbarInstance';
const FAILED_TO_FETCH = 'Failed to fetch';
export const RetcodeMessage = {
200: i18n.t('message.200'),
201: i18n.t('message.201'),
202: i18n.t('message.202'),
204: i18n.t('message.204'),
400: i18n.t('message.400'),
401: i18n.t('message.401'),
403: i18n.t('message.403'),
404: i18n.t('message.404'),
406: i18n.t('message.406'),
410: i18n.t('message.410'),
413: i18n.t('message.413'),
422: i18n.t('message.422'),
500: i18n.t('message.500'),
502: i18n.t('message.502'),
503: i18n.t('message.503'),
504: i18n.t('message.504'),
};
export type ResultCode =
| 200
| 201
| 202
| 204
| 400
| 401
| 403
| 404
| 406
| 410
| 413
| 422
| 500
| 502
| 503
| 504;
// 获取授权token
const getAuthorization = (): string => {
return localStorage.getItem(Authorization) || '';
};
// 重定向到登录页
const redirectToLogin = (): void => {
localStorage.removeItem(Authorization);
window.location.href = '/login';
};
// 转换对象键为snake_case
const convertTheKeysOfTheObjectToSnake = (obj: any): any => {
if (!obj || typeof obj !== 'object') return obj;
if (Array.isArray(obj)) {
return obj.map(convertTheKeysOfTheObjectToSnake);
}
const result: any = {};
Object.keys(obj).forEach(key => {
const snakeKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
result[snakeKey] = convertTheKeysOfTheObjectToSnake(obj[key]);
});
return result;
};
// 创建axios实例
const request: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 300000,
headers: {
'Content-Type': 'application/json',
},
});
// 请求拦截器
request.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 转换数据格式 - 跳过FormData对象
if (config.data && !(config.data instanceof FormData)) {
config.data = convertTheKeysOfTheObjectToSnake(config.data);
}
if (config.params) {
config.params = convertTheKeysOfTheObjectToSnake(config.params);
}
// 对于FormData删除默认的Content-Type让浏览器自动设置
if (config.data instanceof FormData) {
delete config.headers['Content-Type'];
}
// 添加授权头
const authorization = getAuthorization();
if (authorization && !config.headers?.skipToken) {
config.headers.Authorization = authorization;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器
request.interceptors.response.use(
(response: AxiosResponse) => {
const { status } = response;
// 处理特定状态码
if (status === 413 || status === 504) {
snackbar.error(RetcodeMessage[status as ResultCode]);
}
// 处理blob类型响应
if (response.config.responseType === 'blob') {
return response;
}
console.log('interceptors.response ------ response', response);
const data: ResponseType = response.data;
// 处理业务错误码
if (data?.code === 100) {
snackbar.error(data?.message);
} else if (data?.code === 401) {
notification.error(data?.message);
redirectToLogin();
} else if (data?.code !== 0) {
notification.error(`${i18n.t('message.hint')} : ${data?.code}`, data?.message);
}
return response;
},
(error) => {
// 处理网络错误
if (error.message === FAILED_TO_FETCH || !error.response) {
notification.error(i18n.t('message.networkAnomaly'), i18n.t('message.networkAnomalyDescription'));
} else if (error.response) {
const { status, statusText } = error.response;
const errorText = RetcodeMessage[status as ResultCode] || statusText;
notification.error(`${i18n.t('message.requestError')} ${status}`, errorText);
}
return Promise.reject(error);
}
);
export default request;
// 便捷方法
export const get = (url: string, config?: AxiosRequestConfig) => {
return request.get(url, config);
};
export const post = (url: string, data?: any, config?: AxiosRequestConfig) => {
return request.post(url, data, config);
};
export const put = (url: string, data?: any, config?: AxiosRequestConfig) => {
return request.put(url, data, config);
};
export const del = (url: string, config?: AxiosRequestConfig) => {
return request.delete(url, config);
};