import axios from 'axios'; import {ElLoading, ElMessage, ElMessageBox, ElNotification} from 'element-plus'; import {getToken} from '@/utils/auth'; import errorCode from '@/utils/errorCode'; import {blobValidate, tansParams} from '@/utils/yamato.js'; import cache from '@/plugins/cache'; import {saveAs} from 'file-saver'; import useUserStore from '@/store/modules/user'; import {formatMsg} from "@/utils/yamato.js"; const TIMEOUT = 500; // 時間間隔(ms) const LIMIT_SIZE = 5 * 1024 * 1024; // ファイルサイズ制限(5M) // 再ログインの表示 export const isReLogin = { show: false, toggle() { this.show = !this.show; } }; axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'; // axiosインスタンスの作成 const service = axios.create({ baseURL: import.meta.env.VITE_APP_BASE_API, timeout: 10000 }); /** * バイト長の計算 * @param str * @returns {number} */ function calculateByteLength(str) { return new Blob([str]).size; } /** * リクエストインターセプター */ service.interceptors.request.use(async (config) => { const isToken = (config.headers || {}).isToken === false; const isRepeatSubmit = (config.headers || {}).repeatSubmit === false; if (getToken() && !isToken) { config.headers['Authorization'] = 'Bearer ' + getToken(); } if (config.method === 'get' && config.params) { config.url = `${config.url}?${tansParams(config.params)}`; config.params = {}; } if (!isRepeatSubmit && ['post', 'put'].includes(config.method)) { const requestObj = { url: config.url, data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, time: new Date().getTime() }; // バイト長の計算 const requestSize = calculateByteLength(JSON.stringify(requestObj)); if (requestSize >= LIMIT_SIZE) { console.warn(`[${config.url}]: リクエストデータのサイズが許可された${LIMIT_SIZE / (1024 * 1024)}Mの制限を超えています。重複送信の検証はできません。`); return config; } const sessionObj = cache.session.getJSON('sessionObj'); if (!sessionObj) { cache.session.setJSON('sessionObj', requestObj); } else { const {url: s_url, data: s_data, time: s_time} = sessionObj; if (s_data === requestObj.data && requestObj.time - s_time < TIMEOUT && s_url === requestObj.url) { const message = 'データ処理中です。重複送信しないでください'; console.warn(`[${s_url}]: ${message}`); return Promise.reject(new Error(message)); } else { cache.session.setJSON('sessionObj', requestObj); } } } return config; }, error => { console.error(error); return Promise.reject(error); }); /** * レスポンスインターセプター */ service.interceptors.response.use(async (res) => { const code = res.data.code || 200; const msg = errorCode[code] || res.data.msg || errorCode['default']; if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { return res; } if (code === 401) { if (!isReLogin.show) { isReLogin.toggle(); // ログイン状態が期限切れになりました。ページにとどまるか、または再ログインできます。 await ElMessageBox.confirm(formatMsg('Q0004'), 'システムメッセージ', { confirmButtonText: '再ログイン', cancelButtonText: 'キャンセル', type: 'warning' }).then(async () => { await useUserStore().logOut(); location.href = '/index'; isReLogin.toggle(); }).catch(() => { isReLogin.toggle(); }); } else { return Promise.reject('無効なセッション、またはセッションが期限切れになっています。再ログインしてください。'); } } else if (code === 500) { ElMessage({message: msg, type: 'error'}); return Promise.reject(new Error(msg)); } else if (code === 601) { ElMessage({message: msg, type: 'warning'}); return Promise.reject(new Error(msg)); } else if (code !== 200) { ElNotification.error({title: msg}); return Promise.reject('error'); } else { return res.data; } }, error => { console.error('err', error); let {message} = error; if (message === "Network Error") { message = "バックエンドインターフェースの接続に異常があります"; } else if (message.includes("timeout")) { message = "システムインターフェースのリクエストがタイムアウトしました"; } else if (message.includes("Request failed with status code")) { message = `システムインターフェース${message.substr(message.length - 3)}に異常があります`; } ElMessage({message, type: 'error', duration: 5000}); return Promise.reject(error); }); /** * 一般的なダウンロードメソッド * @param url * @param params * @param filename * @param config * @returns {Promise} */ export async function download(url, params, filename, config) { let downloadLoadingInstance = ElLoading.service({ text: "データをダウンロードしています、少々お待ちください", background: "rgba(0, 0, 0, 0.7)", }); try { const response = await service.post(url, params, { transformRequest: [params => tansParams(params)], headers: {'Content-Type': 'application/x-www-form-urlencoded'}, responseType: 'blob', ...config }); const data = response.data; const isBlob = blobValidate(data); if (isBlob) { const blob = new Blob([data]); saveAs(blob, filename); } else { const resText = await data.text(); const rspObj = JSON.parse(resText); const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']; ElMessage.error(errMsg); } } catch (error) { console.error(error); ElMessage.error('ファイルのダウンロード中にエラーが発生しました。管理者にお問い合わせください!'); } finally { downloadLoadingInstance.close(); } } export default service;