# 權限控制

- Human documentation: [https://docs.univer.ai/zh-TW/guides/sheets/features/core/permission](https://docs.univer.ai/zh-TW/guides/sheets/features/core/permission)

- Agent Markdown: [https://docs.univer.ai/zh-TW/guides/sheets/features/core/permission.md](https://docs.univer.ai/zh-TW/guides/sheets/features/core/permission.md)

- Requested language: `zh-TW`

- Content language: `zh-TW`

- Documentation version: `1.2.0`

- Source: [sheets/features/core/permission.zh-TW.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/features/core/permission.zh-TW.mdx)

---

Univer 提供權限控制能力，用於限制使用者對工作簿、工作表、選區的操作。當使用者執行無權限動作時，Univer 會中止執行並提示缺失權限。常見場景如：對一片選區設定保護，限制協作者的編輯/檢視/複製等能力。

> [!WARNING]
> 服務需要持久化保護規則與協作者變更，傳回目前使用者的權限，並傳遞請求失敗。傳回空清單的 mock 不具備持久化能力。協同情境下，後端仍須分別驗證讀取、JOIN 與修改權限，見[身分與權限](https://docs.univer.ai/zh-TW/server/collaboration/identity-and-authorization.md)。前端保護與隱藏陰影不能取代伺服器授權。
> 
> [權限服務整合](#authorization-service)

> Interactive example: [Open the playground](/playground/sheets/permission)

依任務跳轉到下方章節。本頁集中介紹基礎操作、進階範例、設定與疑難排解；完整 API 定義統一在 Reference 中維護。

* [常用任務](#permission-tasks)
* [權限介面設定](#permission-ui)
* [權限服務整合](#permission-integration)
* [Reference](#reference)

## 核心概念

* 作用範圍：權限可以作用在工作簿、工作表、選區三個層級。
* 權限點位：每個功能對應一個權限點位，修改點位即可控制功能是否可用。
* 保護規則：工作表和選區在設定權限點位前，需要先建立保護規則。

> [!INFO]
> 本地非持久化權限可直接修改權限點位；持久化整合見 [權限服務整合](#authorization-service)
> 
> 協同編輯場景下，更新權限點位會同步更新服務端狀態：
> 
> * false：該權限點至少需要 `owner` 角色
> * true：該權限點至少需要 `reader` 角色

## 基礎示例

使用 `allowedUsers` 範例前，請將 `user1`、`user2` 替換為權限服務已傳回的真實協作者 ID。

下面按工作簿、工作表、選區三個層級展示最常見的權限設定方式。

### 工作簿權限程式碼示例

工作簿層級權限透過 [Facade API](https://docs.univer.ai/zh-TW/guides/sheets/getting-started/facade.md) 直接修改權限點位即可。

以編輯權限為例（其他功能只需替換權限點位，參考[權限點位列表 - 工作簿](#workbook-point)）：

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// 設定工作簿不可編輯
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false)
```

要點：

* 工作簿權限點位可以直接設定，不需要建立保護規則。

### 工作表權限程式碼示例

工作表和選區相關的權限設定可以透過 Facade API 或命令系統實現。這裡以工作表編輯權限舉例，其他功能只需替換權限點位，參考[權限點位列表 - 工作表](#worksheet-point)。

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// 建立工作表保護, 允許指定使用者編輯
const permissionId = await worksheetPermission.protect({
  allowedUsers: ['user1', 'user2'],
  name: 'My Worksheet Protection',
})

// 如果需要設定權限點位，必須先建立工作表保護
await worksheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Edit, false)
```

#### 刪除工作表權限

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// 刪除工作表保護
await worksheetPermission.unprotect()
```

### 自訂選區權限程式碼示例

選區的權限同樣支援 API 和命令模式。這裡以選區編輯權限舉例，其他選區功能只需替換權限點位，參考[權限點位列表 - 選區](#range-point)。

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// 設定區域保護權限，允許指定使用者編輯但不允許他人檢視
const rule = await rangePermission.protect({
  name: 'My protected range',
  allowViewByOthers: false,
  allowedUsers: ['user1', 'user2'],
})
console.log(rule)

// 如果需要設定權限點位，必須先建立區域保護
await rule.setPoint(univerAPI.Enum.RangePermissionPoint.Edit, false)
await rule.setPoint(univerAPI.Enum.RangePermissionPoint.View, true)
```

#### 刪除區域保護權限

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// 刪除區域内所有保護規則
await rangePermission.unprotect()

// 或刪除區域内指定規則
const rules = await rangePermission.listRules()
if (rules.length > 0) {
  await rules[0].remove()
}
```

## 常用任務

### 將活頁簿設為唯讀

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const permission = fWorkbook.getWorkbookPermission()
await permission.setMode('viewer')
console.log(permission.getSnapshot())
```

### 管理保護範圍

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const permission = fWorksheet.getWorksheetPermission()

const createdRules = await permission.protectRanges([
  {
    ranges: [fWorksheet.getRange('A1:B2')],
    options: { name: 'Public area', allowViewByOthers: true },
  },
  {
    ranges: [fWorksheet.getRange('C3:D4')],
    options: { name: 'Private area', allowViewByOthers: false, allowedUsers: ['user1'] },
  },
])
console.log(createdRules)

const rules = await permission.listRangeProtectionRules()
const firstRule = rules[0]
if (firstRule) {
  await firstRule.updateRanges([fWorksheet.getRange('A1:B3')])
}
```

### 排查儲存格權限

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const permission = fWorkbook.getActiveSheet().getWorksheetPermission()
console.log(permission.debugCellPermission(0, 0))
```

## 權限點位列表

不同的功能權限由不同的權限點位控制，修改點位的值即可控制對應功能。具體點位程式碼請參閱[這裡](https://github.com/dream-num/univer/tree/dev/packages/sheets/src/services/permission/permission-point)。

如果 `workbook` 的權限控制和 `worksheet` / `range` 有交叉，那麼必須全部為 `true` 才能使用。例如一個單元格的編輯權限必須 `workbook` 和 `worksheet` 的編輯權限都為 `true` 才能編輯。

### 工作簿

| API 列舉                                                    | 對應權限點位類                              | 描述        |
| --------------------------------------------------------- | ------------------------------------ | --------- |
| univerAPI.Enum.WorkbookPermissionPoint.Edit               | WorkbookEditablePermission           | 能否編輯      |
| univerAPI.Enum.WorkbookPermissionPoint.View               | WorkbookViewPermission               | 能否檢視      |
| univerAPI.Enum.WorkbookPermissionPoint.Print              | WorkbookPrintPermission              | 能否列印      |
| univerAPI.Enum.WorkbookPermissionPoint.Export             | WorkbookExportPermission             | 能否匯出      |
| univerAPI.Enum.WorkbookPermissionPoint.Share              | WorkbookSharePermission              | 能否分享      |
| univerAPI.Enum.WorkbookPermissionPoint.CopyContent        | WorkbookCopyPermission               | 能否複製      |
| univerAPI.Enum.WorkbookPermissionPoint.DuplicateFile      | WorkbookDuplicatePermission          | 能否複製文件    |
| univerAPI.Enum.WorkbookPermissionPoint.Comment            | WorkbookCommentPermission            | 能否評論      |
| univerAPI.Enum.WorkbookPermissionPoint.ManageCollaborator | WorkbookManageCollaboratorPermission | 能否管理協作者   |
| univerAPI.Enum.WorkbookPermissionPoint.CreateSheet        | WorkbookCreateSheetPermission        | 能否建立工作表   |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteSheet        | WorkbookDeleteSheetPermission        | 能否刪除工作表   |
| univerAPI.Enum.WorkbookPermissionPoint.RenameSheet        | WorkbookRenameSheetPermission        | 能否重新命名工作表 |
| univerAPI.Enum.WorkbookPermissionPoint.MoveSheet          | WorkbookMoveSheetPermission          | 能否移動工作表   |
| univerAPI.Enum.WorkbookPermissionPoint.HideSheet          | WorkbookHideSheetPermission          | 能否隱藏工作表   |
| univerAPI.Enum.WorkbookPermissionPoint.CopySheet          | WorkbookCopySheetPermission          | 能否複製工作表   |
| univerAPI.Enum.WorkbookPermissionPoint.ViewHistory        | WorkbookViewHistoryPermission        | 能否檢視歷史記錄  |
| univerAPI.Enum.WorkbookPermissionPoint.RecoverHistory     | WorkbookRecoverHistoryPermission     | 能否恢復歷史記錄  |
| univerAPI.Enum.WorkbookPermissionPoint.CreateProtection   | WorkbookCreateProtectPermission      | 能否建立保護    |
| univerAPI.Enum.WorkbookPermissionPoint.InsertRow          | WorkbookInsertRowPermission          | 能否插入行     |
| univerAPI.Enum.WorkbookPermissionPoint.InsertColumn       | WorkbookInsertColumnPermission       | 能否插入列     |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteRow          | WorkbookDeleteRowPermission          | 能否刪除行     |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteColumn       | WorkbookDeleteColumnPermission       | 能否刪除列     |

### 工作表

| API 列舉                                                         | 對應權限點位類                                   | 描述          |
| -------------------------------------------------------------- | ----------------------------------------- | ----------- |
| univerAPI.Enum.WorksheetPermissionPoint.Edit                   | WorksheetEditPermission                   | 能否編輯        |
| univerAPI.Enum.WorksheetPermissionPoint.View                   | WorksheetViewPermission                   | 能否檢視        |
| univerAPI.Enum.WorksheetPermissionPoint.Copy                   | WorksheetCopyPermission                   | 能否複製        |
| univerAPI.Enum.WorksheetPermissionPoint.SetCellValue           | WorksheetSetCellValuePermission           | 能否編輯單元格值    |
| univerAPI.Enum.WorksheetPermissionPoint.SetCellStyle           | WorksheetSetCellStylePermission           | 能否編輯單元格樣式   |
| univerAPI.Enum.WorksheetPermissionPoint.SetRowStyle            | WorksheetSetRowStylePermission            | 能否設定行樣式     |
| univerAPI.Enum.WorksheetPermissionPoint.SetColumnStyle         | WorksheetSetColumnStylePermission         | 能否設定列樣式     |
| univerAPI.Enum.WorksheetPermissionPoint.InsertRow              | WorksheetInsertRowPermission              | 能否插入行       |
| univerAPI.Enum.WorksheetPermissionPoint.InsertColumn           | WorksheetInsertColumnPermission           | 能否插入列       |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteRow              | WorksheetDeleteRowPermission              | 能否刪除行       |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteColumn           | WorksheetDeleteColumnPermission           | 能否刪除列       |
| univerAPI.Enum.WorksheetPermissionPoint.Sort                   | WorksheetSortPermission                   | 能否排序        |
| univerAPI.Enum.WorksheetPermissionPoint.Filter                 | WorksheetFilterPermission                 | 能否篩選        |
| univerAPI.Enum.WorksheetPermissionPoint.PivotTable             | WorksheetPivotTablePermission             | 能否使用透視表     |
| univerAPI.Enum.WorksheetPermissionPoint.InsertHyperlink        | WorksheetInsertHyperlinkPermission        | 能否使用超連結     |
| univerAPI.Enum.WorksheetPermissionPoint.ManageCollaborator     | WorksheetManageCollaboratorPermission     | 能否管理協作者     |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteProtection       | WorksheetDeleteProtectionPermission       | 能否刪除保護      |
| univerAPI.Enum.WorksheetPermissionPoint.EditExtraObject        | WorksheetEditExtraObjectPermission        | 能否編輯額外物件    |
| univerAPI.Enum.WorksheetPermissionPoint.SelectProtectedCells   | WorksheetSelectProtectedCellsPermission   | 能否選取受保護儲存格  |
| univerAPI.Enum.WorksheetPermissionPoint.SelectUnProtectedCells | WorksheetSelectUnProtectedCellsPermission | 能否選取未受保護儲存格 |

### 區域保護

| API 列舉                                                 | 對應權限點位類                                        | 描述           |
| ------------------------------------------------------ | ---------------------------------------------- | ------------ |
| univerAPI.Enum.RangePermissionPoint.Edit               | RangeProtectionPermissionEditPoint             | 能否編輯保護區域     |
| univerAPI.Enum.RangePermissionPoint.View               | RangeProtectionPermissionViewPoint             | 能否檢視保護區域的內容  |
| univerAPI.Enum.RangePermissionPoint.Delete             | RangeProtectionPermissionDeleteProtectionPoint | 能否刪除保護區域     |
| univerAPI.Enum.RangePermissionPoint.ManageCollaborator | RangeProtectionPermissionManageCollaPoint      | 能否管理保護區域的協作者 |

## 權限介面設定

### 權限保護範圍陰影策略

若要區分目前使用者可編輯和不可編輯的保護區域，請使用 `non-editable`：可編輯的保護區域不顯示陰影，編輯權限遭停用的保護區域保留陰影；不可檢視的保護範圍仍保留遮罩。

此設定控制範圍保護和工作表保護的顯示，不會建立保護規則或修改編輯、檢視權限，也不會在未受保護的區域新增陰影。請先依上文設定保護規則和目前使用者的權限。

| 策略                  | 顯示效果                      |
| ------------------- | ------------------------- |
| `true` / `'always'` | 顯示所有保護區域的陰影（預設）。          |
| `'non-editable'`    | 隱藏可編輯保護區域的陰影，保留不可編輯區域的陰影。 |
| `'non-viewable'`    | 僅顯示不可檢視保護區域的陰影。           |
| `false` / `'none'`  | 隱藏全部保護陰影，權限檢查仍然生效。        |



初始化時設定：

#### 外掛模式

```typescript
univer.registerPlugin(UniverSheetsUIPlugin, {
  protectedRangeShadow: 'non-editable',
})
```

#### 預設模式

```typescript
createUniver({
  presets: [
    UniverSheetsCorePreset({
      sheets: {
        protectedRangeShadow: 'non-editable',
      },
    }),
  ],
})
```

也可以透過 API 動態修改：

下方 Facade API 會更新目前 Univer 執行個體中既有活頁簿的顯示策略。外掛模式下需先匯入 `@univerjs/sheets-ui/facade`；Sheets Core 預設已包含此匯入。

```typescript
// 設定只顯示不可編輯範圍的陰影
univerAPI.setProtectedRangeShadowStrategy('non-editable')

// 獲取當前的權限保護範圍陰影顯示策略
console.log(univerAPI.getProtectedRangeShadowStrategy())

// 監聽權限保護範圍陰影顯示策略的變化
const subscription = univerAPI.getProtectedRangeShadowStrategy$().subscribe((strategy) => {
  console.log('Global strategy changed to:', strategy)
  // 更新 UI 或執行其他操作
})

// 稍後，取消訂閱以進行清理
subscription.unsubscribe()
```

### 自訂使用者元件

Univer 內建的自訂使用者元件所適配的場景比較有限，如果需要更復雜的自訂元件，可以透過以下方式進行自訂。

> [!NOTE]
> 可在[《自訂元件》](https://docs.univer.ai/zh-TW/guides/sheets/ui/components.md)檢視如何自訂元件。

#### 外掛模式

```typescript
univer.registerPlugin(UniverSheetsUIPlugin, {
  protectedRangeUserSelector: {
    /**
     * custom component, should implement the `IPermissionDetailUserPartProps` interface.
     */
    component: CustomPermissionDetailUserPart,
    /**
     * The framework of the component. Must be passed correctly.
     */
    framework: 'react',
  },
})
```

#### 預設模式

```typescript
const { univer } = createUniver({
  presets: [
    UniverSheetsCorePreset({
      sheets: {
        protectedRangeUserSelector: {
        /**
         * custom component, should implement the `IPermissionDetailUserPartProps` interface.
         */
          component: CustomPermissionDetailUserPart,
          /**
           * The framework of the component. Must be passed correctly.
           */
          framework: 'react',
        },
      },
    }),
  ],
})
```

在使用者選擇器的變更回呼中呼叫 `setSelectUserList()`。以下最小 React 範例清空已選使用者：`useDependency` 在元件內呼叫，服務狀態只在點擊後更新。完整選擇器請依 `IPermissionDetailUserPartProps` 實作。

#### 外掛模式

```tsx
import type { IPermissionDetailUserPartProps } from '@univerjs/sheets-ui'
import type { FC } from 'react'
import { SheetPermissionUserManagerService } from '@univerjs/sheets-ui'
import { useDependency } from '@univerjs/ui'

export const CustomPermissionDetailUserPart: FC<IPermissionDetailUserPartProps> = () => {
  const service = useDependency(SheetPermissionUserManagerService)
  const clearSelection = () => service.setSelectUserList([])

  return <button type="button" onClick={clearSelection}>清空已選使用者</button>
}
```

#### 預設模式

```tsx
import type { IPermissionDetailUserPartProps } from '@univerjs/preset-sheets-core'
import type { FC } from 'react'
import { SheetPermissionUserManagerService, useDependency } from '@univerjs/preset-sheets-core'

export const CustomPermissionDetailUserPart: FC<IPermissionDetailUserPartProps> = () => {
  const service = useDependency(SheetPermissionUserManagerService)
  const clearSelection = () => service.setSelectUserList([])

  return <button type="button" onClick={clearSelection}>清空已選使用者</button>
}
```

### 去除權限彈窗

```typescript
univerAPI.setPermissionDialogVisible(false)
```

## 權限服務整合

### 拓展使用

當你需要在自己的外掛中增加權限校驗時，可以直接操作權限點位。

下面以 `WorkbookEditablePermission` 為例，其他點位類似：

```typescript
import { IPermissionService } from '@univerjs/core'
import { WorkbookEditablePermission } from '@univerjs/sheets'

class YourService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
  }

  setWorkbookNotEditable() {
    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, false)
  }

  setWorkbookEditable() {
    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, true)
  }
}
```

[權限點位列表](#point-list)

### 第三方外掛如何擴充權限點位

如果你需要自訂權限點位，可以實現 `IPermissionPoint` 並註冊到權限服務中：

```typescript
import type { IPermissionPoint } from '@univerjs/core'
import { IPermissionService, PermissionStatus } from '@univerjs/core'
import { UnitAction, UnitObject } from '@univerjs/protocol'

export class CustomPermissionPoint implements IPermissionPoint {
  type = UnitObject.Unkonwn // your type
  subType = UnitAction.View // your subType
  status = PermissionStatus.INIT
  value = true // 權限的初始值
  id: string
  constructor(unitId: string, subUnitId: string, customId: string) {
    // 這裡自行拼湊一個 id，id 屬性需要保證在整個 IPermissionService 中是唯一的憑證。
    this.id = `${unitId}.${subUnitId}.${customId}`
  }
}

class YourService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
    this._init()
  }

  _init() {
    this._permissionService.addPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id'))
  }
}

// 在其他地方如何使用
class ConsumeService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
  }

  doSomething() {
    const point = this._permissionService.getPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)
    console.log(point?.value)
  }

  bindEvent() {
    // 這將獲得一個 Rx 物件，使得你能夠監聽當前權限的變化作出一些改變
    const point$ = this._permissionService.getPermissionPoint$(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)
    console.log(point$)
  }
}
```

### 第三方權限服務接入(進階用法)

在業務應用中實作 [IAuthzIoService](https://github.com/dream-num/univer/blob/dev/packages/core/src/services/authz-io/type.ts)，將權限、角色與協作者方法接入後端。以下範例假定 `./authorization-service` 已將該實作匯出為 `YourAuthzService`。請在建立活頁簿前註冊，並保留其他初始化選項與外掛註冊。

```typescript
import { IAuthzIoService, Univer } from '@univerjs/core'
import { YourAuthzService } from './authorization-service'

const univer = new Univer({
  override: [[IAuthzIoService, { useClass: YourAuthzService }]],
})
```

服務需要持久化保護規則與協作者變更，傳回目前使用者的權限，並傳遞請求失敗。傳回空清單的 mock 不具備持久化能力。協同情境下，後端仍須分別驗證讀取、JOIN 與修改權限，見[身分與權限](https://docs.univer.ai/zh-TW/server/collaboration/identity-and-authorization.md)。前端保護與隱藏陰影不能取代伺服器授權。

![權限](https://raw.githubusercontent.com/dream-num/documentation/dev/content/guides/sheets/features/core/permission/permission-cn.png)

### 協作者管理

> [!NOTE]
> 協作者管理由業務應用程式和權限服務負責。請接入自己的使用者與 ACL 模型，在伺服器端分別檢查讀取、JOIN 和修改權限，見[身分與權限](https://docs.univer.ai/zh-TW/server/collaboration/identity-and-authorization.md)。下方前端 API 需要匹配的權限服務實作，不會自動設定伺服器端權限。

* 獲取協作者列表

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

const collaborators = await workbookPermission.listCollaborators()
console.log(collaborators)
```

* 新增協作者

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// 一次新增多個協作者
await workbookPermission.setCollaborators([
  {
    user: { userID: 'user1', name: 'John Doe', avatar: 'https://...' },
    role: univerAPI.Enum.UnitRole.Editor,
  },
  {
    user: { userID: 'user2', name: 'Jane Smith', avatar: '' },
    role: univerAPI.Enum.UnitRole.Reader,
  },
])

// 新增單個協作者
await workbookPermission.addCollaborator(
  { userID: 'user1', name: 'John Doe', avatar: 'https://...' },
  univerAPI.Enum.UnitRole.Editor,
)
```

* 更新協作者角色

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

await workbookPermission.updateCollaborator(
  { userID: 'user1', name: 'John Doe Updated', avatar: 'https://...' },
  univerAPI.Enum.UnitRole.Reader,
)
```

* 刪除協作者

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// 刪除多個協作者
await workbookPermission.removeCollaborators(['user1', 'user2'])

// 刪除單個協作者
await workbookPermission.removeCollaborator('user1')
```

## Reference

* [FWorkbookPermission](https://docs.univer.ai/zh-TW/reference/facade/workbook-permission.md)
* [FWorksheetPermission](https://docs.univer.ai/zh-TW/reference/facade/worksheet-permission.md)
* [FRangePermission](https://docs.univer.ai/zh-TW/reference/facade/range-permission.md)
* [FRangeProtectionRule](https://docs.univer.ai/zh-TW/reference/facade/range-protection-rule.md)
