request.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import axios from 'axios';
  2. import {ElLoading, ElMessage, ElMessageBox, ElNotification} from 'element-plus';
  3. import {getToken} from '@/utils/auth';
  4. import errorCode from '@/utils/errorCode';
  5. import {blobValidate, tansParams} from '@/utils/yamato.js';
  6. import cache from '@/plugins/cache';
  7. import {saveAs} from 'file-saver';
  8. import useUserStore from '@/store/modules/user';
  9. import {formatMsg} from "@/utils/yamato.js";
  10. const TIMEOUT = 500; // 時間間隔(ms)
  11. const LIMIT_SIZE = 5 * 1024 * 1024; // ファイルサイズ制限(5M)
  12. // 再ログインの表示
  13. export const isReLogin = {
  14. show: false,
  15. toggle() {
  16. this.show = !this.show;
  17. }
  18. };
  19. axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
  20. // axiosインスタンスの作成
  21. const service = axios.create({
  22. baseURL: import.meta.env.VITE_APP_BASE_API,
  23. timeout: 10000
  24. });
  25. /**
  26. * バイト長の計算
  27. * @param str
  28. * @returns {number}
  29. */
  30. function calculateByteLength(str) {
  31. return new Blob([str]).size;
  32. }
  33. /**
  34. * リクエストインターセプター
  35. */
  36. service.interceptors.request.use(async (config) => {
  37. const isToken = (config.headers || {}).isToken === false;
  38. const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
  39. if (getToken() && !isToken) {
  40. config.headers['Authorization'] = 'Bearer ' + getToken();
  41. }
  42. if (config.method === 'get' && config.params) {
  43. config.url = `${config.url}?${tansParams(config.params)}`;
  44. config.params = {};
  45. }
  46. if (!isRepeatSubmit && ['post', 'put'].includes(config.method)) {
  47. const requestObj = {
  48. url: config.url,
  49. data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
  50. time: new Date().getTime()
  51. };
  52. // バイト長の計算
  53. const requestSize = calculateByteLength(JSON.stringify(requestObj));
  54. if (requestSize >= LIMIT_SIZE) {
  55. console.warn(`[${config.url}]: リクエストデータのサイズが許可された${LIMIT_SIZE / (1024 * 1024)}Mの制限を超えています。重複送信の検証はできません。`);
  56. return config;
  57. }
  58. const sessionObj = cache.session.getJSON('sessionObj');
  59. if (!sessionObj) {
  60. cache.session.setJSON('sessionObj', requestObj);
  61. } else {
  62. const {url: s_url, data: s_data, time: s_time} = sessionObj;
  63. if (s_data === requestObj.data && requestObj.time - s_time < TIMEOUT && s_url === requestObj.url) {
  64. const message = 'データ処理中です。重複送信しないでください';
  65. console.warn(`[${s_url}]: ${message}`);
  66. return Promise.reject(new Error(message));
  67. } else {
  68. cache.session.setJSON('sessionObj', requestObj);
  69. }
  70. }
  71. }
  72. return config;
  73. }, error => {
  74. console.error(error);
  75. return Promise.reject(error);
  76. });
  77. /**
  78. * レスポンスインターセプター
  79. */
  80. service.interceptors.response.use(async (res) => {
  81. const code = res.data.code || 200;
  82. const msg = errorCode[code] || res.data.msg || errorCode['default'];
  83. if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
  84. return res;
  85. }
  86. if (code === 401) {
  87. if (!isReLogin.show) {
  88. isReLogin.toggle();
  89. // ログイン状態が期限切れになりました。ページにとどまるか、または再ログインできます。
  90. await ElMessageBox.confirm(formatMsg('Q0004'), 'システムメッセージ', {
  91. confirmButtonText: '再ログイン',
  92. cancelButtonText: 'キャンセル',
  93. type: 'warning'
  94. }).then(async () => {
  95. await useUserStore().logOut();
  96. location.href = '/index';
  97. isReLogin.toggle();
  98. }).catch(() => {
  99. isReLogin.toggle();
  100. });
  101. } else {
  102. return Promise.reject('無効なセッション、またはセッションが期限切れになっています。再ログインしてください。');
  103. }
  104. } else if (code === 500) {
  105. ElMessage({message: msg, type: 'error'});
  106. return Promise.reject(new Error(msg));
  107. } else if (code === 601) {
  108. ElMessage({message: msg, type: 'warning'});
  109. return Promise.reject(new Error(msg));
  110. } else if (code !== 200) {
  111. ElNotification.error({title: msg});
  112. return Promise.reject('error');
  113. } else {
  114. return res.data;
  115. }
  116. }, error => {
  117. console.error('err', error);
  118. let {message} = error;
  119. if (message === "Network Error") {
  120. message = "バックエンドインターフェースの接続に異常があります";
  121. } else if (message.includes("timeout")) {
  122. message = "システムインターフェースのリクエストがタイムアウトしました";
  123. } else if (message.includes("Request failed with status code")) {
  124. message = `システムインターフェース${message.substr(message.length - 3)}に異常があります`;
  125. }
  126. ElMessage({message, type: 'error', duration: 5000});
  127. return Promise.reject(error);
  128. });
  129. /**
  130. * 一般的なダウンロードメソッド
  131. * @param url
  132. * @param params
  133. * @param filename
  134. * @param config
  135. * @returns {Promise<void>}
  136. */
  137. export async function download(url, params, filename, config) {
  138. let downloadLoadingInstance = ElLoading.service({
  139. text: "データをダウンロードしています、少々お待ちください",
  140. background: "rgba(0, 0, 0, 0.7)",
  141. });
  142. try {
  143. const response = await service.post(url, params, {
  144. transformRequest: [params => tansParams(params)],
  145. headers: {'Content-Type': 'application/x-www-form-urlencoded'},
  146. responseType: 'blob',
  147. ...config
  148. });
  149. const data = response.data;
  150. const isBlob = blobValidate(data);
  151. if (isBlob) {
  152. const blob = new Blob([data]);
  153. saveAs(blob, filename);
  154. } else {
  155. const resText = await data.text();
  156. const rspObj = JSON.parse(resText);
  157. const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'];
  158. ElMessage.error(errMsg);
  159. }
  160. } catch (error) {
  161. console.error(error);
  162. ElMessage.error('ファイルのダウンロード中にエラーが発生しました。管理者にお問い合わせください!');
  163. } finally {
  164. downloadLoadingInstance.close();
  165. }
  166. }
  167. export default service;