request.js 8.5 KB

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