Skip to content

菜单、路由与权限 ​

资源类型常量 ​

ts
export const RESOURCE_TYPE = {
  MENU: 1,
  PAGE: 2,
  BUTTON: 3,
  API: 4,
  GROUP: 5,
} as const;

判断资源类型使用精确等值,不使用 type <= 2 之类依赖数字顺序的逻辑。

侧栏生成 ​

前端从 mineResources 得到资源树后:

  1. 过滤禁用资源。
  2. 展开辅助分组。
  3. 只保留菜单和页面资源。
  4. 过滤不可见节点。
  5. 规范化父子路径。
  6. 只展示当前角色已勾选的节点。
  7. 按 sort 排序。

外链菜单根据 isLink 和 linkUrl 打开,不作为内部 Vue 路由。

固定与动态路由 ​

系统核心页面有固定组件映射,例如:

ts
'system/user/index': UserManage
'system/role/index': RoleManage
'system/menu/index': ResourceManage

后端新增的非系统页面可以通过 import.meta.glob 匹配组件并动态注册。无法解析的组件进入占位页,不应让整个路由初始化失败。

路由守卫 ​

  • /login 无需认证。
  • 没有 Token 时跳转登录并保留 redirect。
  • 有 Token 时先初始化用户和资源。
  • 初始化失败时清理会话并返回登录页。
  • 首页和个人中心忽略资源路径访问控制。
  • 普通业务页面不在可访问路径集合时,跳转第一个可访问页面;没有菜单时回到个人中心。

按钮权限 ​

ts
const canCreate = computed(() =>
  authStore.hasPermission("view:admin:sysUser:create"),
);

后端可能同时在 mine.permissions 和资源树节点中返回权限,前端合并为一个 Set。*:*:* 表示通配权限。

页面展示只检查当前权限标识是否存在,不根据接口路径猜测权限,也不要求每个接口都必须有同名按钮。

状态显示 ​

角色、组织、岗位或资源被禁用后:

  • 新选择时显示“名称(禁用)”并置灰。
  • 已绑定值允许回显。
  • 已绑定禁用值允许取消。
  • 保存原值时不应因为它已禁用而破坏回显。

常见错误 ​

  • 用接口权限直接控制按钮:应使用 view: 权限。
  • 只隐藏按钮但后端无权限注解:存在安全风险。
  • 同一个挂载接口节点使用相同 resId 作为 Tree Key:会导致多位置联动。
  • 清空角色权限后没有刷新用户上下文:页面仍显示旧状态。
  • 角色没有菜单时把登录页也当作无权访问:导致 404 循环。

YeahBoot 官方技术文档