import axios from 'axios'; import store from '@/store' import { getToken,getUserId,removeToken,removeUserId } from '@/utils/token'; import { useUserStore } from '@/store/user' import { DES3 } from '@/utils/3des'; import router from '@/router/index' import { message } from '../utils/message.js' import { Caegw_ProUrl,Caegw_LogUrl } from '@/settings' ;// 引入settings.js const requestList = []; // 请求列表 const CancelToken = axios.CancelToken; let sources = {}; let successCode = '000000000' | '0000000';//成功编码 const userStore = useUserStore() //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 === '系统没有登录或会话超时!' || data.returnMsg === '用户验证失败!') { userStore.clearUserInfo(); removeToken(); removeUserId(); router.replace({ path: '/login' }); } 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'] = getToken()||"e47b87eec69545559d1e81e56626da68"; let userId =getUserId() ||'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) }) } }) } /** * 上传文件(支持 FormData) * @param {FormData} formData * @param {string} channelNo * @param {Function} onProgress 上传进度回调,可选 */ const uploadFile = (formData, channelNo = 'service', onProgress) => { // 自动加固定字段 formData.append('clientToken', getToken() || 'e47b87eec69545559d1e81e56626da68') formData.append('userId', getUserId() || '5f06c8bc77234f969d13e160b54c27e3') formData.append('channelNo', channelNo) return axios.post(getUrl(channelNo), formData, { timeout: 60000, headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: e => { if (e.lengthComputable && typeof onProgress === 'function') { const percent = e.total ? Math.floor((e.loaded / e.total) * 100) : 0 onProgress(percent) } } }) .then(res => res) .catch(err => { if (err !== 'cancel') { message.error(err.returnMsg || '上传失败') } return Promise.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 = 'service') => { if (!id) return ''; let token = getToken() || store.token; let userId = getUserId(); return import.meta.env.VITE_BASE_URL + getUrl(channelNo) + "?transCode=B00022&clientToken=" + token + "&userId=" + userId + "&id=" + id; } //加密密码 const enPassword = (password) => { let token = getToken() || store.token; return DES3.encrypt(token, password); } export { request, uploadFile, getCode, getImage, enPassword, sources }