import axios from 'axios' import {Message} from 'element-ui' import {Loading} from 'element-ui' import $store from '@/store' import store from '@/store/login' import tenant from '@/store/tenant' import router from '@/router.js' import NProgress from 'nprogress' import utils from '@/hotent-ui-util.js' import 'nprogress/nprogress.css' import {saveAs} from 'file-saver' axios.defaults.timeout = 100000 let pending = [] //声明一个数组用于存储每个ajax请求的取消函数和ajax标识 let cancelToken = axios.CancelToken let removePending = (ever) => { for (let p in pending) { if ( pending[p].u === ever.url + '&' + ever.method && pending[p].data === eval.data ) { //当当前请求在数组中存在时执行函数体 pending[p].f() //执行取消操作 pending.splice(p, 1) //把这条记录从数组中移除 } } } let dealError = (error) => { NProgress.done() // 结束 return Promise.reject(error) } Message.errorLog = function (obj, logId) { if (typeof obj == 'string' && logId) { let msg = obj let log = `【日志ID:${logId}】` Message({ type: 'error', message: `
${msg}
${log}
`, dangerouslyUseHTMLString: true, }) } else { Message({ type: 'error', message: obj, dangerouslyUseHTMLString: true, }) } } // 请求拦截(配置发送请求的信息) axios.interceptors.request.use( (config) => { // 处理请求之前的配置 NProgress.start() //开始 store.state.loadding = true //在请求发出之前进行一些操作 config.headers = config.headers || {} if (config.headers && config.headers.constructor == String) { try { config.headers = JSON.parse(config.headers) } catch (e) { Message.error(`请求头部不是有效的JSON格式:${config.headers}`) throw e } } config.headers['Accept-Language'] = localStorage.getItem('lang') || 'zh-CN' if (store.state.loginAccount) { try { config.headers['Tenant-Code'] = localStorage .getItem(store.state.loginAccount + 'manageLoginRoutePath') .replace('/login/', '') || '' } catch (e) { Message.error('请重新登陆系统') } } const currentUser = store.state.currentUser currentUser && currentUser.token && !config.headers.Authorization && (config.headers.Authorization = `Bearer ${currentUser.token}`) if (tenant.state.tenantId && config.url.indexOf('tenantId=') == -1) { let joinChar = '?' if (config.url.indexOf('?') != -1) { joinChar = '&' } config.url = config.url + joinChar + 'tenantId=' + tenant.state.tenantId } //如果是请求auth接口,则不带token if (config.url.indexOf('/auth?') != -1) { delete config.headers.Authorization } removePending(config) //在一个ajax发送前执行一下取消操作 config.cancelToken = new cancelToken((c) => { // 将请求的地址和请求的方式构建为一个字符串存放到请求数组中 pending.push({ u: config.url + '&' + config.method, f: c, data: config.data, }) }) // 判断是否需要刷新token let currentTime = new Date().getTime() if ( currentUser && currentUser.loginTime && currentTime - currentUser.loginTime >= (currentUser.expiration / 5) * 1000 && config.url.indexOf('/refresh') == -1 ) { $store.dispatch('login/refreshAndGetAuthenticationToken') } return config }, (error) => { // 请求失败的处理 NProgress.done() // 结束 return Promise.reject(error) } ) // 响应拦截(配置请求回来的信息) axios.interceptors.response.use( (res) => { // 处理响应数据 removePending(res.config) //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除 if ( res.data && res.data.state != undefined && res.data.state === false && !res.data.message.includes('以下布局重复,是否覆盖更新') ) { if ( res.data.code == '401' && ['4016', '4017'].includes(res.data.errorCode) ) { window.location.href = '/login' } if (['10001'].includes(res.data.errorCode)) { //警告提示信息错误码 Message.warning(res.data.message) } else if ( !( ['2002', '2001'].includes(res.data.errorCode) && (res.config.url.indexOf('auth?tenantId=') != -1 || res.config.url.indexOf('twoStepVerifyAndBind') != -1) ) ) { Message.errorLog(res.data.message, res.data.logId) } } store.state.loadding = false //在这里对返回的数据进行处理 NProgress.done() // 结束 // 附件下载 if ( res && res.status == 200 && res.headers && res.headers['content-disposition'] && res.headers['content-disposition'].startsWith('attachment;') ) { let blob = new Blob([res.data]) const fileName = decodeURIComponent( res.headers['content-disposition'].split(';')[1].split('filename=')[1] ) saveAs(blob, fileName) } return res }, (error) => { // 处理响应失败 if ( error.response.config.url.includes('portal/sysApp/v1/export') || (error.response.config.url.includes('portal/sysApp/v1/import') && !error.response.config.url.includes('portal/sysApp/v1/importCheck')) ) { return dealError(error) } let loadingInstance = Loading.service({fullscreen: true}) //开始 const errorMessage = error && error.response && error.response.data && error.response.data.message ? error.response.data.message : error.message if (error && error.response && error.response.status === 401) { sessionStorage.clear() if (window.ssoConfig.mode != 'cas' && window.ssoConfig.mode != 'oauth') { router.push({ path: localStorage.getItem('manageLoginRoutePath') || '/login', }) } } else if (error && error.response && error.response.status === 403) { if (error && error.response && error.response.data) { Message.errorLog(errorMessage, error.response.data.logId) } else { Message.error(errorMessage) } } else if (error && error.response && error.response.status === 500) { if (error.response.config.url.indexOf('saveForm') == -1) { //设计表单页面-控件没有绑定属性,点击保存后会有多个提示 if (error.response.data && error.response.data.message) { Message.errorLog( error.response.data.message, error.response.data.logId ) } else if (error.response.config.url.indexOf('getFileById') != -1) { Message.error('附件不存在') } else if ( error.response.config.url.indexOf( 'downloadDefaultExportTempByFormKey' ) != -1 ) { NProgress.done() // 结束 loadingInstance.close() // 结束 return Promise.reject(error) } else { Message.error(error.message) } } } else if ( error && error.isAxiosError && error.response && error.response.status != 403 ) { Message.error(errorMessage) } else if (errorMessage && typeof errorMessage != 'undefined') { Message.error(errorMessage) } NProgress.done() // 结束 loadingInstance.close() // 结束 return Promise.reject(error) } ) export default { request(data) { let reqData = data.data || {} //支持表达式作为域名解析 data.url = utils.parseUrl(data.url) //统一拼接域名接口 if (data.url.indexOf('http') == -1) { data.url = context.manage + data.url } let requestData = { url: data.url, data: reqData, method: data.method || 'GET', params: data.params || {}, onUploadProgress: data.onUploadProgress || null, headers: data.headers || '', responseType: data.responseType || 'json', timeout: data.timeout || axios.defaults.timeout, } return axios(requestData) }, download(url) { return this.request({url, responseType: 'arraybuffer'}) }, get(url, type) { return this.request({url, responseType: type}) }, post(url, data, params, responseType) { return this.request({ url, data, params, method: 'POST', responseType: responseType, }) }, remove(url) { return this.request({url, method: 'DELETE'}) }, put(url, data, params, responseType) { return this.request({ url, data, params, method: 'PUT', responseType: responseType, }) }, getContext() { return context }, }