import type { RouteLocationNormalized } from 'vue-router' import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user' import { UserType } from '@af-mobile-client-vue3/types/auth' import { getPlatformRoutePrefix } from '@af-mobile-client-vue3/types/platform' import { hasAuthority } from '@af-mobile-client-vue3/utils/authority-utils' import { isExternalUser } from '@af-mobile-client-vue3/utils/platform-auth' import { showToast } from 'vant' // 不需要登录拦截的路由配置 const loginIgnore = { names: ['404', '403', 'user-appointment', 'appointment-form', 'appointment-history', 'AuthLoading'], // 根据路由名称匹配 paths: ['/login', '/XReportFormIframeView', '/invoiceShow', '/register', '/loading'], // 根据路由fullPath匹配 /** * 判断路由是否包含在该配置中 * @param route vue-router 的 route 对象 */ includes(route) { return this.names.includes(route.name) || this.paths.includes(route.path) }, } /** * 登录守卫 - 支持外部用户微信授权 * @param to 目标路由 * @param from 来源路由 * @param next 导航函数 */ function loginGuard(to: RouteLocationNormalized, from: RouteLocationNormalized, next: any) { const userStore = useUserStore() const token = userStore.getToken() // 跳过不需要登录验证的路由 if (loginIgnore.includes(to)) { next() return } // 已登录用户的处理 if (token && !to.query.appData && !(to.query.code && to.query.state)) { // 如果已登录且访问登录页,重定向到首页 if (to.path === '/login') { const defaultRoute = userStore.getDefaultRoute() next({ path: defaultRoute }) return } next() return } // 未登录用户的处理 if (!token || to.query.appData || (to.query.code && to.query.state)) { // 使用统一的检测函数判断用户类型 const externalResult = isExternalUser(to) if (externalResult.isExternal) { // 外部用户统一跳转到 loading 页面 const query: any = { redirect: to.path, } Object.assign(query, to.query) // 直接将认证参数传递到路由查询参数中 if (externalResult.authParams) { Object.assign(query, externalResult.authParams) } next({ path: '/loading', query, }) return } // 内部用户跳转到登录页 showToast({ message: '登录状态已失效,请重新登录!', position: 'bottom', }) next({ path: '/login' }) } } /** * 权限守卫 - 支持外部用户权限检查 * @param to 目标路由 * @param from 来源路由 * @param next 导航函数 */ function authorityGuard(to: RouteLocationNormalized, from: RouteLocationNormalized, next: any) { const userStore = useUserStore() const userType = userStore.getUserType() const platformType = userStore.getPlatformType() const permissions = userStore.getPermissions() const roles = userStore.getRoles() const meta = to.meta // 检查用户类型权限 const isExternalUser = userType === UserType.EXTERNAL const allowExternalUser = meta.allowExternalUser ?? false if (isExternalUser && !allowExternalUser) { // 外部用户访问不被允许的页面,重定向到403页面 const platformPrefix = getPlatformRoutePrefix(platformType) if (platformPrefix && platformPrefix !== '/ex/') { next({ path: platformPrefix }) return } next({ path: '/403' }) return } // 跳过不需要权限验证的路由 if (loginIgnore.includes(to)) { next() return } // 如果路由不需要认证,直接通过 if (meta.requiresAuth === false) { next() return } // 传统权限检查 if (!hasAuthority(to, permissions, roles)) { // 没有权限,重定向到403页面 next({ path: '/403' }) return } // 权限检查通过 next() } export default { beforeEach: [loginGuard, authorityGuard], afterEach: [], }