// 该文件是request.js的辅助函数文件 // 全局配置 import _config from '@/config' // 加密方式 import { Base64 } from 'js-base64' // message实例 import Message from '@/utils/onlyMsgBox' // utils import { findActiveRoute } from '@/utils/routeHelper' import { sleep } from '@/utils' import { setToken, getToken, cookieSet, cookieGet, getLanguage, removeToken, removeCookie, getRefreshToken, setTokenOutRoute, handleDomainLayout } from '@/utils/auth' // api import { logoutSSOApi } from '@/api/multi-login' const whiteListUrl = [ '/base-user/get-login-user' ] // NOTE: 当前页面是否为白名单 const isInwhiteList = _config.whiteList.includes(window.location.pathname) // NOTE: 是否/portal页 const isPortal = window.location.pathname === '/portal' // NOTE: 当前语种 const lang = getLanguage() || 'zh-cn' // NOTE: 请求头部默认参数 export const defaultHeaders = config => { const token = getToken() // 多语言 const language = getLanguage()?.replace('-', '#') ?? 'zh#cn' if (!token) return { ...config.headers, language } const route = findActiveRoute() const session = localStorage.getItem('GptSession') ?? undefined // 请求token const authorization = token ?? undefined // 请求refreshtoken const refreshAuthorization = getRefreshToken() ?? undefined const requestMenuUrl = Base64.encode(window.location.pathname) const pageName = Base64.encode(route?.meta?.title || '') ?? undefined const pageEnName = Base64.encode(route?.meta?.enTitle || '') ?? undefined const controllerURL = Base64.encode(config.url) // 系统编码 const systemCode = Base64.encode(_config.systemCode) // 接口来源 const loginForm = Base64.encode('PC') const menuId = sessionStorage.getItem('menuId') ?? undefined return { menuId, session, language, pageName, loginForm, pageEnName, systemCode, controllerURL, authorization, requestMenuUrl, 'refresh-authorization': refreshAuthorization } } // NOTE: 默认的回调集合 const defaultRequest = { // 谷神800接口成功函数 800: response => { //更新token if (response.headers.authorization) { setToken(response.headers.authorization, response.headers['refresh-authorization']) } //bpm 兼容 if (response.config.url.indexOf('bpm/') > -1 && response.data.code === 800) { response.data.status = 'S' } }, '-1': response => { removeToken() // 失效时候当前的路由。 !isInwhiteList && !isPortal && setTokenOutRoute(window.location.href) const domain = cookieGet('domainName') const ssoToken = cookieGet('ssoToken') const ssoRefreshToken = cookieGet('ssoRefreshToken') const { portalType, ssoType, urlLogout, urlLogin, portalCode } = response.data // sso单点登录处理 if (portalType === 'sso') { // 如果是sso并且type为企业微信和钉钉 cookieSet('ssoType', ssoType, null) cookieSet('urlLogout', urlLogout, null) cookieSet('urlLogin', urlLogin, null) cookieSet('portalType', portalType, null) cookieSet('portalCode', portalCode, null) // 重定向到sso登录页面 window.location.href = urlLogin } else if (domain && ssoToken && ssoRefreshToken) { logoutSSOApi().then(res => { if (res.code === 800) { removeCookie('domainName') removeCookie('ssoToken') removeCookie('ssoRefreshToken') window.location.href = res.data } }) } else { // 接口-1报错后登出系统 !isInwhiteList && sleep(2000).then(handleDomainLayout) } }, 401: _error => { // 失效时候当前的路由。 !isInwhiteList && !isPortal && setTokenOutRoute(window.location.href) !isInwhiteList && window.localStorage.removeItem('watermarkData') }, 500: error => { if ( //Token失效的情况 (error.response.data?.message && error.response.data?.message?.indexOf('OAuth2TokenRelayFilter') !== -1) || error.response.data?.message === '-1' ) { removeToken() // 失效时候当前的路由。 !isInwhiteList && !isPortal && setTokenOutRoute(window.location.href) !isInwhiteList && window.localStorage.removeItem('watermarkData') } } } // TODO: 请求后的逻辑 export const handleResponse = async example => { let responseData = { ...example } // 请求返回编码 let code = responseData.data?.code ?? '' const res = example // 错误处理 if (example instanceof Error) { responseData = res.response ?? {} code = responseData?.status ?? '' } // 请求配置 const config = responseData.config ?? {} // 用户传入的编码函数逻辑 let userHandlers = {} Object.keys(config).forEach(key => { // 判断是否为编码函数 if (!Number.isNaN(key)) { // 类型为函数的就赋值 if (typeof config[key] === 'function') { userHandlers[key] = config[key] } } }) // 用户逻辑以及默认逻辑 try { const userLogic = userHandlers[code] const defaultLogic = defaultRequest[code] if (userLogic) { let fn = defaultLogic ? () => defaultLogic(example) : undefined await userLogic(example, fn) } else if (defaultLogic) { await defaultLogic(example) } } catch (error) { console.error('请求回调报错,请检查相应配置') console.error(error) } } // TODO: 生成提示信息 export const handleMessage = example => { // 检查URL是否在白名单中 const currentUrl = example.config?.url || '' if (whiteListUrl.some(whiteUrl => currentUrl.includes(whiteUrl))) return let responseData: any = { ...example } // 请求返回编码 let code = responseData.data?.code ?? '' // 是否为错误 let isError = false const res = example // 判断传入参数是否为Error实例,为true时证明接口走的是报错回调 if (example instanceof Error) { responseData = res.response ?? {} code = responseData?.status ?? '' isError = true } // 请求配置 const config: any = responseData.config ?? {} // 谷神成功的编码 const successCodes = config.successCodes ?? [800] // 用户传入的值 const { success, error } = config.message ?? {} // 判断当前请求是否成功 const isSuccess = successCodes.includes(code) && !isError const result = isSuccess ? success : error // 用户传入的message if (result) { if (typeof result === 'function') { result(example) } else if (typeof result === 'object' || typeof result === 'boolean') { Message[isSuccess ? 'success' : 'error']( Object.assign( { single: true }, { message: fetchMessage(responseData), duration: 3 * 1000, customClass: 'zindex' }, result ) ) } } else { // 走默认报错的message if (!isSuccess) { if (result === false) return let { code, status, msg_en, msg } = responseData?.data ?? {} if (code || status || msg_en || msg) { Message.error( Object.assign( { single: true }, { message: fetchMessage(responseData), duration: 3 * 1000, customClass: 'zindex' }, result ) ) } } } } // TODO: 消息内容 const fetchMessage = response => { // 国际化 const $t = window?.$vueApp?.config?.globalProperties?.$t let { code, status, msg_en, msg } = response?.data let responseCode = code || status const msgTips = lang === 'en-us' ? msg_en || msg : msg // 消息码 switch (responseCode) { case 800: return msgTips case 401: case 500: return $t('tokenInvalid') case 504: return $t('timesOut') case '-1': return $t('loginFailed') default: return msgTips || $t('systemException') } }