import { AUTH_ENABLED, AUTH_STORAGE_KEYS } from '@/constants/auth' import { ROUTES, TAB_ROUTES } from '@/constants/routes' export const LOGIN_PAGE = ROUTES.LOGIN export const HOME_PAGE = ROUTES.HOME export const TAB_PAGES = TAB_ROUTES let hasSetupInterceptors = false /** * 规范化路由,保证以 `/` 开头。 */ function normalizeUrl(url = '') { if (!url) { return '' } if (url.startsWith('/')) { return url } return `/${url}` } /** * 获取不带 query 的路径。 */ function getPath(url = '') { return normalizeUrl(url).split('?')[0] } function safeDecode(value = '') { try { return decodeURIComponent(value) } catch (error) { return value } } /** * 把页面 options 组装成 query 字符串。 */ function buildQuery(options = {}) { const keys = Object.keys(options) if (!keys.length) { return '' } const query = keys .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(options[key] || '')}`) .join('&') return query ? `?${query}` : '' } /** * 获取当前页面完整地址(path + query)。 */ function getCurrentPageUrl() { const pages = getCurrentPages() if (!pages.length) { return '' } const current = pages[pages.length - 1] const currentPath = current.route ? `/${current.route}` : '' const currentQuery = current.options ? buildQuery(current.options) : '' return `${currentPath}${currentQuery}` } function isLoginPage(url = '') { return getPath(url) === LOGIN_PAGE } function needLogin(url = '') { return !isLoginPage(url) } export function isAuthEnabled() { return AUTH_ENABLED } export function isTabPage(url = '') { return TAB_PAGES.includes(getPath(url)) } export function getToken() { return uni.getStorageSync(AUTH_STORAGE_KEYS.TOKEN) || '' } export function isLoggedIn() { if (!AUTH_ENABLED) { return true } return Boolean(getToken()) } export function getUser() { return uni.getStorageSync(AUTH_STORAGE_KEYS.USER) || null } /** * 保存登录态。 */ export function setAuth({ token, user } = {}) { if (token) { uni.setStorageSync(AUTH_STORAGE_KEYS.TOKEN, token) } if (user) { uni.setStorageSync(AUTH_STORAGE_KEYS.USER, user) } } export function clearAuth() { uni.removeStorageSync(AUTH_STORAGE_KEYS.TOKEN) uni.removeStorageSync(AUTH_STORAGE_KEYS.USER) } /** * 跳转到登录页并携带重定向地址。 */ export function redirectToLogin(targetUrl = '') { if (!AUTH_ENABLED) { return } const redirect = normalizeUrl(targetUrl || getCurrentPageUrl()) if (isLoginPage(redirect)) { return } const loginUrl = redirect ? `${LOGIN_PAGE}?redirect=${encodeURIComponent(redirect)}` : LOGIN_PAGE uni.reLaunch({ url: loginUrl }) } /** * 登录成功后按 redirect 返回目标页。 */ export function goAfterLogin(redirect = '') { const target = normalizeUrl(safeDecode(redirect) || HOME_PAGE) const targetPath = getPath(target) if (isLoginPage(targetPath)) { uni.switchTab({ url: HOME_PAGE }) return } if (isTabPage(targetPath)) { uni.switchTab({ url: targetPath }) return } uni.reLaunch({ url: target }) } function guardPage(url = '') { if (!AUTH_ENABLED) { return true } if (!needLogin(url) || isLoggedIn()) { return true } redirectToLogin(url) return false } /** * 初始化 uni 路由拦截器,只注册一次。 */ export function setupAuthInterceptors() { if (hasSetupInterceptors) { return } const methods = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'] methods.forEach((method) => { uni.addInterceptor(method, { invoke(args) { return guardPage(args.url) } }) }) hasSetupInterceptors = true } export function ensureCurrentPageAuth() { const currentUrl = getCurrentPageUrl() if (!currentUrl) { return } guardPage(currentUrl) }