---
name: swing-cli-role-assign
description: "Swing System 角色权限分配。查询平台角色，将菜单/页面路由和按钮 action 权限分配给指定角色。当用户说「分配角色」「角色权限」「授权」「分配权限」「给角色配置菜单」时使用。"
---

# swing-cli-role-assign — 角色权限分配

> 查询已有角色，将创建好的 MENU/PAGE 路由和按钮 action 权限分配给指定角色。
>
> **核心原则：先查后对比，只分配缺失项。** 每一步都必须查询角色已有权限，与目标权限对比，仅对缺失部分执行分配。

## Workflow

### [Step 1/6] 前置检查

执行 `swing-cli config get` + `swing-cli auth status`，用户确认 server 和登录信息。
确认站点 siteId（使用 UUID）。

### [Step 2/6] 查询角色列表

```bash
swing-cli role list --site <siteId>
```

打印全部角色。询问用户选择要分配权限的角色，记录 roleId（注意：role list 返回的 `id` 字段是真正的角色 ID，不是 `name`）。

### [Step 3/6] 查询角色已有权限

```bash
# 查询角色已有的路由
swing-cli role routes <roleId> --site <siteId>

# 查询角色已有的 action
swing-cli role actions <roleId> --site <siteId>
```

> **注意**：`role routes` 和 `role actions` 的参数是角色的数据库 `id`（如 `"1"`），不是 `name`（如 `"Admin"`）。

### [Step 4/6] 对比确认

将角色**已有**的权限与**待分配**的权限进行逐项对比，按以下格式展示：

```
【角色】{displayName} (ID: {roleId})

━━━ 路由权限 ━━━
状态 | 类型 | 名称            | routeId
────┼──────┼─────────────────┼────────────────────────────
✅  | MENU | 仓库管理         | ...-10001003
✅  | MENU | 库存台账         | ...-100010031001
⏳  | PAGE | 原辅料库存台账    | ...-1000100310011000   ← 待分配
...

━━━ 按钮权限 ━━━
状态 | 页面           | action                  | actionId
────┼───────────────┼─────────────────────────┼────────────────────
✅  | 原辅料库存台账  | add-raw-sub-record-inv  | 2075157303943806977
⏳  | 原辅料库存台账  | view-raw-sub-record-inv | ...               ← 待分配
...
```

> **关键规则**：
> 1. 必须通过 `role routes` 和 `role actions` 实际查询角色的当前权限，**不得假设**任何权限已存在或不存在
> 2. 逐项对比每个 routeId 是否在角色已有路由列表中，每个 actionId 是否在角色已有 action 列表中
> 3. ✅ = 已分配，⏳ = 待分配，❌ = 不存在但未在计划中（需向用户说明）
> 4. 只有 ⏳ 状态的项才会进入执行步骤

用户确认对比结果后进入下一步。

### [Step 5/6] 执行分配（仅 ⏳ 项）

#### 分配路由

```bash
# swing-cli role assign-route 是替换式分配（PATCH），会替换角色所有路由
# 因此需要把角色已有路由 + 新增路由合并后一次性提交
# 合并所有 routeId（已有的 + 新增的）
swing-cli role assign-route <roleId> --route-ids "<id1>,<id2>,<id3>,..."
```

#### 分配 Action

```bash
# 每个页面分一组，按 routeId 分组
swing-cli role assign-action <roleId> --route-id <routeId> --action-ids "<id1>,<id2>,..."
```

> **重要**：`role assign-route` 和 `role assign-action` 都是**替换式**操作（PATCH），提交时会替换角色当前所有相关权限。因此：
> - 分配路由时：必须**合并**角色已有 routeId + 新增 routeId 一起提交
> - 分配 action 时：必须**合并**角色该 routeId 下已有的 actionId + 新增 actionId 一起提交
>
> 每次执行前展示完整命令，用户确认后才执行。

### [Step 6/6] 验证

```bash
# 查看角色已分配的路由
swing-cli role routes <roleId>

# 查看角色已分配的 action
swing-cli role actions <roleId>
```

展示分配后的完整权限列表，用户确认结果。
