react项目axios配置

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
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值