// +---------------------------------------------------------------------- // | 路由导航工具类 // +---------------------------------------------------------------------- // | 提供统一的路由跳转方法,支持路径别名和参数处理 // +---------------------------------------------------------------------- /** * 路由别名映射表 * 将简短的别名映射到实际的页面路径 */ export const routeAlias = { // 主要页面 '/': '/pages/index/index', '/home': '/pages/index/index', '/index': '/pages/index/index', '/user': '/pages/personal/index', '/personal': '/pages/personal/index', '/rushing': '/pages/rushing/index', // 登录相关 '/login': '/pages/sub-pages/login/index', '/register': '/pages/sub-pages/login/register', '/reset-pwd': '/pages/sub-pages/login/reset-account', '/change-pwd': '/pages/sub-pages/login/change-pwd', // 签名功能 '/sign': '/pages/sub-pages/webview/sign', '/sign-preview': '/pages/sub-pages/webview/sign-preview', // 订单相关 '/orders': '/pages/sub-pages/rushing-order/index', '/order-detail': '/pages/sub-pages/rushing-order/detail', // 用户信息 '/profile': '/pages/sub-pages/user-info/index', '/address': '/pages/sub-pages/address/index', '/address-edit': '/pages/sub-pages/address/detail', // 财务相关 '/balance': '/pages/sub-pages/balance/index', '/withdraw': '/pages/sub-pages/withdraw/index', '/withdraw-log': '/pages/sub-pages/withdraw/list', '/prize': '/pages/sub-pages/prize/index', // 其他功能 '/coupon': '/pages/sub-pages/coupon/index', '/invite': '/pages/sub-pages/invite/index', '/fans': '/pages/sub-pages/my-fans/index', '/payee': '/pages/sub-pages/my-payee/index', '/search': '/pages/sub-pages/search/index', '/settings': '/pages/sub-pages/setting/index', '/agreement': '/pages/sub-pages/agreement/index', } /** * 将路径别名解析为实际路径 * @param {String} path - 路径或别名 * @returns {String} 实际路径 */ function resolveAlias(path) { // 如果是别名,返回实际路径 if (routeAlias[path]) { return routeAlias[path] } // 否则返回原路径 return path } /** * 构建带查询参数的URL * @param {String} path - 路径 * @param {Object} query - 查询参数对象 * @returns {String} 完整URL */ function buildUrl(path, query = {}) { const resolvedPath = resolveAlias(path) const queryString = Object.keys(query) .filter(key => query[key] !== undefined && query[key] !== null) .map(key => `${key}=${encodeURIComponent(query[key])}`) .join('&') return queryString ? `${resolvedPath}?${queryString}` : resolvedPath } /** * 路由导航类 */ export const Navigation = { /** * 保留当前页面,跳转到应用内的某个页面 * @param {String} path - 页面路径或别名 * @param {Object} query - 查询参数 * @returns {Promise} * * @example * Navigation.push('/sign', { id: 123 }) * Navigation.push('/pages/sub-pages/webview/sign', { id: 123 }) */ push(path, query = {}) { const url = buildUrl(path, query) return new Promise((resolve, reject) => { uni.navigateTo({ url, success: resolve, fail: reject }) }) }, /** * 关闭当前页面,跳转到应用内的某个页面 * @param {String} path - 页面路径或别名 * @param {Object} query - 查询参数 * @returns {Promise} * * @example * Navigation.replace('/login') */ replace(path, query = {}) { const url = buildUrl(path, query) return new Promise((resolve, reject) => { uni.redirectTo({ url, success: resolve, fail: reject }) }) }, /** * 关闭所有页面,打开到应用内的某个页面 * @param {String} path - 页面路径或别名 * @param {Object} query - 查询参数 * @returns {Promise} * * @example * Navigation.reLaunch('/home') */ reLaunch(path, query = {}) { const url = buildUrl(path, query) return new Promise((resolve, reject) => { uni.reLaunch({ url, success: resolve, fail: reject }) }) }, /** * 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 * @param {String} path - tabBar 页面路径或别名 * @returns {Promise} * * @example * Navigation.switchTab('/home') */ switchTab(path) { const url = resolveAlias(path) return new Promise((resolve, reject) => { uni.switchTab({ url, success: resolve, fail: reject }) }) }, /** * 关闭当前页面,返回上一页面或多级页面 * @param {Number} delta - 返回的页面数,如果 delta 大于现有页面数,则返回到首页 * @returns {Promise} * * @example * Navigation.back() * Navigation.back(2) */ back(delta = 1) { return new Promise((resolve, reject) => { uni.navigateBack({ delta, success: resolve, fail: reject }) }) }, /** * 预加载页面 * @param {String} path - 页面路径或别名 * @returns {Promise} * * @example * Navigation.preload('/order-detail') */ preload(path) { const url = resolveAlias(path) // #ifdef APP-PLUS return new Promise((resolve, reject) => { uni.preloadPage({ url, success: resolve, fail: reject }) }) // #endif // #ifndef APP-PLUS return Promise.resolve() // #endif }, /** * 获取当前页面栈 * @returns {Array} 页面栈 */ getPages() { return getCurrentPages() }, /** * 获取当前页面路径 * @returns {String} 当前页面路径 */ getCurrentPath() { const pages = getCurrentPages() const currentPage = pages[pages.length - 1] return currentPage ? `/${currentPage.route}` : '' }, /** * 获取上一页面路径 * @returns {String|null} 上一页面路径 */ getPrevPath() { const pages = getCurrentPages() if (pages.length < 2) return null const prevPage = pages[pages.length - 2] return prevPage ? `/${prevPage.route}` : null }, /** * 判断是否可以返回 * @returns {Boolean} */ canBack() { const pages = getCurrentPages() return pages.length > 1 }, /** * 解析URL参数 * @param {String} url - URL字符串 * @returns {Object} 参数对象 */ parseQuery(url) { const query = {} const queryString = url.split('?')[1] if (queryString) { queryString.split('&').forEach(item => { const [key, value] = item.split('=') query[key] = decodeURIComponent(value) }) } return query } } /** * 路由拦截器 * 可用于登录验证、权限检查等 */ export class RouteInterceptor { constructor() { this.beforeEachHooks = [] this.afterEachHooks = [] } /** * 注册全局前置守卫 * @param {Function} hook - (to, from, next) => {} */ beforeEach(hook) { this.beforeEachHooks.push(hook) } /** * 注册全局后置守卫 * @param {Function} hook - (to, from) => {} */ afterEach(hook) { this.afterEachHooks.push(hook) } /** * 执行前置守卫 * @param {String} to - 目标路径 * @param {String} from - 来源路径 * @returns {Promise} */ async runBeforeHooks(to, from) { for (const hook of this.beforeEachHooks) { const result = await new Promise((resolve) => { hook(to, from, (next) => { resolve(next !== false) }) }) if (!result) return false } return true } /** * 执行后置守卫 * @param {String} to - 目标路径 * @param {String} from - 来源路径 */ runAfterHooks(to, from) { this.afterEachHooks.forEach(hook => hook(to, from)) } } // 创建全局路由拦截器实例 export const router = new RouteInterceptor() // 导出默认对象 export default { Navigation, router, routeAlias, resolveAlias, buildUrl }