const LOGIN_RETURN_KEY = 'login_redirect' const DEFAULT_RETURN_URL = '/pages/toolbox/toolbox' const LOGIN_ROUTES = ['pages/login/login', 'pages/login/phone'] function routePath(url = '') { return String(url).replace(/^\/+/, '').split(/[?#]/)[0] } function isLoginRoute(url = '') { return LOGIN_ROUTES.includes(routePath(url)) } function normalizeReturnUrl(value = '') { if (!value) return '' let url = String(value) try { if (/%[0-9a-f]{2}/i.test(url)) url = decodeURIComponent(url) } catch (e) {} if (!url.startsWith('/')) url = `/${url}` if (!url.startsWith('/pages/') || isLoginRoute(url)) return '' return url } function getPageUrl(page) { if (!page) return '' const fullPath = page.$page && page.$page.fullPath const normalizedFullPath = normalizeReturnUrl(fullPath) if (normalizedFullPath) return normalizedFullPath const route = routePath(page.route || '') if (!route || isLoginRoute(route)) return '' const options = page.options || (page.$page && page.$page.options) || {} const query = Object.keys(options) .filter((key) => options[key] !== undefined && options[key] !== null && options[key] !== '') .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(String(options[key]))}`) .join('&') return normalizeReturnUrl(`/${route}${query ? `?${query}` : ''}`) } /** * 记录发起登录的页面。普通端返回时优先使用原页面栈;该记录主要用于 H5 微信授权后页面栈丢失的场景。 */ export function rememberLoginSource(explicitUrl = '') { const directUrl = normalizeReturnUrl(explicitUrl) if (directUrl) { uni.setStorageSync(LOGIN_RETURN_KEY, directUrl) return directUrl } const pages = getCurrentPages() for (let index = pages.length - 1; index >= 0; index -= 1) { const url = getPageUrl(pages[index]) if (!url) continue uni.setStorageSync(LOGIN_RETURN_KEY, url) return url } return normalizeReturnUrl(uni.getStorageSync(LOGIN_RETURN_KEY)) } /** * 登录成功后回到发起页: * - 页面栈仍存在时 navigateBack,保留表单/滚动位置,并触发来源页 onShow; * - H5 微信授权导致页面栈丢失时 reLaunch 到已记录路径; * - 没有来源页时才回到工具箱首页。 */ export function returnAfterLogin() { const pages = getCurrentPages() const firstLoginIndex = pages.findIndex((page) => isLoginRoute(page.route || '')) if (firstLoginIndex > 0) { uni.removeStorageSync(LOGIN_RETURN_KEY) uni.navigateBack({ delta: pages.length - firstLoginIndex }) return } const returnUrl = normalizeReturnUrl(uni.getStorageSync(LOGIN_RETURN_KEY)) uni.removeStorageSync(LOGIN_RETURN_KEY) if (returnUrl) { uni.reLaunch({ url: returnUrl }) return } uni.switchTab({ url: DEFAULT_RETURN_URL }) }