Files
bdrp-app/src/composables/uni-router.ts
2026-04-30 11:39:57 +08:00

244 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { pages } from 'virtual:uni-pages'
/**
* 将 webview 的 vue-router 用法映射到 uni 路由(迁移页面使用)
*/
const pathToPage: Record<string, string> = {
'/': '/pages/index',
'/login': '/pages/login',
'/historyQuery': '/pages/history-query',
'/help': '/pages/help',
'/help/detail': '/pages/help-detail',
'/help/guide': '/pages/help-guide',
'/withdraw': '/pages/withdraw',
'/report': '/pages/report-result-webview',
'/example': '/pages/report-example-webview',
'/app/report': '/pages/report-result-webview',
'/app/example': '/pages/report-example-webview',
'/privacyPolicy': '/pages/privacy-policy',
'/userAgreement': '/pages/user-agreement',
'/authorization': '/pages/authorization',
'/agentManageAgreement': '/pages/agent-manage-agreement',
'/agentSerivceAgreement': '/pages/agent-service-agreement',
'/agentServiceAgreement': '/pages/agent-service-agreement',
'/payment/result': '/pages/payment-result',
'/agent': '/pages/agent',
'/agent/promote': '/pages/promote',
'/me': '/pages/me',
'/cancelAccount': '/pages/cancel-account',
}
const nameToPage: Record<string, string> = {
index: '/pages/index',
login: '/pages/login',
invite: '/pages/invitation',
invitation: '/pages/invitation',
promote: '/pages/promote',
agent: '/pages/agent',
history: '/pages/history-query',
help: '/pages/help',
helpDetail: '/pages/help-detail',
helpGuide: '/pages/help-guide',
withdraw: '/pages/withdraw',
report: '/pages/report-result-webview',
example: '/pages/report-example-webview',
paymentResult: '/pages/payment-result',
privacyPolicy: '/pages/privacy-policy',
userAgreement: '/pages/user-agreement',
authorization: '/pages/authorization',
agentManageAgreement: '/pages/agent-manage-agreement',
agentSerivceAgreement: '/pages/agent-service-agreement',
agentServiceAgreement: '/pages/agent-service-agreement',
me: '/pages/me',
cancelAccount: '/pages/cancel-account',
}
function withQuery(url: string, query?: Record<string, string>) {
if (!query || !Object.keys(query).length)
return url
const q = Object.entries(query)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&')
return `${url}${url.includes('?') ? '&' : '?'}${q}`
}
export function resolveWebToUni(to: string | { name?: string, path?: string, query?: Record<string, string> }): string {
if (typeof to === 'string') {
const qIdx = to.indexOf('?')
const pathOnly = qIdx === -1 ? to : to.slice(0, qIdx)
const queryPart = qIdx === -1 ? '' : to.slice(qIdx + 1)
if (pathOnly.startsWith('/inquire/')) {
const feature = pathOnly.replace(/^\/inquire\//, '')
const base = `/pages/inquire?feature=${encodeURIComponent(feature)}`
return queryPart ? `${base}&${queryPart}` : base
}
if (pathOnly.startsWith('/agent/invitationAgentApply/')) {
const id = pathOnly.replace(/^\/agent\/invitationAgentApply\//, '')
const base = `/pages/invitation-agent-apply?linkIdentifier=${encodeURIComponent(id)}`
return queryPart ? `${base}&${queryPart}` : base
}
if (pathOnly.startsWith('/report/share/')) {
const id = pathOnly.replace(/^\/report\/share\//, '')
const base = `/pages/report-share?linkIdentifier=${encodeURIComponent(id)}`
return queryPart ? `${base}&${queryPart}` : base
}
if (pathToPage[pathOnly]) {
const mapped = pathToPage[pathOnly]
return queryPart ? `${mapped}?${queryPart}` : mapped
}
if (to.startsWith('/pages/'))
return to
return `/pages/${pathOnly.replace(/^\//, '')}${queryPart ? `?${queryPart}` : ''}`
}
if (to.path) {
const base = pathToPage[to.path] || to.path
return withQuery(base, to.query)
}
if (to.name && nameToPage[to.name])
return withQuery(nameToPage[to.name], to.query)
return '/pages/index'
}
export function useRouter() {
return {
push(to: string | { name?: string, path?: string, query?: Record<string, string> }) {
const url = resolveWebToUni(to as any)
uni.navigateTo({ url })
},
replace(to: string | { name?: string, path?: string, query?: Record<string, string> }) {
const url = resolveWebToUni(to as any)
uni.redirectTo({ url })
},
go() {
uni.navigateBack({})
},
back() {
uni.navigateBack({})
},
}
}
/** 当前页 uni route如 `pages/history-query`(无首尾多余斜杠) */
export function getCurrentUniRoute(): string {
const pages = getCurrentPages()
const page = pages[pages.length - 1] as any
return (page?.route || 'pages/index').replace(/^\//, '')
}
type UniPageMeta = (typeof pages)[number] & {
path?: string
auth?: boolean
style?: {
navigationBarTitleText?: string
}
}
function normalizeUniRoute(route?: string) {
return (route || 'pages/index').replace(/^\//, '')
}
const pageMetaByRoute = new Map(
(pages as UniPageMeta[]).map(page => [normalizeUniRoute(page.path), page]),
)
export function getCurrentPageMeta(): UniPageMeta | undefined {
return pageMetaByRoute.get(getCurrentUniRoute())
}
export function getPageTitleByRoute(route = getCurrentUniRoute()): string {
return pageMetaByRoute.get(normalizeUniRoute(route))?.style?.navigationBarTitleText || 'BDRP'
}
export function getLayoutPageTitle(): string {
return getPageTitleByRoute()
}
/**
* 与 webview vue-router path 对齐,用于全局通知 notificationPage 匹配。
* 一个 uni 页面可对应多个 web 路径(如 webview 中 /withdraw 和 /agent/withdraw 是同一页面)。
*/
const UNI_TO_WEB_NOTIFY_PATHS: Record<string, string[]> = {
'pages/index': ['/'],
'pages/agent': ['/agent'],
'pages/me': ['/me'],
'pages/promote': ['/agent/promote'],
'pages/history-query': ['/historyQuery'],
'pages/help': ['/help'],
'pages/help-detail': ['/help/detail'],
'pages/help-guide': ['/help/guide'],
'pages/withdraw': ['/withdraw', '/agent/withdraw'],
'pages/report-result-webview': ['/app/report', '/report'],
'pages/report-example-webview': ['/app/example', '/example'],
'pages/privacy-policy': ['/privacyPolicy'],
'pages/user-agreement': ['/userAgreement'],
'pages/agent-manage-agreement': ['/agentManageAgreement'],
'pages/agent-service-agreement': ['/agentSerivceAgreement'],
'pages/authorization': ['/authorization'],
'pages/payment-result': ['/payment/result'],
'pages/inquire': ['/inquire'],
'pages/login': ['/login'],
'pages/invitation': ['/agent/invitation'],
'pages/agent-promote-details': ['/agent/promoteDetails'],
'pages/agent-rewards-details': ['/agent/rewardsDetails'],
'pages/agent-vip': ['/agent/agentVip'],
'pages/agent-vip-apply': ['/agent/vipApply'],
'pages/agent-vip-config': ['/agent/vipConfig'],
'pages/withdraw-details': ['/agent/withdrawDetails'],
'pages/subordinate-list': ['/agent/subordinateList'],
'pages/cancel-account': ['/cancelAccount'],
'pages/subordinate-detail': ['/agent/subordinateDetail'],
'pages/invitation-agent-apply': ['/agent/invitationAgentApply'],
'pages/report-share': ['/report/share'],
}
/**
* 获取当前 uni 页面在 web 端可能的所有路径(用于通知匹配)
*/
export function getWebPathsForNotification(): string[] {
const r = getCurrentUniRoute()
const pages = getCurrentPages()
const page = pages[pages.length - 1] as any
const q: Record<string, string> = { ...(page?.options || {}) }
// 动态路由:带参数的路径
if (r === 'pages/inquire' && q.feature)
return [`/inquire/${q.feature}`]
if (r === 'pages/subordinate-detail' && q.id)
return [`/agent/subordinateDetail/${q.id}`]
if (r === 'pages/invitation-agent-apply' && q.linkIdentifier)
return [`/agent/invitationAgentApply/${q.linkIdentifier}`]
if (r === 'pages/report-share' && q.linkIdentifier)
return [`/report/share/${q.linkIdentifier}`]
return UNI_TO_WEB_NOTIFY_PATHS[r] || ['/']
}
export function getWebPathForNotification(): string {
return getWebPathsForNotification()[0] ?? '/'
}
const uniRouteToName: Record<string, string> = {
'pages/index': 'index',
'pages/agent': 'agent',
'pages/me': 'me',
'pages/promote': 'promote',
}
export function useRoute() {
const pages = getCurrentPages()
const page = pages[pages.length - 1] as any
const query: Record<string, string> = { ...(page?.options || {}) }
const params: Record<string, string> = { ...query }
const routeKey = normalizeUniRoute(page?.route)
return {
query,
path: page?.route ? `/${page.route}` : '/',
params,
name: uniRouteToName[routeKey] || routeKey,
meta: {
title: getPageTitleByRoute(routeKey),
},
}
}