import axios from 'axios';
import { message } from 'antd';
import React from 'react';
import stores from '../stores';
/**
* 支持常用的请求方法包括 ['get', 'delete', 'head', 'post', 'put', 'options']
* 对外暴露的实例如下
* 1:HttpClient 满足全局loading样式(需要配合mobx的store管理全局状态)
* 2:HttpClientOnly 满足不展示对应loading
* 3:HttpClientPart 满足局部loading(需要配合mobx的store管理全局状态)
*/
axios.defaults.headers['Cache-Control'] = 'no-store,no-cache,no-transform,must-revalidate,max-age=0';
class BaseHttpClient {
constructor(partName) {
this.partName = partName;
this.methods = ['get', 'delete', 'head', 'post', 'put', 'options'];
this.methods.forEach((item) => {
this[item] = (url, params = {}, headers = {}) => this.commonMethod(item, url, params, headers)
})
}
baseUrl = '';
instance = axios.create({
baseURL: this.baseUrl,
timeout: 20000,
withCredentials: true,
});
commonMethod (method, url, params = {}, headers) {
this.url = url
this.loading && !this.part && stores.gStore.increment();// 增加全局loading状态
this.loading && this.part && stores.gStore.updateLoadingPart(this.partName, true)// 设置局部loading状态
let allParams = [url, { params, ...headers = {} }]
if (['get', 'delete', 'head', 'options'].includes(method)) { // get系请求
allParams = [url, { params, ...headers }]
} else if (['post', 'put'].includes(method)) { // post系请求
allParams = [url, params, headers];
}
return this.instance[method](...allParams)
.then(this.handleSuccessResponse.bind(this))
.catch(this.handleErrorResponse.bind(this))
.finally(() => {
this.loading && !this.part && stores.gStore.reduce();// 减少全局loading()
this.loading && this.part && stores.gStore.updateLoadingPart(this.partName, false)// 删除局部loading状态
});
}
handleSuccessResponse (res) {// 请求成功}
handleErrorResponse (err) { //报错处理}
}
function withLoading (loading, part) {
return (target) => {
// eslint-disable-next-line no-param-reassign
target.prototype.loading = loading; // 是否需要loading
target.prototype.part = part;// 是否需要局部loading
};
}
// 带有拦截器的HttpClient
class HttpClientWithInterceptors extends BaseHttpClient {
constructor() {
super()
this.instance.interceptors.response.use(
(response) => response, // 在这里添加响应的拦截
(error) => {
const originalRequest = error.config
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1 && !originalRequest._retry) {
message.error('查询超时,请稍后重试')
}
},
);
}
}
@withLoading(true)
class HttpClientClass extends HttpClientWithInterceptors { }
@withLoading(true, true)
class HttpClientPartClass extends HttpClientWithInterceptors {
constructor(partName) {
super();
this.partName = partName;
}
}
@withLoading(false)
class HttpClientOnlyClass extends HttpClientWithInterceptors { }
export const HttpClient = new HttpClientClass();
export const HttpClientOnly = new HttpClientOnlyClass();
export const HttpClientPart = (partName) => new HttpClientPartClass(partName);
//---------------------mobx的store------------------------------
// gStore
@observable loadingPart = {}// 存放局部loading的组件标志
@computed get loading() {// 展示全局loading
return this.httpCount !== 0;
}
@action increment() {
this.httpCount += 1;
}
@action reduce() {
this.httpCount -= 1;
}
@action updateLoadingPart = (partName, loading) => {
this.loadingPart[partName] = loading;
}
// -----------------------------------
<Spin spinning={stores.gStore.loading}></Spin>// 全局加载
<Spin spinning={stores.gStore.loadingPart.xxx}></Spin>// 局部加载
网友评论