---
title: 递归获取所有部门
description: 从根部门开始，结合分页遍历完整部门树。
sidebar_label: 递归获取所有部门
sidebar_position: 5
---

# 递归获取所有部门

部门接口只返回指定节点的直属子部门。获取完整组织树时，需要从根部门开始，对每个节点分页查询并继续遍历。

## 调用顺序

1. 调用[查询部门详情](/api/alimailpb-ud-department-service-get-department)，使用 `$root` 获取根部门。
2. 调用[查询子部门列表](/api/alimailpb-ud-department-service-list-sub-departments)。
3. 按 `offset` 和 `limit` 读取当前节点的全部直属子部门。
4. 将子部门加入待处理队列，直到队列为空。

## Python 示例

```python runtimeApiEndpoint
from collections import deque
import requests

API_BASE = "https://alimail-cn.aliyuncs.com"


def list_all_departments(access_token: str) -> list[dict]:
    headers = {"Authorization": f"Bearer {access_token}"}
    root = requests.get(
        f"{API_BASE}/v2/departments/$root",
        headers=headers,
        timeout=15,
    )
    root.raise_for_status()

    result = [root.json()]
    pending = deque([root.json()["id"]])
    while pending:
        parent_id = pending.popleft()
        offset = 0
        while True:
            response = requests.get(
                f"{API_BASE}/v2/departments/{parent_id}/departments",
                headers=headers,
                params={"offset": offset, "limit": 100},
                timeout=15,
            )
            response.raise_for_status()
            payload = response.json()
            children = payload.get("departments", [])
            result.extend(children)
            pending.extend(item["id"] for item in children)
            offset += len(children)
            if offset >= payload.get("total", 0) or not children:
                break
    return result
```

大型组织应增加重试、速率限制和断点记录，并使用部门 ID 去重，避免异常数据导致重复遍历。

参考：[原始示例](https://help.aliyun.com/zh/document_detail/2856733.html)。
