axios.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. import axios from "axios";
  2. import { Message, MessageBox, Notification } from "element-ui";
  3. import { objTypeOf } from "./utils";
  4. import router from "../router";
  5. import Vue from "vue";
  6. import { getAuthorization } from "./crypto";
  7. import { PLATFORM, DEVICE_ID } from "../constants/app";
  8. import { initSyncTime, fetchTime } from "./syncServerTime";
  9. import log4js from "./logger";
  10. const logger = log4js.getLogger("request");
  11. // logger
  12. const addLog = (datas, type) => {
  13. if (type === "start") {
  14. const msg = `${datas.url},开始请求`;
  15. logger.info(msg);
  16. } else if (type === "success") {
  17. const msg = `${datas.config.url},请求成功`;
  18. logger.info(msg);
  19. } else {
  20. if (datas.config && datas.response) {
  21. const msg = `${datas.config?.url},请求错误,错误信息:${datas.response.data.status} - ${datas.response.data.message}`;
  22. logger.error(msg);
  23. } else {
  24. logger.error(datas.message || "请求错误");
  25. }
  26. }
  27. };
  28. // axios interceptors
  29. var load = "";
  30. // 同一时间有多个请求时,会形成队列。在第一个请求创建loading,在最后一个响应关闭loading
  31. var queue = [];
  32. axios.interceptors.request.use(
  33. (config) => {
  34. // 显示loading提示
  35. if (!queue.length && !config["slientRequest"]) {
  36. load = Message({
  37. customClass: "el-message-loading",
  38. iconClass: "el-message__icon el-icon-loading",
  39. message: "加载中...",
  40. duration: 0,
  41. });
  42. }
  43. queue.push(1);
  44. // 为请求头添加鉴权信息
  45. let token = Vue.ls.get("token");
  46. if (token) {
  47. const ids = {
  48. orgId: Vue.ls.get("orgId", ""),
  49. schoolId: Vue.ls.get("curSchool", { id: "" }).id,
  50. userId: Vue.ls.get("user", { id: "" }).id,
  51. };
  52. Object.entries(ids).forEach(([key, val]) => {
  53. if (val === null || val === "null" || val === "") return;
  54. config.headers[key] = val;
  55. });
  56. // 新版鉴权
  57. const sessionId = Vue.ls.get("user", { sessionId: "" }).sessionId;
  58. const timestamp = fetchTime();
  59. const Authorization = getAuthorization(
  60. {
  61. token: token,
  62. timestamp,
  63. account: sessionId,
  64. uri: config.url.split("?")[0],
  65. method: config.method,
  66. },
  67. "token"
  68. );
  69. config.headers["Authorization"] = Authorization;
  70. config.headers["time"] = timestamp;
  71. }
  72. // 为请求地址添加全局domain
  73. let domain = Vue.ls.get("domain", "");
  74. if (config.url.indexOf("http://") < 0) {
  75. config.url = domain + config.url;
  76. }
  77. config.headers["deviceId"] = DEVICE_ID;
  78. config.headers["platform"] = PLATFORM;
  79. config.headers["domain"] = domain;
  80. // 设置延迟时效
  81. config.timeout = 10 * 60 * 1000;
  82. addLog(config, "start");
  83. return config;
  84. },
  85. (error) => {
  86. // console.log(error);
  87. // logger.error("");
  88. // 关闭loading提示
  89. setTimeout(() => {
  90. queue.shift();
  91. if (!queue.length) load && load.close();
  92. }, 100);
  93. return Promise.reject(error);
  94. }
  95. );
  96. axios.interceptors.response.use(
  97. (response) => {
  98. initSyncTime(new Date(response.headers.date).getTime());
  99. addLog(response, "success");
  100. // 关闭loading提示
  101. setTimeout(() => {
  102. queue.shift();
  103. if (!queue.length) load && load.close();
  104. }, 100);
  105. return response;
  106. },
  107. (error) => {
  108. if (error.response) {
  109. initSyncTime(new Date(error.response.headers.date).getTime());
  110. }
  111. addLog(error, "error");
  112. // 关闭loading提示
  113. setTimeout(() => {
  114. queue.shift();
  115. if (!queue.length) load && load.close();
  116. }, 100);
  117. return Promise.reject(error);
  118. }
  119. );
  120. const mdData = (datas) => {
  121. let nData = {};
  122. if (!datas) return nData;
  123. Object.entries(datas).forEach(([key, val]) => {
  124. if (val === null || val === "null" || val === "") return;
  125. nData[key] = val;
  126. });
  127. return nData;
  128. };
  129. /**
  130. * errorCallback 请求失败的回调
  131. * @param {Object} error 请求失败时的错误信息
  132. */
  133. const errorCallback = (error, config = {}) => {
  134. const slientRequest = config && config["slientRequest"];
  135. if (slientRequest) {
  136. return error;
  137. }
  138. if (error.response) {
  139. return errorDataCallback(error.response);
  140. }
  141. if (error.request) {
  142. let message = "请求错误";
  143. if (error.message.indexOf("timeout") > -1) {
  144. message = "请求超时";
  145. }
  146. Notification.error({ title: "错误提示", message });
  147. return error;
  148. }
  149. Notification.error({ title: "错误提示", message: "请求错误" });
  150. return error;
  151. };
  152. let unauthMsgBoxIsShow = false;
  153. /**
  154. * errorDataCallback 请求成功,结果有误的回调
  155. * @param {Object} response Response信息
  156. */
  157. const errorDataCallback = (response) => {
  158. if (objTypeOf(response.data) === "blob") return response.data;
  159. const error = response.data;
  160. let message = error.message || error.error || "请求错误";
  161. const unauthStatus = [401, 403];
  162. if (unauthStatus.includes(response.status)) {
  163. if (error.code === 401001 && message === "没有权限") {
  164. Notification.error({ title: "错误提示", message });
  165. return error;
  166. }
  167. if (unauthMsgBoxIsShow) return error;
  168. const exposeMsgs = ["系统授权信息已过期,请联系系统管理员激活!"];
  169. unauthMsgBoxIsShow = true;
  170. message = exposeMsgs.includes(message)
  171. ? message
  172. : "身份验证失效,请重新登录";
  173. MessageBox.confirm(message, "重新登陆?", {
  174. type: "warning",
  175. closeOnClickModal: false,
  176. closeOnPressEscape: false,
  177. showClose: false,
  178. callback: (action) => {
  179. unauthMsgBoxIsShow = false;
  180. if (action !== "confirm") return;
  181. router.push({ name: "Login" });
  182. },
  183. });
  184. } else {
  185. Notification.error({ title: "错误提示", message });
  186. }
  187. return error;
  188. };
  189. /**
  190. * response format
  191. * {
  192. config, header, data, request, status, statusText
  193. }
  194. *
  195. */
  196. /**
  197. * successCallback 请求成功的回调
  198. * @param {Object} data Response中的data信息
  199. */
  200. const successCallback = (data) => {
  201. if (data.code === 200) {
  202. if (
  203. objTypeOf(data.data) === "object" &&
  204. Object.prototype.hasOwnProperty.call(data.data, "success")
  205. ) {
  206. if (data.data.success) {
  207. return data.data;
  208. } else {
  209. return Promise.reject(data.data);
  210. }
  211. } else {
  212. return data.data;
  213. }
  214. } else {
  215. return Promise.reject(data.data);
  216. }
  217. };
  218. /**
  219. * get请求
  220. * @param {String} url 请求地址
  221. * @param {Object} datas 请求数据
  222. */
  223. const $get = (url, datas) => {
  224. return axios
  225. .get(url, { params: mdData(datas) })
  226. .then((rep) => {
  227. return successCallback(rep.data);
  228. })
  229. .catch((error) => {
  230. return Promise.reject(errorCallback(error));
  231. });
  232. };
  233. /**
  234. * get请求
  235. * @param {String} url 请求地址
  236. * @param {Object} datas 请求数据
  237. */
  238. const $postParam = (url, datas, config = {}) => {
  239. return axios
  240. .post(url, {}, { ...config, params: mdData(datas) })
  241. .then((rep) => {
  242. if (config["responseType"] === "blob") return rep;
  243. return successCallback(rep.data);
  244. })
  245. .catch((error) => {
  246. return Promise.reject(errorCallback(error, config));
  247. });
  248. };
  249. /**
  250. * post请求
  251. * @param {String} url 请求地址
  252. * @param {Object} datas 请求数据
  253. */
  254. const $post = (url, datas, config = {}) => {
  255. let sqDatas = {};
  256. if (datas.constructor === Object) {
  257. sqDatas = mdData(datas);
  258. } else {
  259. sqDatas = datas;
  260. }
  261. return axios
  262. .post(url, sqDatas, config)
  263. .then((rep) => {
  264. if (config["responseType"] === "blob") return rep;
  265. return successCallback(rep.data);
  266. })
  267. .catch((error) => {
  268. return Promise.reject(errorCallback(error, config));
  269. });
  270. };
  271. /**
  272. * delete请求
  273. * @param {String} url
  274. * @param {Object} datas
  275. */
  276. const $del = (url, datas) => {
  277. return axios
  278. .delete(url, { params: mdData(datas) })
  279. .then((rep) => {
  280. return rep.data;
  281. })
  282. .catch((error) => {
  283. return Promise.reject(errorCallback(error));
  284. });
  285. };
  286. /**
  287. * put 请求
  288. * @param {String} url 请求地址
  289. * @param {Object} datas 请求数据
  290. */
  291. const $put = (url, datas) => {
  292. return axios
  293. .put(url, { params: mdData(datas) })
  294. .then((rep) => {
  295. return rep.data;
  296. })
  297. .catch((error) => {
  298. return Promise.reject(errorCallback(error));
  299. });
  300. };
  301. /**
  302. * patch请求
  303. * @param {String} url 请求地址
  304. * @param {Object} datas 请求数据
  305. */
  306. const $patch = (url, datas) => {
  307. return axios
  308. .patch(url, { params: mdData(datas) })
  309. .then((rep) => {
  310. return rep.data;
  311. })
  312. .catch((error) => {
  313. return Promise.reject(errorCallback(error));
  314. });
  315. };
  316. export { $get, $postParam, $post, $del, $put, $patch };