request.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import axios from "axios";
  2. import { Notification, MessageBox, Message, Loading } from "element-ui";
  3. import store from "@/store";
  4. import { getToken } from "@/utils/auth";
  5. import errorCode from "@/utils/errorCode";
  6. import { tansParams, blobValidate } from "@/utils/ruoyi";
  7. import cache from "@/plugins/cache";
  8. import { saveAs } from "file-saver";
  9. let downloadLoadingInstance;
  10. // 是否显示重新登录
  11. export let isRelogin = { show: false };
  12. axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
  13. // 创建axios实例
  14. const service = axios.create({
  15. // axios中请求配置有baseURL选项,表示请求URL公共部分
  16. baseURL: process.env.VUE_APP_BASE_API,
  17. // 超时
  18. timeout: 10000,
  19. });
  20. // request拦截器
  21. service.interceptors.request.use(
  22. (config) => {
  23. // 是否需要设置 token
  24. const isToken = (config.headers || {}).isToken === false;
  25. // 是否需要防止数据重复提交
  26. const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
  27. // 是否存在列表查询
  28. const isQueryList =
  29. config.url.includes("/list") || config.url.includes("/query");
  30. if (getToken() && !isToken) {
  31. config.headers["Authorization"] = "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
  32. }
  33. // get请求映射params参数
  34. if (config.method === "get" && config.params) {
  35. let url = config.url + "?" + tansParams(config.params);
  36. url = url.slice(0, -1);
  37. config.params = {};
  38. config.url = url;
  39. }
  40. if (
  41. !isRepeatSubmit &&
  42. !isQueryList &&
  43. (config.method === "post" || config.method === "put")
  44. ) {
  45. const requestObj = {
  46. url: config.url,
  47. data:
  48. typeof config.data === "object"
  49. ? JSON.stringify(config.data)
  50. : config.data,
  51. time: new Date().getTime(),
  52. };
  53. const sessionObj = cache.session.getJSON("sessionObj");
  54. if (
  55. sessionObj === undefined ||
  56. sessionObj === null ||
  57. sessionObj === ""
  58. ) {
  59. cache.session.setJSON("sessionObj", requestObj);
  60. } else {
  61. const s_url = sessionObj.url; // 请求地址
  62. const s_data = sessionObj.data; // 请求数据
  63. const s_time = sessionObj.time; // 请求时间
  64. const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
  65. if (
  66. s_data === requestObj.data &&
  67. requestObj.time - s_time < interval &&
  68. s_url === requestObj.url
  69. ) {
  70. const message = "数据正在处理,请勿重复提交";
  71. console.warn(`[${s_url}]: ` + message);
  72. return Promise.reject(new Error(message));
  73. } else {
  74. cache.session.setJSON("sessionObj", requestObj);
  75. }
  76. }
  77. }
  78. return config;
  79. },
  80. (error) => {
  81. console.log(error);
  82. Promise.reject(error);
  83. }
  84. );
  85. // 响应拦截器
  86. service.interceptors.response.use(
  87. (res) => {
  88. // 未设置状态码则默认成功状态
  89. const code = res.data.code || 200;
  90. // 获取错误信息
  91. const msg = errorCode[code] || res.data.msg || errorCode["default"];
  92. // 二进制数据则直接返回
  93. if (
  94. res.request.responseType === "blob" ||
  95. res.request.responseType === "arraybuffer"
  96. ) {
  97. return res.data;
  98. }
  99. if (code === 401) {
  100. if (!isRelogin.show) {
  101. isRelogin.show = true;
  102. MessageBox.confirm(
  103. "登录状态已过期,您可以继续留在该页面,或者重新登录",
  104. "系统提示",
  105. {
  106. confirmButtonText: "重新登录",
  107. cancelButtonText: "取消",
  108. type: "warning",
  109. }
  110. )
  111. .then(() => {
  112. isRelogin.show = false;
  113. store.dispatch("LogOut").then(() => {
  114. location.href = "/index";
  115. });
  116. })
  117. .catch(() => {
  118. isRelogin.show = false;
  119. });
  120. }
  121. return Promise.reject("无效的会话,或者会话已过期,请重新登录。");
  122. } else if (code === 500) {
  123. Notification.error({
  124. title: "error",
  125. message: msg.replaceAll(/(\n|\r|\r\n|↵)/g, "<br/>"),
  126. dangerouslyUseHTMLString: true,
  127. });
  128. // Message({ message: msg, type: "error" });
  129. return Promise.reject(new Error(msg));
  130. } else if (code === 601) {
  131. Notification.warning({
  132. title: "error",
  133. message: msg.replaceAll(/(\n|\r|\r\n|↵)/g, "<br/>"),
  134. dangerouslyUseHTMLString: true,
  135. });
  136. // Message({ message: msg, type: "warning" });
  137. return Promise.reject("error");
  138. } else if (code !== 200) {
  139. Notification.error({
  140. title: msg.replaceAll(/(\n|\r|\r\n|↵)/g, "<br/>"),
  141. dangerouslyUseHTMLString: true,
  142. });
  143. return Promise.reject("error");
  144. } else {
  145. return res.data;
  146. }
  147. },
  148. (error) => {
  149. console.log("err" + error);
  150. let { message } = error;
  151. if (message == "Network Error") {
  152. message = "后端接口连接异常";
  153. } else if (message.includes("timeout")) {
  154. message = "系统接口请求超时";
  155. } else if (message.includes("Request failed with status code")) {
  156. message = "系统接口" + message.substr(message.length - 3) + "异常";
  157. }
  158. Message({ message: message, type: "error", duration: 5 * 1000 });
  159. return Promise.reject(error);
  160. }
  161. );
  162. // 通用下载方法
  163. export function download(url, params, filename, config) {
  164. downloadLoadingInstance = Loading.service({
  165. text: "正在下载数据,请稍候",
  166. spinner: "el-icon-loading",
  167. background: "rgba(255, 255, 255, 0.7)",
  168. });
  169. return service
  170. .post(url, params, {
  171. transformRequest: [
  172. (params) => {
  173. return tansParams(params);
  174. },
  175. ],
  176. headers: { "Content-Type": "application/x-www-form-urlencoded" },
  177. responseType: "blob",
  178. ...config,
  179. })
  180. .then(async (data) => {
  181. const isBlob = blobValidate(data);
  182. if (isBlob) {
  183. const blob = new Blob([data]);
  184. saveAs(blob, filename);
  185. } else {
  186. const resText = await data.text();
  187. const rspObj = JSON.parse(resText);
  188. const errMsg =
  189. errorCode[rspObj.code] || rspObj.msg || errorCode["default"];
  190. Message.error(errMsg);
  191. }
  192. downloadLoadingInstance.close();
  193. })
  194. .catch((r) => {
  195. console.error(r);
  196. Message.error("下载文件出现错误,请联系管理员!");
  197. downloadLoadingInstance.close();
  198. });
  199. }
  200. // // 通用上传方法
  201. // export function upload(url, params, filename, config) {
  202. // downloadLoadingInstance = Loading.service({
  203. // text: "正在上传数据,请稍候",
  204. // spinner: "el-icon-loading",
  205. // background: "rgba(255, 255, 255, 0.7)",
  206. // });
  207. // return service
  208. // .post(url, params, {
  209. // transformRequest: [
  210. // (params) => {
  211. // return tansParams(params);
  212. // },
  213. // ],
  214. // headers: { "Content-Type": "application/x-www-form-urlencoded" },
  215. // responseType: "blob",
  216. // ...config,
  217. // })
  218. // .then(async (data) => {
  219. // const isBlob = blobValidate(data);
  220. // if (isBlob) {
  221. // const blob = new Blob([data]);
  222. // saveAs(blob, filename);
  223. // } else {
  224. // const resText = await data.text();
  225. // const rspObj = JSON.parse(resText);
  226. // const errMsg =
  227. // errorCode[rspObj.code] || rspObj.msg || errorCode["default"];
  228. // Message.error(errMsg);
  229. // }
  230. // downloadLoadingInstance.close();
  231. // })
  232. // .catch((r) => {
  233. // console.error(r);
  234. // Message.error("下载文件出现错误,请联系管理员!");
  235. // downloadLoadingInstance.close();
  236. // });
  237. // }
  238. export default service;