baseApi.ts
import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios'
import md5 from 'js-md5'
import { Modal, message } from 'antd'
import CookieUtils from '../utils/CookieUtils'
import { MethodType, IResponse } from '../types'
import {
SERVICE_URL,
SERVICE_CODE,
SERVICE_MSG,
SYS_NO_PERMISSION,
SYS_YUNXIN_ERROR,
} from './constant'
import actions from 'src/store/modules/login/actions'
import store from '../store'
const dispatch: any = store.dispatch
// 储存请求标识
const pending: any[] = []
const { CancelToken } = axios
interface IRequest {
method: MethodType,
url: string,
params?: any,
config?: any,
returnAll?: boolean,
/**
* 当请求数据非正常code返回,是否需要默认message提示错误信息,默认提示
*/
errorMessageAlert?: boolean,
errMsg?: string | boolean
}
export default class BaseApi {
$http: AxiosInstance
constructor(axiosConfig = {}) {
this.$http = this.setHttpConfig(axiosConfig)
}
async request(query: IRequest) {
const { method, url, params = {}, config = {}, returnAll = false, errorMessageAlert = true, errMsg } = query
const paramsObj = ['get'].includes(method) ? { params } : { data: params }
const promise = new Promise<any>(async (resolve, reject) => {
try {
await this.checkPassportLoginState()
const result = await this.$http({
method,
url,
...paramsObj,
...config,
})
// 无返回数据
if (!result) {
if (errMsg === false) {
console.log('不提示报错')
} else {
message.error(errMsg || '数据正在路上,请您尝试刷新!')
}
reject()
}
this.checkCodeFunc(result, {
resolve,
reject,
returnAll,
errorMessageAlert,
})
} catch (error) {
// message.error(error+'')
reject(error)
}
})
return promise
}
/**
* 返回数据code处理
*/
checkCodeFunc(result: any, params: any) {
const { resolve, reject, returnAll, errorMessageAlert } = params
const status = result.status.toString().substr(0, 2)
if (['20'].includes(status)) {
const data: any = result.data
const { retCode, retDesc, retData } = data
if (!!retCode && retCode.toString() !== SERVICE_CODE.SUCCESS) {
// 需要重新到选择机器人页面的code
if (
SYS_NO_PERMISSION.includes(retCode.toString())
) {
message.error(retDesc + '')
const login = (store.getState().login as any)
if (login.robotId || login.isFirst) {
dispatch(actions.updateRobotId({
insideBotId: 0,
botName: '',
primaryFlag: 0,
}))
}
reject(result.data)
return
} else if (SYS_YUNXIN_ERROR.includes(retCode.toString())) { // 运行登录错误处理
Modal.error({
title: '提示信息',
content: retDesc,
onOk: () => {
const IWindow: any = window
IWindow.location.reload()
},
})
} else {
if (returnAll) {
resolve(result.data)
}
errorMessageAlert && message.error(retDesc + '')
reject(result.data)
}
} else {
if (returnAll) {
resolve(result.data)
} else {
resolve(retData)
}
}
} else {
// if(result.data&&result.data.retDesc){
// message.error(result.data.retDesc)
// }else{
// message.error(`${result.status}${result.statusText}`)
// }
message.error('系统异常,稍后重试')
reject(result)
}
}
/**
* passport校验登录状态
*/
checkPassportLoginState() {
const iWindow: any = window
return new Promise((resolve, reject) => {
// 接入passport探测登录信息
if (typeof iWindow.probeAuthStatus === 'function') {
// if(this.passportInterval()){
// resolve()
// return
// }
iWindow.probeAuthStatus(
(principal: any) => {
CookieUtils.setCookie('operUser', principal)
resolve()
},
() => {
Modal.error({
title: '提示',
content: '登录超时,请重新登录',
onOk() {
window.location.href = SERVICE_URL.WEB_ROOT
},
})
reject('登录超时,请重新登录!')
}
)
} else {
message.error('passport.js 文件不存在!')
reject('passport.js 文件不存在!')
}
})
}
passportInterval() {
const timeStamp = Number(new Date())
const lastTimeStamp = Number(CookieUtils.getLocalStorage('passportInterval') || 0)
if ((timeStamp - lastTimeStamp) > 60 * 1000) {
CookieUtils.setLocalStorage('passportInterval', timeStamp)
return false
} else {
return true
}
}
/**
* @desc 检查http状态码, 判断http层面调用结果
* @param {*} res
*/
checkStatus(res: AxiosResponse) {
if (res === undefined) {
return {
retCode: SERVICE_CODE.HTTPERROR,
}
} else {
const statusString = res.status + ''
if (statusString.indexOf('20') === 0 || statusString.indexOf('30') === 0) return res.data
return {
retCode: SERVICE_CODE.HTTPERROR,
retDesc: `${res.status} ${res.statusText}!`,
retData: res,
}
}
}
/**
* @desc 检查返回的数据code值,判断业务服务层面调用结果
* @param {*} res
*/
checkCode(res: IResponse<any>) {
const { retCode = SERVICE_CODE.HTTPERROR } = res
const msg = res.retDesc || SERVICE_MSG[retCode]
switch (retCode) {
case SERVICE_CODE.HTTPERROR:
break
default:
break
// case SERVICE_CODE.SYS_AUTH:
// throw new Error(res.retDesc || SERVICE_MSG[retCode])
// break
// case SERVICE_CODE.PAGE_AUTH:
// throw new Error(res.retDesc || SERVICE_MSG[retCode])
// case SERVICE_CODE.OPT_AUTH:
// throw new Error(res.retDesc || SERVICE_MSG[retCode])
// case SERVICE_CODE.SUCCESS:
// return res && res.retData
// default:
// throw new Error(res&&res.retDesc&&SERVICE_MSG[SERVICE_CODE.HTTPERROR])
}
message.warning(msg)
}
/**
* @desc 根据请求的url和method生成hash标识
* @param {String} url
* @param {String} method
*/
hashTag(config: AxiosRequestConfig): string {
return md5(`${config.url}${config.method}`)
}
/**
* @desc 取消未响应的重复请求, 并从记录中移除对应的hash标识
* @param {Object} config
*/
removePending(config: AxiosRequestConfig) {
const currentTag = this.hashTag(config)
pending.forEach((item, index) => {
const { tag, fn } = item
if (currentTag === tag) {
// tslint:disable-next-line: no-unused-expression
return (fn && fn() && pending.splice(index, 1))
}
})
}
// 请求与响应的拦截
setHttpConfig(axiosConfig: any): AxiosInstance {
const $http = axios.create({
baseURL: axiosConfig.baseURL || SERVICE_URL.BASE_API,
timeout: axiosConfig.timeout || 15000,
withCredentials: true,
})
$http.interceptors.request.use(
config => {
// 当headers.insideBotId为空 再去取radux 参数传过来的header优先级高
if (!config.headers.insideBotId) {
let robotId: (string | number) = ''
if (store && store.getState && store.getState().login) {
robotId = (store.getState().login as any).robotId
if (robotId) {
config.headers.insideBotId = robotId
}
}
}
if (config.params) {
this.removePending(config)
const tag = this.hashTag(config)
// eslint-disable-next-line
config.cancelToken = new CancelToken(cancel =>
pending.push({
tag,
fn: cancel,
})
)
}
return config
},
err => {
message.error('请求超时!')
return Promise.reject(err)
}
)
$http.interceptors.response.use(
response => {
return response
},
err => {
return Promise.resolve(err.response)
}
)
return $http
}
}
react项目axios配置
最新推荐文章于 2023-10-19 17:53:37 发布