JMI-OPENATOM
首页
快速开始
  • 架构概览
  • 项目结构
  • 认证与权限
  • 数据库迁移
  • 配置说明
  • 开发规范
  • 架构概览
  • 项目结构
  • 路由与权限
  • API 请求
  • 组件库
  • UniApp 小程序
  • Docker 部署
  • CI/CD
  • Nginx 反向代理
  • 环境变量
  • QQ 机器人
  • 实验室管理系统
  • API 权限清单
  • 数据库表结构
  • 常见问题
首页
快速开始
  • 架构概览
  • 项目结构
  • 认证与权限
  • 数据库迁移
  • 配置说明
  • 开发规范
  • 架构概览
  • 项目结构
  • 路由与权限
  • API 请求
  • 组件库
  • UniApp 小程序
  • Docker 部署
  • CI/CD
  • Nginx 反向代理
  • 环境变量
  • QQ 机器人
  • 实验室管理系统
  • API 权限清单
  • 数据库表结构
  • 常见问题
  • 前端开发

    • 前端架构概览
    • 前端项目结构
    • 路由与权限
    • API 请求层
    • 组件库
    • UniApp 微信小程序

路由与权限

路由架构

前端使用 Vue Router 4,采用 createWebHistory 模式,路由按前台展示、根级页面和管理后台三大区域组织。所有页面组件使用动态导入(懒加载)并带重试机制。

路由守卫

路由守卫实现了多层次的访问控制:

// router/index.ts
router.beforeEach(async (to) => {
    startNavigation(to.fullPath)

    // 1. 登录检查:管理后台与需登录的站点页面
    if ((requiresAdminAuth(to) || requiresSiteLogin(to)) && !getToken()) {
        window.location.assign(await buildOidcAuthorizeUrl(to.fullPath))
        return false
    }

    // 2. 未激活账号拦截(激活页引导流程启用时)
    if (!ACTIVATION_BYPASS_PATHS.has(to.path) && getToken() && !isActivated()) {
        return { path: '/activation', query: { redirect: to.fullPath } }
    }

    // 3. 管理后台权限检查
    if (requiresAdminAuth(to)) {
        await refreshAuthSnapshot()
        if (!hasAdminAccess()) return '/progress'
        if (!canAccessAdminPath(to)) return firstAccessibleAdminPath()
    }

    // 4. 登录页处理:已登录用户重定向到工作台/后台
    if (to.path === '/login' && getToken()) {
        return hasAdminAccess() ? firstAccessibleAdminPath() : '/progress'
    }
})
  • 登录检查:requiresSiteLogin 由路由 meta.requiresSiteLogin 标记;requiresAdminAuth 匹配 /admin 前缀(/admin/login 除外)。未登录统一重定向到 OIDC 授权页。
  • 未激活拦截:除激活页/登录页/auth 回调外,未激活用户强制跳转 /activation。
  • 权限检查:按 meta.permissions 判断,无权限回落到第一个可访问的后台路径。
  • OIDC 流程:登录态统一由 /auth/callback 接收授权码并换取 Token,失效 Token 通过 authApi.me() 校验后清除会话,避免重定向循环。

前台路由(SiteLayout 子路由)

路径页面说明需登录
/Home.vue首页
/aboutAbout.vue关于我们(根级路由)
/nextNextPage.vue加入开放原子(根级路由)
/activitiesActivities.vue活动列表
/activities/:idActivityDetail.vue活动详情
/applyRecruitment.vue招新信息
/apply/:idApplicationForm.vue报名表单填写
/forms/:idSiteForm.vue在线表单填写
/blogBlog.vue博客列表
/blog/:idBlogDetail.vue博客详情
/blog/myMyBlog.vue我的博客✓
/blog/writeMyBlog.vue写博客✓
/regulationsRegulations.vue规章制度列表
/regulations/:idRegulations.vue制度详情
/appsApps.vue应用展示
/apps/:idAppDetail.vue应用详情
/partnersPartners.vue合作社团
/open-platformOpenPlatform.vue数据开放平台
/votesVotes.vue社区投票
/votes/:idVotes.vue投票详情
/pointsPoints.vue社区积分
/calendarSchoolCalendar.vue校历查看
/alumni-managersAlumniManagers.vue往届/校友展示
/imagesImageHosting.vue图床服务✓
/workspaceWorkspace.vue个人工作台✓
/progressApplicationProgress.vue我的申请进度✓
/membersMembers.vue社团成员✓
/members/:slugMemberProfile.vue成员主页✓
/profileMemberProfile.vue我的主页✓
/profile/editProfileEditor.vue编辑主页✓
/settings/accountProfile.vue账号与安全✓
/notificationsNotifications.vue通知中心✓
/leavesLeaves.vue我的请假✓
/evening-studyEveningStudy.vue晚自习签到✓

根级路由

路径页面说明
/check-in/scanCheckInScan.vue扫码签到
/qr-screenQrScreen.vue二维码大屏
/lottery/:id/screenLotteryScreen.vue抽奖大屏
/doc-edit/:idDocEditorPage.vue文档编辑(需登录)
/shared-edit/:idSharedEditPage.vue共享文档编辑(需登录)
/loginLogin.vue登录页
/activationActivation.vue账号激活
/auth/callbackAuthCallback.vueOIDC 认证回调
/auth/github/callbackGithubAuthCallback.vueGitHub 登录回调
/auth/gitee/callbackGiteeAuthCallback.vueGitee 登录回调
/:pathMatch(.*)*NotFound.vue404

管理后台路由

路径页面说明权限
/admin/dashboardDashboard.vue仪表盘登录
/admin/usersUsers.vue用户管理user:list
/admin/clubsClubs.vue社团管理club:list
/admin/departmentsDepartments.vue部门管理department:list
/admin/positionsPositions.vue岗位管理position:list
/admin/groupsGroups.vue统一分组中心group:list
/admin/groups/createGroupEditor.vue新建分组group:create
/admin/groups/:groupIdGroupEditor.vue分组管理group:detail
/admin/bot-groupsBotGroups.vue机器人群管理bot-management:list
/admin/alumni-groupsAlumniGroups.vue校友分组membership:list
/admin/membershipsMemberships.vue成员管理membership:list
/admin/alumni-managersAlumniManagers.vue往届管理membership:list
/admin/activation-settingsActivationSettings.vue激活设置club:update 等
/admin/recruitment-campaignsRecruitmentCampaigns.vue招新计划recruitment-campaign:list
/admin/applicationsApplications.vue入会申请application:list
/admin/interviewsInterviews.vue面试管理interview:list
/admin/activitiesActivities.vue活动管理activity:list
/admin/ai-activitiesAiActivityAutomation.vueAI 活动自动化activity:create
/admin/check-insCheckIns.vue签到管理check-in:list
/admin/leavesLeaves.vue请假管理leave-application:list
/admin/awardsAwards.vue获奖管理award:list
/admin/notificationsNotifications.vue通知管理notification:list
/admin/office-documentsOfficeDocuments.vue文书管理document:list
/admin/doc-centerDocCenter.vue文档中心document:list
/admin/school-calendarSchoolCalendar.vue校历管理school-calendar:manage
/admin/regulationsRegulations.vue规章管理regulation:list
/admin/rolesRoles.vue角色管理role:list 等
/admin/site-formsSiteForms.vue表单管理site-form:list
/admin/form-submissionsFormSubmissions.vue表单提交site-form:detail
/admin/lotteriesLotteries.vue抽奖管理lottery:list
/admin/votesVotes.vue投票管理vote:list
/admin/pointsPoints.vue积分管理point:*:list
/admin/blogsBlogs.vue博客管理blog:list
/admin/member-profile-commentsMemberProfileComments.vue主页评论管理member-profile-comment:list
/admin/imagesImages.vue图床管理image:list
/admin/showcase-appsShowcaseApps.vue应用展示showcase-app:list
/admin/partner-clubsPartnerClubs.vue合作社团partner-club:list
/admin/data-openDataOpen.vue数据开放data-open:list
/admin/oauth-clientsOauthClients.vueOAuth 管理oauth-client:list
/admin/qr-centerQrCenter.vue二维码中心登录
/admin/file-migrationFileMigration.vue文件迁移file:migration:*
/admin/logsLogs.vue日志查看log:operation:list 等

路由懒加载与重试

所有页面组件使用动态导入,并实现重试机制:

function resilientView(loader: () => Promise<any>) {
    return async () => {
        let lastError: unknown
        for (let attempt = 0; attempt <= ROUTE_LOAD_RETRIES; attempt++) {
            try {
                return await loader()
            } catch (error) {
                lastError = error
                if (!isRecoverableRouteLoadError(error) || attempt === ROUTE_LOAD_RETRIES) break
                await waitForOnline()
                await sleep(450 * 2 ** attempt)
            }
        }
        throw lastError
    }
}

当动态导入失败(网络问题或部署路径变化)时,自动等待网络恢复并重试 2 次;恢复失败后 router.onError 会通过 sessionStorage 记录并在 700ms 后整页刷新恢复。

权限工具函数

函数说明
hasAdminAccess()是否可访问管理后台(拥有任意后台权限或超管角色)
hasAnyPermission(permissions)拥有指定权限列表中的任意一个
getToken() / setSession() / clearSession()会话 Token 读写与清理
isActivated()账号是否已完成激活
shouldUseFullPageAuthRedirect(redirect)是否使用整页重定向完成 OIDC 流程
buildOidcAuthorizeUrl(target)构建 OIDC 授权 URL
appendTokenQuery(url)追加 Token 查询参数
Prev
前端项目结构
Next
API 请求层