| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- import pagesJson from 'virtual:pages-json'
- import type { Page } from '@uni-ku/pages-json/types'
- interface cousPage extends Page {
- islogin: boolean
- name?: string
- }
- function generateRoutes() {
- if (!pagesJson.pages)
- return []
- const routes = pagesJson.pages.map((page) => {
- const newPath = `/${page.path}`
- return { ...page, path: newPath }
- }) as cousPage[]
- if (pagesJson.subPackages && pagesJson.subPackages.length > 0) {
- pagesJson.subPackages.forEach((subPackage) => {
- const subRoutes = subPackage.pages.map((page: any) => {
- const newPath = `/${subPackage.root}/${page.path}`
- return { ...page, path: newPath }
- })
- routes.push(...subRoutes)
- })
- }
- return routes
- }
- const router = createRouter({
- routes: generateRoutes(),
- })
- /**
- * 过滤出所有需要登录的name 返回不需要登录的name
- *
- */
- function whitePathName() {
- return generateRoutes().filter(it => !it.islogin).map(it => it.name)
- }
- router.beforeEach((to, from, next) => {
- console.log('🚀 beforeEach 守卫触发:', { to, from }, '')
- const { token, redirectName } = storeToRefs(useUserStore())
- if (to.name === 'smqjh-login') {
- redirectName.value = appendParamsToPath(String(from.path), from.params as any)
- console.log(redirectName.value, ' redirectName.value')
- }
- if (!whitePathName().includes(to.name) && !token.value) {
- const { confirm: showConfirm } = useGlobalMessage()
- return new Promise<void>((resolve, reject) => {
- showConfirm({
- title: '警告',
- msg: '检测到当前状态未登录,是否登录',
- confirmButtonText: '登录',
- cancelButtonText: '取消',
- success() {
- redirectName.value = String(to.path)
- // console.log('✅ 用户确认访问,允许导航')
- router.replace({ name: 'smqjh-login' })
- // resolve()
- },
- fail() {
- // console.log('❌ 用户取消访问,阻止导航')
- next(false)
- reject(new Error('用户取消访问'))
- },
- })
- })
- }
- // 演示:基本的导航日志记录
- if (to.path && from.path) {
- console.log(`📍 导航: ${from.path} → ${to.path}`)
- }
- // 继续导航
- next()
- })
- router.afterEach((to, from) => {
- console.log('🎯 afterEach 钩子触发:', { to, from })
- // 演示:简单的页面切换记录
- if (to.path) {
- console.log(`📄 页面切换完成: ${to.path}`)
- }
- })
- export default router
- /**
- * 将 params 参数拼接到 path 路径后面
- * 兼容扫码拉起小程序时 q 参数为编码后的 URL 的情况
- * @param path 基础路径
- * @param params 参数对象
- * @returns 拼接后的完整路径
- */
- function appendParamsToPath(path: string, params: Record<string, any>): string {
- if (!params || Object.keys(params).length === 0) {
- return path
- }
- const queryParams: string[] = []
- Object.entries(params).forEach(([key, value]) => {
- if (value !== undefined && value !== null) {
- const strValue = String(value)
- // 处理扫码参数 q,可能是编码后的 URL
- if (key === 'q') {
- const extractedParams = extractParamsFromEncodedUrl(strValue)
- if (extractedParams) {
- // 将提取的参数合并到 queryParams
- Object.entries(extractedParams).forEach(([k, v]) => {
- queryParams.push(`${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
- })
- return
- }
- }
- // 普通参数直接编码
- const encodedKey = encodeURIComponent(key)
- const encodedValue = encodeURIComponent(strValue)
- queryParams.push(`${encodedKey}=${encodedValue}`)
- }
- })
- const queryString = queryParams.join('&')
- return queryString ? `${path}?${queryString}` : path
- }
- /**
- * 从编码后的 URL 中提取查询参数
- * @param encodedUrl 可能被编码的 URL 字符串
- * @returns 解析后的查询参数对象,如果不是有效的 URL 则返回 null
- */
- function extractParamsFromEncodedUrl(encodedUrl: string): Record<string, string> | null {
- try {
- // 尝试解码 URL
- let decodedUrl = encodedUrl
- // 可能需要多次解码(处理多次编码的情况)
- while (decodedUrl.includes('%')) {
- const newDecoded = decodeURIComponent(decodedUrl)
- if (newDecoded === decodedUrl)
- break
- decodedUrl = newDecoded
- }
- // 检查是否是有效的 URL 格式
- if (!decodedUrl.includes('http://') && !decodedUrl.includes('https://')) {
- return null
- }
- // 提取 ? 后面的查询参数
- const questionIndex = decodedUrl.indexOf('?')
- if (questionIndex === -1) {
- return null
- }
- const queryString = decodedUrl.substring(questionIndex + 1)
- if (!queryString) {
- return null
- }
- // 解析查询参数
- const params: Record<string, string> = {}
- const pairs = queryString.split('&')
- pairs.forEach((pair) => {
- const equalIndex = pair.indexOf('=')
- if (equalIndex > 0) {
- const key = decodeURIComponent(pair.substring(0, equalIndex))
- const val = decodeURIComponent(pair.substring(equalIndex + 1))
- params[key] = val
- }
- else if (pair) {
- params[decodeURIComponent(pair)] = ''
- }
- })
- return Object.keys(params).length > 0 ? params : null
- }
- catch {
- return null
- }
- }
|