Newer
Older
urbanLifeline_YanAn / src / utils / request.js
@zhangqy zhangqy on 3 Oct 5 KB first commit
  1. import axios from 'axios';
  2. import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus';
  3. import { getToken } from '@/utils/auth';
  4. import errorCode from '@/utils/errorCode';
  5. import { tansParams, blobValidate } from '@/utils/ruoyi';
  6. import cache from '@/plugins/cache';
  7. import { saveAs } from 'file-saver';
  8. import useUserStore from '@/store/modules/user';
  9. let downloadLoadingInstance;
  10. // 是否显示重新登录
  11. export let isRelogin = { show: false };
  12.  
  13. axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
  14. // 创建axios实例
  15. const service = axios.create({
  16. // axios中请求配置有baseURL选项,表示请求URL公共部分
  17. baseURL: import.meta.env.VITE_APP_BASE_API,
  18. // 超时
  19. timeout: 30000,
  20. });
  21.  
  22. // request拦截器
  23. service.interceptors.request.use(
  24. config => {
  25. // console.log("config.url", config.url);
  26. // 是否需要设置 token
  27. const isToken = (config.headers || {}).isToken === false;
  28. // 是否需要防止数据重复提交
  29. const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
  30. if (getToken() && !isToken) {
  31. config.headers['Authorization'] = 'Bearer ' + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
  32. }
  33. if (config.url.indexOf('/v3/geocode/regeo') > -1) {
  34. config.baseURL = '/';
  35. }
  36.  
  37. if (config.method === 'get' && config.params) {
  38. // get请求映射params参数
  39. let url = config.url + '?' + tansParams(config.params);
  40. url = url.slice(0, -1);
  41. config.params = {};
  42. config.url = url;
  43. }
  44. if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
  45. const requestObj = {
  46. url: config.url,
  47. data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
  48. time: new Date().getTime(),
  49. };
  50. const sessionObj = cache.session.getJSON('sessionObj');
  51. if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
  52. cache.session.setJSON('sessionObj', requestObj);
  53. } else {
  54. const s_url = sessionObj.url; // 请求地址
  55. const s_data = sessionObj.data; // 请求数据
  56. const s_time = sessionObj.time; // 请求时间
  57. const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
  58. if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
  59. const message = '数据正在处理,请勿重复提交';
  60. console.warn(`[${s_url}]: ` + message);
  61. return Promise.reject(new Error(message));
  62. } else {
  63. cache.session.setJSON('sessionObj', requestObj);
  64. }
  65. }
  66. }
  67. return config;
  68. },
  69. error => {
  70. console.log(error);
  71. Promise.reject(error);
  72. }
  73. );
  74.  
  75. // 响应拦截器
  76. service.interceptors.response.use(
  77. res => {
  78. // 未设置状态码则默认成功状态
  79. const code = res.data.code || 200;
  80. // 获取错误信息
  81. const msg = errorCode[code] || res.data.msg || errorCode['default'];
  82. // 二进制数据则直接返回
  83. if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
  84. return res.data;
  85. }
  86. if (code === 401) {
  87. if (!isRelogin.show) {
  88. isRelogin.show = true;
  89. ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
  90. confirmButtonText: '重新登录',
  91. cancelButtonText: '取消',
  92. type: 'warning',
  93. })
  94. .then(() => {
  95. isRelogin.show = false;
  96. useUserStore()
  97. .logOut()
  98. .then(() => {
  99. location.href = '/index';
  100. });
  101. })
  102. .catch(() => {
  103. isRelogin.show = false;
  104. });
  105. }
  106. return Promise.reject('无效的会话,或者会话已过期,请重新登录。');
  107. } else if (code === 500) {
  108. ElMessage({ message: msg, type: 'error' });
  109. return Promise.reject(new Error(msg));
  110. } else if (code === 601) {
  111. ElMessage({ message: msg, type: 'warning' });
  112. return Promise.reject(new Error(msg));
  113. } else if (code !== 200) {
  114. ElNotification.error({ title: msg });
  115. return Promise.reject('error');
  116. } else {
  117. return Promise.resolve(res.data);
  118. }
  119. },
  120. error => {
  121. console.log('err' + error);
  122. let { message } = error;
  123. if (message == 'Network Error') {
  124. message = '后端接口连接异常';
  125. } else if (message.includes('timeout')) {
  126. message = '系统接口请求超时';
  127. } else if (message.includes('Request failed with status code')) {
  128. message = '系统接口' + message.substr(message.length - 3) + '异常';
  129. }
  130. ElMessage({ message: message, type: 'error', duration: 5 * 1000 });
  131. return Promise.reject(error);
  132. }
  133. );
  134.  
  135. // 通用下载方法
  136. export function download(url, params, filename, config) {
  137. downloadLoadingInstance = ElLoading.service({
  138. text: '正在下载数据,请稍候',
  139. background: 'rgba(0, 0, 0, 0.7)',
  140. });
  141. return service
  142. .post(url, params, {
  143. transformRequest: [
  144. params => {
  145. return tansParams(params);
  146. },
  147. ],
  148. headers: {
  149. 'Content-Type': 'application/x-www-form-urlencoded',
  150. },
  151. // headers: {
  152. // "Content-Type": "application/json;charset=UTF-8",
  153. // },
  154. responseType: 'blob',
  155. ...config,
  156. })
  157. .then(async data => {
  158. const isLogin = await blobValidate(data);
  159. if (isLogin) {
  160. const blob = new Blob([data]);
  161. saveAs(blob, filename);
  162. } else {
  163. const resText = await data.text();
  164. const rspObj = JSON.parse(resText);
  165. const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
  166. ElMessage.error(errMsg);
  167. }
  168. downloadLoadingInstance.close();
  169. })
  170. .catch(r => {
  171. console.error(r);
  172. ElMessage.error('下载文件出现错误,请联系管理员!');
  173. downloadLoadingInstance.close();
  174. });
  175. }
  176.  
  177. export default service;