import axios, { AxiosInstance } from 'axios'; import { ElMessage, ElMessageBox } from 'element-plus'; import { MessageType } from 'element-plus/lib/el-message/src/types'; import { Base64 } from 'js-base64'; import { IRequests, ServiceOptions, SvcParams, whiteListUrl } from '../model/requst'; import { RESPONSETYPE } from '../model/requst'; import store from '../store'; import { getTenant, getToken } from './auth'; // 预防 出现option跨域请求 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; let invalidationMark = true; const servicesOptions:ServiceOptions = { mesRequest: { timeout: 60000, baseURL: `${import.meta.env.VITE_APP_BASE_API}`, // withCredentials: true } } function permissionHandler() { if (invalidationMark) { invalidationMark = false; ElMessageBox.alert( '你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { confirmButtonText: '确定', callback: () => { store.dispatch('FedLogOut').then(() =>{ location.reload(); // 莫名其妙代码 }); invalidationMark = true; } } ) } } function arrayBufferHandler(responseData: Iterable<number>) { const enc = new TextDecoder('utf-8'); const errorData = JSON.parse(enc.decode(new Uint8Array(responseData))); return errorData; } function messageHandler(msg: string, type: MessageType) { ElMessage({ message: msg, type: type, duration: 3000 }); } function decorateService(service: AxiosInstance) { // 请求拦截 service.interceptors.request.use( // 请求配置 (config) => { const clientId = import.meta.env.VITE_APP_CLIENT_ID; const clientSecret = import.meta.env.VITE_APP_CLIENT_SECRET; const isToken = config.headers['X-isToken'] === false ? config.headers['X-isToken'] : true; const isTenant = config.headers['X-isTenant'] === false ? config.headers['X-isTenant'] : true && import.meta.env.VITE_APP_IS_MULTI_TENANT_TYPE !== "NONE"; isToken && (config.headers.token = 'Bearer ' + getToken()); isTenant && (config.headers.tenant = getTenant()); config.headers['Authorization'] = `Basic ${Base64.encode(`${clientId}:${clientSecret}`)}`; return config; }, (error) => { Promise.reject(error); } ); service.interceptors.response.use( (response) => { const responseData = response.data; const url = response.config.url?.substring(0, response.config.url.lastIndexOf('/')); const isWhite = url && whiteListUrl.includes(url); const contentType = response.headers['content-type']; const isJson = contentType && contentType === 'application/json; charset=UTF-8'; if (responseData.code === 0 || !isJson) { return Promise.resolve(responseData); } !isWhite && messageHandler(responseData.msg, 'error'); return Promise.reject(responseData); }, (error) => { const responseType = error.config?.responseType; const errorData = responseType === RESPONSETYPE.ARRAYBUFFER ? arrayBufferHandler(error.response.data) : error.response?.data; const status = error.response?.status switch(status) { case 500: case 501: case 502: case 503: messageHandler('服务暂未启动,请稍等一会儿再试~~', 'error'); return Promise.reject(Error('服务暂未启动')); case 401: return permissionHandler(); default: const msg = errorData?.msg || errorData?.errorMsg || '系统内部异常,请联系网站管理员'; messageHandler(msg, 'error'); return Promise.reject(errorData); } } ) } function getServices(options: ServiceOptions): IRequests { const requests:IRequests = {}; Object.keys(options).forEach((svcName) => { requests[svcName] = axios.create(options[svcName as SvcParams]); decorateService(requests[svcName]); }); return requests; } export default getServices(servicesOptions);
// requst的接口 import type { AxiosInstance, AxiosRequestConfig } from "axios"; export const whiteListUrl = [ '/componentBom/batchImport', '/componentBom/importBomBasic', '/componentBom/importMaterial', '/componentBom/importBomRebar', '/stackLoadPlan/planImport' ] export const RESPONSETYPE = { ARRAYBUFFER: 'arraybuffer', BLOB: 'blob', DOCUMENT: 'document', JSON: 'json', STREAM: 'stream', TEXT: 'text', } export interface ServiceOptions { mesRequest: AxiosRequestConfig; } export interface IRequests { [axiosSvcName: string]: AxiosInstance } export type SvcParams = 'mesRequest';