Files
eaiadmin 90031b75f3 docs: 重构仓库文档目录并迁移训练素材
按当前架构重组 docs 目录,统一中文命名与目录分层,并将训练原材料迁移到独立目录以保持架构文档边界清晰。
2026-09-22 23:23:16 +08:00

5.8 KiB
Raw Permalink Blame History

DR02 — 导航与路由访问规则

版本:V1.1 | 左导航布局 | Vue3 + Element Plus + Vue Router 参考:pj006-zhilianyuan2 frontend-orgadmin 的路由守卫模式

⚠️ 本文为 V1 导航基线。 当前正式导航与对象化工作台口径,请以 SY22_Role_Skill_App_Unified_Task_Architecture.md 为准: 新建任务 / 项目 / 专员·技能·APP·连接器 / 长程APP / 知识库 / 后台管理 / 我的

本文第 1 节菜单树、路由示例和权限说明,主要用于保留早期培训平台的导航与鉴权基线。 其中出现的“首页 / 公司介绍培训 / 产品知识 / 产品销售培训 / 考试 / 知识管理 / 系统管理”,都应理解为 V1 历史结构,而不是当前目标导航。


1. 导航菜单可见性规则

菜单 可见角色 类型 说明
首页 employee + admin 一级菜单 所有人可见
公司介绍培训 employee + admin 一级菜单 所有人可见
产品知识 employee + admin 一级菜单 所有人可见
产品销售培训 employee + admin 一级菜单 所有人可见
考试 employee + admin 一级展开 所有人可见
├ 自测练习 employee + admin 子菜单 —
├ 正式结业考试 employee + admin 子菜单 —
├ 我的考试记录 employee + admin 子菜单 —
└ 题库管理 admin only 子菜单 管理员专属,员工不可见
知识管理 admin only 一级展开 管理员专属,员工不可见
├ 课件素材管理 admin only 子菜单 —
└ 素材审批列表 admin only 子菜单 —
系统管理 admin only 一级展开 管理员专属,员工不可见
├ 用户账号管理 admin only 子菜单 —
├ 全部考试成绩 admin only 子菜单 —
└ 系统参数配置 admin only 子菜单 —

2. 路由守卫实现

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/store/auth'

const routes = [
  {
    path: '/login',
    component: () => import('@/views/Login.vue'),
    meta: { requiresAuth: false },
  },
  {
    path: '/',
    component: MainLayout,
    children: [
      // 员工 + 管理员都能访问
      { path: '', component: () => import('@/views/home/HomeView.vue') },
      { path: 'company-train', component: () => import('@/views/companyTrain/CompanyTrainView.vue') },
      { path: 'products', component: () => import('@/views/product/ProductList.vue') },
      { path: 'products/:id', component: () => import('@/views/product/ProductDetail.vue') },
      { path: 'courses', component: () => import('@/views/salesTrain/CourseList.vue') },
      { path: 'courses/:id', component: () => import('@/views/salesTrain/CourseDetail.vue') },
      { path: 'exam/self-test', component: () => import('@/views/exam/ExamSelfTest.vue') },
      { path: 'exam/formal', component: () => import('@/views/exam/ExamFormal.vue') },
      { path: 'exam/my-records', component: () => import('@/views/exam/ExamMyRecord.vue') },

      // 管理员专属路由
      {
        path: 'exam/questions',
        component: () => import('@/views/exam/ExamQuestionBank.vue'),
        meta: { requiresAdmin: true },
      },
      {
        path: 'knowledge/materials',
        component: () => import('@/views/knowledge/MaterialManage.vue'),
        meta: { requiresAdmin: true },
      },
      {
        path: 'knowledge/audit',
        component: () => import('@/views/knowledge/MaterialAuditList.vue'),
        meta: { requiresAdmin: true },
      },
      {
        path: 'system/users',
        component: () => import('@/views/system/UserManage.vue'),
        meta: { requiresAdmin: true },
      },
      {
        path: 'system/exam-records',
        component: () => import('@/views/system/ExamRecordManage.vue'),
        meta: { requiresAdmin: true },
      },
      {
        path: 'system/config',
        component: () => import('@/views/system/SystemConfig.vue'),
        meta: { requiresAdmin: true },
      },
    ],
  },
]

const router = createRouter({ history: createWebHistory(), routes })

// 路由守卫
router.beforeEach((to, from, next) => {
  if (to.path === '/login') {
    next()
    return
  }

  const authStore = useAuthStore()

  // 未登录 → 跳转登录页
  if (!authStore.isLoggedIn) {
    next('/login')
    return
  }

  // 管理员路由校验(⚠️ 前端仅作 UX 隐藏,非安全边界)
  if (to.meta.requiresAdmin && authStore.user?.role !== 'admin') {
    next('/')
    return
  }

  next()
})

export default router

3. 后端鉴权对应规则

路由 后端校验 说明
/api/auth/* 仅 login 无需认证 —
/api/company-train/* 需有效 JWT 员工/管理员均可
/api/products/* 需有效 JWT 员工/管理员均可
/api/courses/* 需有效 JWT 员工/管理员均可
/api/exam/list|cover|start|submit|record 需有效 JWT 学员端考试
/api/exam/questions|papers 需 admin 角色 题库/考试配置管理
/api/media/upload|preview|status 需有效 JWT 文件操作
/api/media/audit* 需 admin 角色 素材审批
/api/system/* 需 admin 角色 系统管理全部
/api/ai-chat/* 需有效 JWT 员工/管理员均可
/api/health 无需认证 健康检查

4. 安全边界说明

前端路由守卫仅提供用户体验层面的菜单隐藏和路径拦截,不能作为安全边界。 所有权限校验必须在后端 API 层强制执行。

即使员工通过直接输入 URL 访问 /knowledge/materials:

  1. 前端路由守卫会拦截并重定向 → UX 保护
  2. 如果前端拦截被绕过,后端 API 返回 403 → 真正安全边界