diff --git a/src/authority/index.js b/src/authority/index.js index 2cc9fa5..5ef24d5 100644 --- a/src/authority/index.js +++ b/src/authority/index.js @@ -17,7 +17,7 @@ NProgress.configure({ showSpinner: false, trickleSpeed: 500 }) */ const checkRouteLoading = route => route?.meta?.loading ?? GLOBAL_ROUTE_LOADING -const startRouteLoading = (route) => { +export const startRouteLoading = (route) => { if (checkRouteLoading(route)) { NProgress.start() if (GLOBAL_ROUTE_NEW_LOADING) { @@ -25,17 +25,16 @@ const startRouteLoading = (route) => { } } } -const endRouteLoading = (route) => { - if (checkRouteLoading(route)) { - NProgress.done() - if (GLOBAL_ROUTE_NEW_LOADING) { - $coreHideLoading() - } + +export const endRouteLoading = (route, force = false) => { + NProgress.done() + if (GLOBAL_ROUTE_NEW_LOADING) { + $coreHideLoading(force) } } /** - * 检查路有权限 + * 检查路由权限 * @param to {RouteRecordSingleViewWithChildren} 目的地路由 * @param from 出事路由 * @returns {{name: string}|boolean} @@ -50,7 +49,7 @@ export const checkRouteAuthority = async (to) => { // check权限 return true } - endRouteLoading(to) + endRouteLoading(to, true) return { name: 'Login' } } @@ -61,7 +60,8 @@ const processRouteSavedParam = (to, from) => { } export const processRouteLoading = (to, from) => { - endRouteLoading(to) + const isLoginRoute = to.name === 'Login' || to.path === '/login' + endRouteLoading(to, isLoginRoute) if (to.query?.language && Object.values(GlobalLocales).includes(to.query.language)) { $changeLocale(to.query?.language) } diff --git a/src/utils/index.js b/src/utils/index.js index bd91002..376be0c 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -198,6 +198,7 @@ export const useReload = () => { } export const $logout = () => { + $coreHideLoading(true) useLoginConfigStore().logout() Promise.resolve().then(() => { $goto('/login') @@ -206,32 +207,56 @@ export const $logout = () => { const globalLoadingConfig = { delay: LOADING_DELAY, globalLoading: null, - delayLoadingId: null + delayLoadingId: null, + count: 0 } -export const $coreShowLoading = (message) => { - const globalLoading = globalLoadingConfig.globalLoading - if (globalLoading) { - globalLoading.close() +export const $coreShowLoading = (messageOrConfig) => { + globalLoadingConfig.count++ + if (globalLoadingConfig.count > 1) { + return } - const openLoading = () => ElLoading.service(Object.assign({ - lock: true, - background: 'rgba(0, 0, 0, 0.7)', - text: message - })) - if (globalLoadingConfig.delay > 0) { + if (globalLoadingConfig.delayLoadingId) { + clearTimeout(globalLoadingConfig.delayLoadingId) + globalLoadingConfig.delayLoadingId = null + } + const text = isString(messageOrConfig) ? messageOrConfig : (messageOrConfig?.text || undefined) + const delay = isNumber(messageOrConfig?.delay) ? messageOrConfig.delay : globalLoadingConfig.delay + const openLoading = () => { + if (globalLoadingConfig.count > 0 && !globalLoadingConfig.globalLoading) { + globalLoadingConfig.globalLoading = ElLoading.service(Object.assign({ + lock: true, + background: 'rgba(0, 0, 0, 0.7)', + text + })) + } + } + if (delay > 0) { globalLoadingConfig.delayLoadingId = setTimeout(() => { - globalLoadingConfig.globalLoading = openLoading() - }, globalLoadingConfig.delay) + globalLoadingConfig.delayLoadingId = null + openLoading() + }, delay) } else { - globalLoadingConfig.globalLoading = openLoading() + openLoading() } } -export const $coreHideLoading = () => { - globalLoadingConfig.delayLoadingId && clearTimeout(globalLoadingConfig.delayLoadingId) - globalLoadingConfig.delayLoadingId = null - globalLoadingConfig.globalLoading?.close() +export const $coreHideLoading = (force = false) => { + if (force) { + globalLoadingConfig.count = 0 + } else { + globalLoadingConfig.count = Math.max(0, globalLoadingConfig.count - 1) + } + if (globalLoadingConfig.count === 0) { + if (globalLoadingConfig.delayLoadingId) { + clearTimeout(globalLoadingConfig.delayLoadingId) + globalLoadingConfig.delayLoadingId = null + } + if (globalLoadingConfig.globalLoading) { + globalLoadingConfig.globalLoading.close() + globalLoadingConfig.globalLoading = null + } + } } export const $coreAlert = (message, title = $i18nBundle('common.label.reminder'), options = undefined) => { diff --git a/src/vendors/axios.js b/src/vendors/axios.js index 49a3382..6781cb3 100644 --- a/src/vendors/axios.js +++ b/src/vendors/axios.js @@ -45,6 +45,16 @@ $http.interceptors.request.use(/** @param config {ServiceRequestConfig} */ confi const networkErrorFun = debounce(() => ElMessage.error($i18nBundle('common.msg.networkError')), 300) const networkTimeoutFun = debounce(() => ElMessage.error($i18nBundle('common.msg.networkTimeout')), 300) +const handle401Redirect = debounce(() => { + $coreHideLoading(true) + useLoginConfigStore().logout() + $goto('/login') +}, 200) + +const auth401ErrorFun = debounce((message) => { + ElMessage.error(message || $i18nBundle('common.msg.sessionExpired') || '登录会话已过期,请重新登录') +}, 300) + $http.interceptors.response.use(response => { if (hasLoading(response.config)) { $coreHideLoading() @@ -65,11 +75,25 @@ $http.interceptors.response.use(response => { } else if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') > -1) { networkTimeoutFun() } - if (error.response?.status === 401 && !error.response?.config.isLogin) { - // 跳转登录页面 - $goto('/login') + const is401 = error.response?.status === 401 + const isLoginReq = !!error.config?.isLogin + const resData = error.response?.data + const message = resData?.message || error.message || '系统异常,请稍后再试' + + if (is401 && !isLoginReq) { + auth401ErrorFun(resData?.message) + handle401Redirect() + } else if (showErrorMessage(error.config)) { + ElMessage.error(message) } - return error.response + + if (error.response) { + error.response.data = error.response.data || {} + error.response.data.success = false + error.response.data.message = message + return error.response + } + return Promise.reject(error) }) /**