Files
integral-shop/single_uniapp22miao/utils/navigation.js

335 lines
7.9 KiB
JavaScript
Raw Normal View History

// +----------------------------------------------------------------------
// | 路由导航工具类
// +----------------------------------------------------------------------
// | 提供统一的路由跳转方法,支持路径别名和参数处理
// +----------------------------------------------------------------------
/**
* 路由别名映射表
* 将简短的别名映射到实际的页面路径
*/
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<Boolean>}
*/
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
}