import axios from 'axios'; import store from '@/store' import { getToken } from '@/utils/token'; import { DES3 } from '@/utils/3des'; import router from '@/router/index' import { ElMessage } from '../utils/message.js' import { Caegw_ProUrl,Caegw_LogUrl } from '@/settings' ;// 引入settings.js let Message = new ElMessage() const requestList = []; // 请求列表 const CancelToken = axios.CancelToken; let sources = {}; let successCode = '000000000' | '0000000';//成功编码 //axios配置 //全局的 axios 默认值:指定将被用在各个请求的配置默认值 axios.defaults.timeout = 20000;//设置超时时间 axios.defaults.baseURL = import.meta.env.VITE_BASE_URL;// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL //axios.defaults.headers.common['Authorization'] = AUT202H_TOKEN;//根据项目需要配置 //axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';//设置请求头的类型 axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';//设置请求头的类型 // 添加请求拦截器 axios.interceptors.request.use(config => { const request = JSON.stringify(config.url) + (!!config.data ? JSON.stringify(config.data) : JSON.stringify(config.params)) config.cancelToken = new CancelToken((cancel) => { sources[request] = cancel }) //判断请求是否已存在请求列表,避免重复请求,将当前请求添加进请求列表数组; if (requestList.includes(request)) { // console.log(request) // sources[request]('取消重复请求') // requestList.splice(requestList.findIndex(item => item === request), 1) requestList.push(request) } else { requestList.push(request) } //因本项目部分请求需要重复获取所以不用去重 // requestList.push(request) // 登录控制中根据本地是否存在token判断用户的登录情况, // 但即使token存在,也有可能token是过期的,所以在每次的请求头中携带token, // 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码, // 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。 //本项目不用请求头判断而是在报文体中发送token // let token = store.getters.token || getToken(); // token && (config.headers.Authorization = token); return config; }, error => Promise.reject(error)); // 添加响应拦截器 axios.interceptors.response.use(res => { const request = JSON.stringify(res.config.url) + (!!res.config.data ? JSON.stringify(res.config.data) : JSON.stringify(res.config.params)) requestList.splice(requestList.findIndex(item => item === request), 1) if (res.status === 200) { let { data } = res if (data.returnCode == successCode) { return Promise.resolve(data) } else { if (data.returnMsg === '系统没有登录或会话超时!') { store.dispatch('user/changeState', { key: 'token', value: '' }) store.dispatch('user/changeState', { key: 'name', value: '' }) store.dispatch('user/changeState', { key: 'userId', value: '' }) store.dispatch('user/changeState', { key: 'loginStatus', value: false }) MessageBox.confirm('系统没有登录或会话超时, 是否登录?', '提示', { confirmButtonText: '登录', cancelButtonText: '取消', type: 'warning' }) .then(() => { MessageBox.close() // window.location.hash = "/login/index"; // window.location.href = "#/login/index"; // router.replace(`/login/index`) // this.$router.replace('/login/index') let logUrl = window.location.protocol+"//"+window.location.host+"/"+Caegw_LogUrl; // console.log(logUrl); window.location.href=logUrl }) .catch(() => { Message.info('已取消!') MessageBox.close() }) } return Promise.reject(data) } } else { return Promise.reject(res) } }, err => { const { res } = err; if (res) { // 请求已发出,但是不在2xx的范围 requestList.length = 0; errorHandle(res.status, res.data.message); return Promise.reject(res); } else { console.log(err) if (err.message == '取消上传') { return Promise.reject('cancel') } // 处理断网的情况 // eg:请求超时或断网时,更新network状态,可在app.vue中控制着一个全局的断网提示组件的显示隐藏 if (err.message == '取消重复请求') { // console.log(err) } else { let error = err.message.indexOf('timeout') != -1 ? { returnMsg: '请求超时' } : { returnMsg: '网络通讯异常' }; requestList.splice(requestList.findIndex(item => item === request), 1) return Promise.reject(error) } } }); //完善请求url function getUrl(channelNo = 'service') { let url = '' if (channelNo == 'service') { url = '/TransServlet' } else if (channelNo == 'manager') { url = '/managersvr/TransServlet' } return url } //配置上行报文公共包头 function getParams(params, channelNo) { // params['clientToken'] = "11112"; params['clientToken'] = "e47b87eec69545559d1e81e56626da68"; let userId ='5f06c8bc77234f969d13e160b54c27e3'; // let userId = store.getters.userId; // if (userId) { params['userId'] = userId; // } params['channelNo'] = channelNo; return params; } // 请求 const request = (params, channelNo = 'service', method = 'post') => { let url = getUrl(channelNo);//完善请求url params = getParams(params, channelNo);//配置上行报文公共包头 return new Promise((resolve, reject) => { if (method == 'post') {//'http://192.168.131:8187/TransServlet' axios.post(url, params).then(res => { resolve(res) }).catch(err => { // Message.error(err.returnMsg) reject(err) }) } else if (method == 'get') { axios.get(url, { params }).then(res => { resolve(res) }).catch(err => { // Message.error(err.returnMsg) reject(err) }) } }) } // 文件上传 const uploadFile = (params, channelNo = 'service', callback1) => { let config = { timeout: 60000, headers: { "Content-Type": "multipart/form-data" }, onUploadProgress: progressEvent => { //属性lengthComputable主要表明总共需要完成的工作量和已经完成的工作是否可以被测量,如果lengthComputable为false,就获取不到progress.total和progress.loaded if (progressEvent.lengthComputable) { let loaded = progressEvent.loaded let total = progressEvent.total // let progress = Math.floor((loaded / total) * 100) > 1 ? Math.floor((loaded / total) * 100) : 1; // console.log('上传进度 ' + progress + '%'); // callback1(progress) } } } let url = getUrl(channelNo);//完善请求url params.append("clientToken", store.getters.token || getToken()); params.append("userId", store.getters.userId); params.append("channelNo", channelNo);//配置上行报文公共包头 console.log(params); return new Promise((resolve, reject) => { axios.post(url, params, config).then(res => { resolve(res) }).catch(err => { if (err != 'cancel') { Message.error(err.returnMsg) } reject(err) }) }) } // 获取图片验证码 const getCode = (channelNo = 'service') => { let rand = Math.random(); let token = store.getters.token || getToken(); return process.env.VUE_APP_BASE_API + getUrl(channelNo) + '?transCode=HM0000&randomKey=' + rand + '&clientToken=' + token; } // 获取图片Url const getImage = (id, channelNo = 'server') => { let token = store.getters.token || getToken(); return process.env.VUE_APP_BASE_API + getUrl(channelNo) + "?transCode=B00022&clientToken=" + token + "&id=" + id; } //加密密码 const enPassword = (password) => { let token = store.getters.token || getToken(); return DES3.encrypt(token, password); } export { request, uploadFile, getCode, getImage, enPassword, sources }