// common/constants/routes.js /** 与 pages.json 保持一致 */ export const PAGE = { INDEX: '/pages/index/index', COURSE: '/pages/course/index', TRAIN: '/pages/train/index', DISCOVER: '/pages/discover/index', MEMBER: '/pages/memberInfo/memberInfo', BOOKING: '/pages/memberInfo/booking', MEMBER_CARD: '/pages/memberInfo/memberCard', USER_INFO: '/pages/memberInfo/userInfo', BODY_TEST_HOME: '/pages/memberInfo/bodyTestHome', BODY_TEST_CONNECT: '/pages/memberInfo/bodyTestConnect', BODY_TEST_MEASURING: '/pages/memberInfo/bodyTestMeasuring', BODY_TEST_REPORT: '/pages/memberInfo/bodyTestReport', BODY_TEST_HISTORY: '/pages/memberInfo/bodyTestHistory', BODY_TEST_COMPARE: '/pages/memberInfo/bodyTestCompare', BODY_TEST_SETTINGS: '/pages/memberInfo/bodyTestSettings', BODY_TEST_TREND: '/pages/memberInfo/bodyTestTrend', COURSE_LIST: '/pages/groupCourse/list', COURSE_DETAIL: '/pages/memberInfo/courseDetail', COUPON_DETAIL: '/pages/memberInfo/couponDetail', COUPON_CENTER: '/pages/memberInfo/couponCenter', POINTS_MALL: '/pages/memberInfo/pointsMall', POINTS_HISTORY: '/pages/memberInfo/pointsHistory', ONLINE_COURSE: '/pages/memberInfo/onlineCourseDetail', COURSE_EVALUATE: '/pages/memberInfo/courseEvaluate', TRAIN_SESSION: '/pages/memberInfo/trainSessionDetail', TRAIN_REPORT: '/pages/memberInfo/trainReport', COUPONS: '/pages/memberInfo/coupons', POINTS: '/pages/memberInfo/points', REFERRAL: '/pages/memberInfo/referral', MY_COURSES: '/pages/memberInfo/myCourses', CHECK_IN_HISTORY: '/pages/memberInfo/checkInHistory' } /** 底部 TabBar 页面路径,顺序与 TabBar.vue 一致 */ export const TAB_ROUTES = [ PAGE.INDEX, PAGE.COURSE, PAGE.TRAIN, PAGE.DISCOVER, PAGE.MEMBER ] const TAB_PAGES = new Set(TAB_ROUTES) /** 防止 Tab 连点触发并发路由 */ let tabNavigating = false function normalizePath(url) { if (!url) return '' const path = url.split('?')[0] return path.startsWith('/') ? path : `/${path}` } export function getTabIndexByRoute(route) { const path = normalizePath(route) const idx = TAB_ROUTES.indexOf(path) return idx >= 0 ? idx : 0 } export function getCurrentRoutePath() { const pages = getCurrentPages() if (!pages.length) return PAGE.INDEX const page = pages[pages.length - 1] const route = page.route || page.$page?.fullPath || '' return normalizePath(route ? `/${route}` : PAGE.INDEX) } /** * 跳转到普通页面(非 TabBar 页面) * 使用 navigateTo,保留页面栈,可以正常返回 */ export function navigateToPage(url) { uni.showLoading({ title: '加载中...', mask: true }) const path = normalizePath(url) // ✅ 如果目标是 TabBar 页面,不应该使用 navigateTo // 这种情况应该使用 switchToTabPage(会清空页面栈) if (TAB_PAGES.has(path)) { console.warn('[navigateToPage] 不应该用 navigateTo 跳转 TabBar 页面,请使用 switchToTabPage') switchToTabPage(path) return } console.log('[navigateToPage] 跳转到:', url) uni.navigateTo({ url, fail: (err) => { console.error('[navigateTo]', url, err) // 页面栈满时降级使用 redirectTo if (err.errMsg && err.errMsg.includes('limit')) { uni.redirectTo({ url }) } else { uni.showToast({ title: '页面跳转失败', icon: 'none' }) } }, success: () => { setTimeout(() => { uni.hideLoading() },3000) } }) } /** * 跳转到 TabBar 页面(清空页面栈) * 用于从任何页面跳转到首页/课程/训练等 TabBar 页面 */ export function switchToTabPage(url) { const path = normalizePath(url) if (!TAB_PAGES.has(path)) { console.warn('[switchToTabPage] 目标不是 TabBar 页面:', path) navigateToPage(url) return } if (getCurrentRoutePath() === path || tabNavigating) return console.log('[switchToTabPage] 跳转到 TabBar:', path) tabNavigating = true uni.switchTab({ // ✅ 改用 switchTab,而不是 reLaunch url: path, complete: () => { setTimeout(() => { tabNavigating = false }, 320) }, fail: (err) => { console.error('[switchTab]', path, err) // 降级使用 reLaunch uni.reLaunch({ url: path, complete: () => { setTimeout(() => { tabNavigating = false }, 320) } }) } }) } /** * 重置到 TabBar 页面(清空所有历史) * 用于退出登录、强制跳转等场景 */ export function reLaunchToTabPage(url) { const path = normalizePath(url) console.log('[reLaunchToTabPage] 重置到:', path) uni.reLaunch({ url: path, fail: (err) => { console.error('[reLaunch]', path, err) uni.switchTab({ url: path }) } }) } /** * 返回上一页,如果没有上一页则跳转到指定 TabBar 页面 */ export function goBackOrTab(fallbackUrl = PAGE.MEMBER) { const pages = getCurrentPages() if (pages.length > 1) { uni.navigateBack({ delta: 1 }) } else { switchToTabPage(fallbackUrl) } } /** * 子页面返回个人中心 */ export function backToMemberCenter() { goBackOrTab(PAGE.MEMBER) } /** * 子页面返回指定 TabBar 页面 */ export function backToTab(tabUrl) { goBackOrTab(tabUrl) }