/** * H5 上 uni.navigateBack 偶发既不成功也不进 fail;离开 OA web-view 时做兜底。 * @param {{ fallbackUrl?: string, onStuck?: () => void }} [opts] */ export function isOaHostWebviewRoute(route) { const value = String(route || '') return ( value.indexOf('oa/start/webview') !== -1 || value.indexOf('oa/webview/') !== -1 || value.indexOf('market/webview/') !== -1 ) } export function navigateBackFromOaHost(opts) { const onStuck = opts && opts.onStuck const pageRoute = (page) => { return String( (page && (page.route || (page.$page && page.$page.fullPath))) || '' ) } const samePageStillOnTop = (start) => { try { const pages = getCurrentPages() const current = pages && pages[pages.length - 1] return ( !!current && pages.length === start.depth && current === start.page && pageRoute(current) === start.route && isOaHostWebviewRoute(start.route) ) } catch (_) { return false } } const resolveFallbackUrl = () => { const explicit = String((opts && opts.fallbackUrl) || '').trim() if (explicit) return explicit try { const pages = getCurrentPages() if (pages && pages.length >= 2) { const prev = pages[pages.length - 2] const route = prev && prev.route if (route) return '/' + String(route).replace(/^\//, '') } } catch (_) { /* ignore */ } return '/pages/oa/start/index' } let fallbackStarted = false const fallback = () => { if (fallbackStarted) return fallbackStarted = true const fallbackUrl = resolveFallbackUrl() if (!fallbackUrl) { if (onStuck) onStuck() return } uni.redirectTo({ url: fallbackUrl, fail: () => { uni.reLaunch({ url: fallbackUrl, fail: () => { if (onStuck) onStuck() } }) } }) } try { const pages = getCurrentPages() if (pages && pages.length > 1) { const startPage = pages[pages.length - 1] const start = { page: startPage, route: pageRoute(startPage), depth: pages.length } uni.navigateBack({ delta: 1, fail: () => fallback() }) // H5:navigateBack 偶发静默失败 setTimeout(() => { if (samePageStillOnTop(start)) fallback() }, 280) return } } catch (_) { /* fall through */ } fallback() }