import axios from "axios"; import { Message, MessageBox, Notification } from "element-ui"; import { objTypeOf } from "./utils"; import router from "../router"; import Vue from "vue"; import { getAuthorization } from "./crypto"; import { PLATFORM, DEVICE_ID } from "../constants/app"; import { initSyncTime, fetchTime } from "./syncServerTime"; import log4js from "./logger"; const logger = log4js.getLogger("request"); // logger const addLog = (datas, type) => { if (type === "start") { const msg = `${datas.url},开始请求`; logger.info(msg); } else if (type === "success") { const msg = `${datas.config.url},请求成功`; logger.info(msg); } else { if (datas.config && datas.response) { const msg = `${datas.config?.url},请求错误,错误信息:${datas.response.data.status} - ${datas.response.data.message}`; logger.error(msg); } else { logger.error(datas.message || "请求错误"); } } }; // axios interceptors var load = ""; // 同一时间有多个请求时,会形成队列。在第一个请求创建loading,在最后一个响应关闭loading var queue = []; axios.interceptors.request.use( (config) => { // 显示loading提示 if (!queue.length && !config["slientRequest"]) { load = Message({ customClass: "el-message-loading", iconClass: "el-message__icon el-icon-loading", message: "加载中...", duration: 0, }); } queue.push(1); // 为请求头添加鉴权信息 let token = Vue.ls.get("token"); if (token) { const ids = { orgId: Vue.ls.get("orgId", ""), schoolId: Vue.ls.get("curSchool", { id: "" }).id, userId: Vue.ls.get("user", { id: "" }).id, }; Object.entries(ids).forEach(([key, val]) => { if (val === null || val === "null" || val === "") return; config.headers[key] = val; }); // 新版鉴权 const sessionId = Vue.ls.get("user", { sessionId: "" }).sessionId; const timestamp = fetchTime(); const Authorization = getAuthorization( { token: token, timestamp, account: sessionId, uri: config.url.split("?")[0], method: config.method, }, "token" ); config.headers["Authorization"] = Authorization; config.headers["time"] = timestamp; } // 为请求地址添加全局domain let domain = Vue.ls.get("domain", ""); if (config.url.indexOf("http://") < 0) { config.url = domain + config.url; } config.headers["deviceId"] = DEVICE_ID; config.headers["platform"] = PLATFORM; config.headers["domain"] = domain; // 设置延迟时效 config.timeout = 10 * 60 * 1000; addLog(config, "start"); return config; }, (error) => { // console.log(error); // logger.error(""); // 关闭loading提示 setTimeout(() => { queue.shift(); if (!queue.length) load && load.close(); }, 100); return Promise.reject(error); } ); axios.interceptors.response.use( (response) => { initSyncTime(new Date(response.headers.date).getTime()); addLog(response, "success"); // 关闭loading提示 setTimeout(() => { queue.shift(); if (!queue.length) load && load.close(); }, 100); return response; }, (error) => { if (error.response) { initSyncTime(new Date(error.response.headers.date).getTime()); } addLog(error, "error"); // 关闭loading提示 setTimeout(() => { queue.shift(); if (!queue.length) load && load.close(); }, 100); return Promise.reject(error); } ); const mdData = (datas) => { let nData = {}; if (!datas) return nData; Object.entries(datas).forEach(([key, val]) => { if (val === null || val === "null" || val === "") return; nData[key] = val; }); return nData; }; /** * errorCallback 请求失败的回调 * @param {Object} error 请求失败时的错误信息 */ const errorCallback = (error, config = {}) => { const slientRequest = config && config["slientRequest"]; if (slientRequest) { return error; } if (error.response) { return errorDataCallback(error.response); } if (error.request) { let message = "请求错误"; if (error.message.indexOf("timeout") > -1) { message = "请求超时"; } Notification.error({ title: "错误提示", message }); return error; } Notification.error({ title: "错误提示", message: "请求错误" }); return error; }; let unauthMsgBoxIsShow = false; /** * errorDataCallback 请求成功,结果有误的回调 * @param {Object} response Response信息 */ const errorDataCallback = (response) => { if (objTypeOf(response.data) === "blob") return response.data; const error = response.data; let message = error.message || error.error || "请求错误"; const unauthStatus = [401, 403]; if (unauthStatus.includes(response.status)) { if (error.code === 401001 && message === "没有权限") { Notification.error({ title: "错误提示", message }); return error; } if (unauthMsgBoxIsShow) return error; const exposeMsgs = ["系统授权信息已过期,请联系系统管理员激活!"]; unauthMsgBoxIsShow = true; message = exposeMsgs.includes(message) ? message : "身份验证失效,请重新登录"; MessageBox.confirm(message, "重新登陆?", { type: "warning", closeOnClickModal: false, closeOnPressEscape: false, showClose: false, callback: (action) => { unauthMsgBoxIsShow = false; if (action !== "confirm") return; router.push({ name: "Login" }); }, }); } else { Notification.error({ title: "错误提示", message }); } return error; }; /** * response format * { config, header, data, request, status, statusText } * */ /** * successCallback 请求成功的回调 * @param {Object} data Response中的data信息 */ const successCallback = (data) => { if (data.code === 200) { if ( objTypeOf(data.data) === "object" && Object.prototype.hasOwnProperty.call(data.data, "success") ) { if (data.data.success) { return data.data; } else { return Promise.reject(data.data); } } else { return data.data; } } else { return Promise.reject(data.data); } }; /** * get请求 * @param {String} url 请求地址 * @param {Object} datas 请求数据 */ const $get = (url, datas) => { return axios .get(url, { params: mdData(datas) }) .then((rep) => { return successCallback(rep.data); }) .catch((error) => { return Promise.reject(errorCallback(error)); }); }; /** * get请求 * @param {String} url 请求地址 * @param {Object} datas 请求数据 */ const $postParam = (url, datas, config = {}) => { return axios .post(url, {}, { ...config, params: mdData(datas) }) .then((rep) => { if (config["responseType"] === "blob") return rep; return successCallback(rep.data); }) .catch((error) => { return Promise.reject(errorCallback(error, config)); }); }; /** * post请求 * @param {String} url 请求地址 * @param {Object} datas 请求数据 */ const $post = (url, datas, config = {}) => { let sqDatas = {}; if (datas.constructor === Object) { sqDatas = mdData(datas); } else { sqDatas = datas; } return axios .post(url, sqDatas, config) .then((rep) => { if (config["responseType"] === "blob") return rep; return successCallback(rep.data); }) .catch((error) => { return Promise.reject(errorCallback(error, config)); }); }; /** * delete请求 * @param {String} url * @param {Object} datas */ const $del = (url, datas) => { return axios .delete(url, { params: mdData(datas) }) .then((rep) => { return rep.data; }) .catch((error) => { return Promise.reject(errorCallback(error)); }); }; /** * put 请求 * @param {String} url 请求地址 * @param {Object} datas 请求数据 */ const $put = (url, datas) => { return axios .put(url, { params: mdData(datas) }) .then((rep) => { return rep.data; }) .catch((error) => { return Promise.reject(errorCallback(error)); }); }; /** * patch请求 * @param {String} url 请求地址 * @param {Object} datas 请求数据 */ const $patch = (url, datas) => { return axios .patch(url, { params: mdData(datas) }) .then((rep) => { return rep.data; }) .catch((error) => { return Promise.reject(errorCallback(error)); }); }; export { $get, $postParam, $post, $del, $put, $patch };