zhgdlarge/src/api/index.ts
2023-07-12 09:56:31 +08:00

116 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 axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
import { showFullScreenLoading, tryHideFullScreenLoading } from "@/config/serviceLoading";
import { ResultData } from "@/api/interface";
import { ResultEnum } from "@/enums/httpEnum";
import { checkStatus } from "./helper/checkStatus";
import { ElMessage } from "element-plus";
import { GlobalStore } from "@/stores";
import { LOGIN_URL } from "@/config/config";
import router from "@/routers";
// import { useRoute, useRouter } from "vue-router";
// const router = useRouter();
const config = {
// 默认地址请求地址,可在 .env.*** 文件中修改
baseURL: import.meta.env.VITE_API_URL as string,
// baseURL: import.meta.env.NODE_ENV=='development' ?'/api' : window.http,
// 设置超时时间10s
timeout: ResultEnum.TIMEOUT as number,
// 跨域时候允许携带凭证
withCredentials: true
};
class RequestHttp {
service: AxiosInstance;
public constructor(config: AxiosRequestConfig) {
// 实例化axios
this.service = axios.create(config);
/**
* @description 请求拦截器
* 客户端发送请求 -> [请求拦截器] -> 服务器
* token校验(JWT) : 接受服务器返回的token,存储到vuex/pinia/本地储存当中
*/
this.service.interceptors.request.use(
(config: AxiosRequestConfig) => {
const globalStore = GlobalStore();
// * 如果当前请求不需要显示 loading,在 api 服务中通过指定的第三个参数: { headers: { noLoading: true } }来控制不显示loading参见loginApi
config.headers!.noLoading || showFullScreenLoading();
const token = globalStore.token;
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`;
}
return { ...config, headers: { ...config.headers, token } };
},
(error: AxiosError) => {
return Promise.reject(error);
}
);
/**
* @description 响应拦截器
* 服务器换返回信息 -> [拦截统一处理] -> 客户端JS获取到信息
*/
this.service.interceptors.response.use(
(response: AxiosResponse) => {
const { data } = response;
const globalStore = GlobalStore();
// * 在请求结束后,并关闭请求 loading
tryHideFullScreenLoading();
// * 登陆失效code == 401
if (data.code == ResultEnum.OVERDUE) {
ElMessage.error(data.message);
globalStore.resetStore();
return Promise.reject(data);
}
// * 全局错误信息拦截防止下载文件得时候返回数据流没有code直接报错
if (data.code && Number(data.code) !== ResultEnum.SUCCESS) {
ElMessage.error(data.message);
return Promise.reject(data);
}
// * 成功请求(在页面上除非特殊情况,否则不用在页面处理失败逻辑)
return data;
},
async (error: AxiosError) => {
const { response } = error;
const globalStore = GlobalStore();
tryHideFullScreenLoading();
// 请求超时 && 网络错误单独判断,没有 response
if (error.message.indexOf("timeout") !== -1) ElMessage.error("请求超时!请您稍后重试");
if (error.message.indexOf("Network Error") !== -1) ElMessage.error("网络错误!请您稍后重试");
if (error.message.indexOf("Request failed with status code 401") !== -1) {
// ElMessage.error("登录已过期,请重新登录");
globalStore.resetStore();
router.replace(LOGIN_URL);
}
// 根据响应的错误状态码,做不同的处理
// if (response) checkStatus(response.status);
// 根据响应的错误状态码,抛出异常错误信息
if (response) ElMessage.error((response.data as AxiosError).message);
// 服务器结果都没有返回(可能服务器错误可能客户端断网),断网处理:可以跳转到断网页面
if (!window.navigator.onLine) router.replace("/500");
return Promise.reject(error);
}
);
}
// * 常用请求方法封装
get<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
return this.service.get(url, { params, ..._object });
}
post<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
return this.service.post(url, params, _object);
}
put<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
return this.service.put(url, params, _object);
}
delete<T>(url: string, params?: any, _object = {}): Promise<ResultData<T>> {
return this.service.delete(url, { params, ..._object });
}
download(url: string, params?: object, _object = {}): Promise<BlobPart> {
return this.service.post(url, params, { ..._object, responseType: "blob" });
}
}
export default new RequestHttp(config);