import axios from 'axios' import { Message, MessageBox, Loading } from 'element-ui' import Vue from 'vue' import store from '../store' import errorCode from '@/utils/errorCode' import { codeHeaders, encryptBody } from './sm' // 是否显示重新登录 let isReloginShow // 创建axios实例 const service = axios.create({ timeout: 120000, withCredentials: true }) let loading = null /** * loading开始时 * @param {*} config */ function startLoading(config) { loading = Loading.service({ target: '.loading-mask', lock: true, text: '加载中……', customClass: 'customLoading' // background: 'rgba(0, 0, 0, 0.7)' }) } /** * loading结束时 */ function endLoading() { loading.close() } let needLoadingRequestCount = 0 export function showFullScreenLoading(config) { if (!config.showLoading && !config[0]) { return } if (needLoadingRequestCount === 0) { startLoading(config) } needLoadingRequestCount++ } export function tryHideFullScreenLoading() { if (needLoadingRequestCount <= 0) return needLoadingRequestCount-- if (needLoadingRequestCount === 0) { endLoading() } } // request拦截器 service.interceptors.request.use((config) => { config.baseURL = process.env.VUE_APP_CURRENTMODE === 'development' ? '/api' : window.API_BASE_URL // 如果没有设置Content-Type,默认application/json if (!config.headers['Content-Type']) { config.headers['Content-Type'] = 'application/json' } // 方法做防重返和防篡改 if (process.env.VUE_APP_ENCRYPTION === '1') { config = codeHeaders(config) config = encryptBody(config) } // 每次发送请求之前判断vuex中是否存在token // 如果存在,则统一在http请求的header都加上token const token = store.state.token // const token = 'a71a73f84475dcb3c61dbd9c4905858f' if (token) { config.headers.Authorization = 'Bearer ' + token } config.headers.bizId = 'B02' showFullScreenLoading(config) return config }, (error) => { Promise.reject(error) tryHideFullScreenLoading() }) // respone拦截器 service.interceptors.response.use((res) => { const code = res.data.code ? String(res.data.code) : '0' // 获取错误信息 const msg = errorCode[code] || res.data.msg || res.data.message || errorCode.default tryHideFullScreenLoading() // 二进制数据则直接返回 if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { return res.data } if (code === '401' || code === '4001' || code === '4000') { if (!isReloginShow) { isReloginShow = true MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { isReloginShow = false Vue.prototype.$mainStore.commit('logout') Vue.prototype.$mainRouter.replace('/') }).catch(() => { isReloginShow = false }) } const msg = '无效的会话,或者会话已过期,请重新登录。' return Promise.reject(msg) } else if (code === '999') { //token过期 Message.warning('认证 token 已过期,请重新登录') Vue.prototype.$mainStore.commit('logout'); Vue.prototype.$mainRouter.replace('/'); } else if (code === '500') { Message({ message: msg, type: 'error' }) return Promise.reject(msg) } else if (code !== '0') { Message.warning(msg) return Promise.reject(msg) } else { return res.data } }, (error) => { let { message } = error tryHideFullScreenLoading() if (message === 'Network Error') { message = '后端接口连接异常' } else if (message.includes('timeout')) { message = '系统接口请求超时' } else { message = error.response.data.error_description || error.response.data.message } message && Message({ message: message, type: 'error', duration: 3 * 1000 }) switch (String(error.response.data.status)) { case '401': Vue.prototype.$mainStore.dispatch('clearLoginInfo') Vue.prototype.$mainRouter.replace('/') break case '403': Vue.prototype.$mainRouter.push({ name: '404' }) break } return Promise.reject(error) }) export default service