> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashduty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 自定义菜单

> 在 Flashduty 控制台侧边栏中嵌入自定义链接或内部页面，并通过角色权限控制可见性

自定义菜单允许管理员在控制台侧边栏中添加自定义导航项，将外部系统页面或内部链接直接嵌入 Flashduty 导航树。每个菜单项对应一个账户级权限点，由管理员按角色授权后方可在导航中显示。

**配置路径**：平台管理 → 自定义菜单

## 创建菜单

<Steps>
  <Step title="进入自定义菜单配置页">
    前往 **平台管理 → 自定义菜单**，点击 **新建菜单** 按钮。
  </Step>

  <Step title="填写菜单信息">
    按照以下字段填写菜单配置：

    | 字段                  | 是否必填 | 限制                | 说明                         |
    | ------------------- | :--: | ----------------- | -------------------------- |
    | **中文名称**（label\_zh） |  必填  | 最多 128 字符         | 菜单在中文界面显示的名称               |
    | **英文名称**（label\_en） |  选填  | 最多 128 字符         | 菜单在英文界面显示的名称；不填时英文界面沿用中文名称 |
    | **图标**（icon）        |  选填  | 最多 255 字符         | 菜单图标标识符                    |
    | **链接地址**（url）       |  必填  | 最多 2048 字符        | 点击菜单时跳转或嵌入的目标 URL          |
    | **打开方式**（mode）      |  必填  | `iframe` 或 `open` | 见下方说明                      |
    | **授权角色**            |  选填  | —                 | 指定可见该菜单的角色列表；不填则默认无成员可见    |
  </Step>

  <Step title="选择打开方式">
    打开方式决定用户点击菜单后的行为：

    * **iframe**：在控制台主内容区内嵌显示目标页面。适用于希望用户留在 Flashduty 界面内访问内部工具的场景，例如 Grafana 大盘、内部知识库等。目标页面需允许被 iframe 嵌套（即 HTTP 响应头 `X-Frame-Options` 不为 `DENY` / `SAMEORIGIN`）。
    * **open**：在浏览器新标签页中打开目标 URL。适用于外部系统或不支持 iframe 嵌入的页面。
  </Step>

  <Step title="配置授权角色">
    在 **授权角色** 字段中选择允许看到该菜单的角色。

    <Warning>
      系统预置角色（**Admin**、**Responder**、**Viewer**）不支持绑定到自定义菜单，因为它们在运行时已自动继承账户内所有权限。请使用**自定义角色**进行授权。
    </Warning>

    未选择任何角色时，该菜单对所有普通成员不可见（主体账号和 Admin 角色仍可通过管理界面访问）。
  </Step>

  <Step title="保存">
    点击 **保存** 完成创建。系统会自动为该菜单生成一个权限点（格式为 `customMenu:visit:<menu_id>`），并将其同步到所选角色的权限位图中。
  </Step>
</Steps>

## 编辑菜单

在菜单列表中点击目标菜单的 **编辑** 按钮，即可修改上述所有字段。

<Note>
  修改 **授权角色** 字段时，系统执行全量同步：新列表中的角色获得该菜单的访问权限，不在新列表中的角色将失去该权限。若不传授权角色字段，则保留原有绑定不变（仅用于修改名称、图标、URL 等字段时）。
</Note>

## 删除菜单

在菜单列表中点击 **删除** 按钮即可删除对应菜单。删除操作会同时移除关联的权限点，并从所有角色的权限位图中清除对应权限——**持有该角色的成员在下次登录或权限刷新后将不再看到该菜单入口**。

删除操作是幂等的：对已删除的菜单再次执行删除不会报错。

## 菜单排序

菜单列表支持拖拽调整顺序。系统使用 LexoRank 算法持久化排列位置，多次在同一位置插入后仍可正常排序。

## 配额限制

每个账户最多可创建 **100 个**自定义菜单。超出配额时，创建请求将返回错误，需先删除不再使用的菜单后方可继续新增。

## 权限说明

自定义菜单使用账户级动态权限，与系统内置权限平级展示于角色配置界面的 **自定义菜单** 分组下：

* **权限点命名**：`customMenu:visit:<menu_id>`，其中 `<menu_id>` 为菜单创建时由系统分配的唯一数字标识。
* **可见性控制**：仅被授予对应权限点的成员才能在导航侧边栏中看到该菜单项；未被授予的成员看不到该入口，也无法通过直接访问 URL 触发导航高亮。
* **主体账号**：主体账号（即账户创建者）绕过权限过滤，始终可见所有自定义菜单。
* **权限生命周期**：菜单删除后，其对应权限点随之失效，已写入角色位图的权限位也会同步清除；新增菜单后，需在角色配置界面重新将其授予目标角色，已有角色不会自动获得新菜单的访问权限。

<Tip>
  关于 `customMenu:visit:<menu_id>` 权限点在角色体系中的完整语义，请参阅[权限设计](/zh/platform/permission-design)中的「自定义菜单权限组」章节。
</Tip>

## 延伸阅读

<CardGroup cols={2}>
  <Card title="权限设计" icon="shield-halved" href="/zh/platform/permission-design">
    了解 Flashduty RBAC 权限体系与账户级动态权限
  </Card>

  <Card title="组织管理" icon="users" href="/zh/platform/team-members">
    管理团队和成员，配置角色与访问控制
  </Card>
</CardGroup>
