取得部門列表
分頁取得指定父部門下的直接子部門列表。
介面資訊
| 項目 | 說明 |
|---|---|
| 介面名稱 | 取得部門列表 |
| 權限標識 | contact.department.read(讀取組織架構) |
| 請求方式 | POST / GET |
| 請求地址 | https://{gateway_host}/open/v1/contact/department/list |
| 資料格式 | application/json(POST 時)或 URL Query |
| 鑑權方式 | 應用級 access_token(需具備 contact.department.read 權限) |
前置條件
- 應用已在管理後臺「內部應用」中發布並啟用。
- 已取得有效的應用級
access_token。 - 父部門必須存在且在應用的可見範圍內。
請求參數
| 參數名 | 類型 | 必填 | 說明 |
|---|---|---|---|
access_token | string | 是 | 應用級令牌(未在 Authorization 標頭中攜帶時必填) |
dept_id | string | 否 | 父部門 ID。省略或傳入 "0" 時,返回應用可見範圍內的頂層部門 |
cursor | string | 否 | 從 0 開始的數字分頁偏移量,預設 0;相容別名 next_cursor、nextCursor |
size | integer | 否 | 每頁數量,範圍 1–100,預設 100 |
language | string | 否 | 語言/國際化保留參數,目前不影響返回內容 |
請求範例
POST https://{gateway_host}/open/v1/contact/department/list
Authorization: Bearer <access_token>
Content-Type: application/json
{ "dept_id": "0", "cursor": "0", "size": 50 }
GET https://{gateway_host}/open/v1/contact/department/list?dept_id=0&cursor=0&size=50
Authorization: Bearer <access_token>
回應參數
{
"code": 200,
"msg": "",
"data": {
"departments": [
{ "deptId": "20", "name": "研發部", "parentId": "10", "order": 1 },
{ "deptId": "30", "name": "市場部", "parentId": "10", "order": 2 }
],
"hasMore": true,
"nextCursor": "2"
}
}
| 欄位 | 類型 | 說明 |
|---|---|---|
code | integer | 業務狀態碼;200 表示成功 |
msg | string | 訊息;成功時為空 |
data.departments | object[] | 直接子部門列表 |
data.departments[].deptId | string | 部門 ID |
data.departments[].name | string | 部門名稱 |
data.departments[].parentId | string | 父部門 ID;父部門超出可見範圍時截斷為 "0" |
data.departments[].order | integer | 同級部門的排序權重 |
data.hasMore | boolean | 是否還有資料;為 true 表示遍歷尚未完成 |
data.nextCursor | string | 下一頁游標;僅在 hasMore=true 時返回,下一次請求作為 cursor 傳入 |
遍歷與組織樹指南
- 逐層取得:本介面只返回指定部門的直接子部門,不會遞迴展開整棵樹。
- 完整遍歷建議:先以
dept_id="0"取得頂層部門,再逐一按層呼叫本介面向下遍歷,最後對每個部門呼叫取得部門成員列表組裝完整通訊錄。 - 分頁終止條件:使用
hasMore == false作為迴圈終止條件。
可見範圍與組織遍歷
應用可見範圍會同時影響工作臺展示、免登和通訊錄返回結果。範圍外的成員或部門會被視為不存在。
建議遍歷順序
- 不傳
dept_id呼叫部門列表介面,取得可見範圍內的頂層節點。 - 對每個部門遞迴呼叫部門列表介面,直到沒有子部門。
- 對每個部門呼叫部門成員列表介面,並按
userId合併記錄。 - 將事件訂閱作為變更信號,並定期執行完整對帳。
語義約束
parentId="0"只表示可見範圍內的頂層節點,不一定是企業真實根部門。- 可見範圍變更後,後續請求會立即按新範圍過濾,不需要重新換取
access_token。 - 一名成員可能屬於多個部門;
deptIdList只包含應用可見的部門。 - 以
hasMore作為唯一判斷依據,不要用當前頁數量小於size判斷是否結束。
組織遍歷範例
Shell
# 先讀取頂層部門,再將 nextCursor 原樣傳入下一頁。
curl -sS -X POST "https://{gateway_host}/open/v1/contact/department/list" -H "Authorization: Bearer access-token-xxx" -H "Content-Type: application/json" -d '{"cursor":"0","size":100}'
PHP
<?php
// 生產環境應使用佇列遍歷部門,避免遞迴深度不可控。
$url = 'https://{gateway_host}/open/v1/contact/department/list?cursor=0&size=100';
$handle = curl_init($url); curl_setopt_array($handle, [CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer access-token-xxx'], CURLOPT_RETURNTRANSFER => true]); echo curl_exec($handle); curl_close($handle);
Golang
package main
import "net/http"
func main() {
// 真實同步任務應使用佇列,並按 userId 去重。
request, _ := http.NewRequest(http.MethodPost, "https://{gateway_host}/open/v1/contact/department/list?cursor=0&size=100", nil); request.Header.Set("Authorization", "Bearer access-token-xxx"); response, _ := http.DefaultClient.Do(request); defer response.Body.Close()
}
C++
#include <curl/curl.h>
int main() {
// 不要硬編碼單一根部門 ID,應從介面返回的頂層節點開始。
CURL* handle = curl_easy_init(); struct curl_slist* headers = curl_slist_append(nullptr, "Authorization: Bearer access-token-xxx"); curl_easy_setopt(handle, CURLOPT_URL, "https://{gateway_host}/open/v1/contact/department/list?cursor=0&size=100"); curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(handle, CURLOPT_POST, 1L); const CURLcode result = curl_easy_perform(handle); curl_slist_free_all(headers); curl_easy_cleanup(handle); return result == CURLE_OK ? 0 : 1;
}
事件只表示可能發生變更,不能取代最終查詢;請參閱事件訂閱。
資料規則
- 可見範圍外的資料視為不存在,應用無法透過錯誤碼區分「不存在」和「不可見」。
- 部門列表介面返回直接子部門,成員列表介面返回直接成員;完整同步遵循可見範圍與組織遍歷。
- 成員 ID 和部門 ID 使用字串;未設定的可選欄位可能省略。
- 列表介面使用
cursor、size、hasMore和nextCursor分頁。
請參閱接入指南。
錯誤碼
| HTTP 狀態碼 | msg 錯誤碼 | 說明 |
|---|---|---|
| 401 | INVALID_TOKEN | 令牌缺失、過期、撤銷,或應用不可用 |
| 403 | SCOPE_DENIED | 令牌缺少 contact.department.read 權限 |
| 403 | IP_DENIED | 來源 IP 不在應用安全設定的 IP 白名單中 |
200 / code=500 | INVALID_REQUEST | cursor 不是有效數字或超出範圍,或 size 不在 1–100 之間 |
200 / code=500 | DEPARTMENT_NOT_FOUND | 父部門不存在、已刪除或超出應用可見範圍 |
200 / code=500 | PERMISSION_DENIED | 應用狀態無效 |
200 / code=500 | SERVER_ERROR | 服務端異常,請稍後重試 |
多語言呼叫範例
Shell
curl -sS -X POST "https://{gateway_host}/open/v1/contact/department/list" -H "Authorization: Bearer access-token-xxx" -H "Content-Type: application/json" -d '{"dept_id":"0","cursor":"0","size":50}'
PHP
<?php
// 生產環境應檢查 HTTP 狀態和回應體,再映射業務錯誤。
$handle = curl_init('https://{gateway_host}/open/v1/contact/department/list'); curl_setopt_array($handle, [CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer access-token-xxx', 'Content-Type: application/json'], CURLOPT_POSTFIELDS => '{"dept_id":"0","cursor":"0","size":50}', CURLOPT_RETURNTRANSFER => true]); echo curl_exec($handle); curl_close($handle);
Golang
package main
import ("bytes"; "net/http")
func main() { request, _ := http.NewRequest(http.MethodPost, "https://{gateway_host}/open/v1/contact/department/list", bytes.NewBufferString(`{"dept_id":"0","cursor":"0","size":50}`)); request.Header.Set("Authorization", "Bearer access-token-xxx"); response, _ := http.DefaultClient.Do(request); defer response.Body.Close() }
C++
#include <curl/curl.h>
int main() { CURL* handle = curl_easy_init(); struct curl_slist* headers = curl_slist_append(nullptr, "Authorization: Bearer access-token-xxx"); curl_easy_setopt(handle, CURLOPT_URL, "https://{gateway_host}/open/v1/contact/department/list"); curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(handle, CURLOPT_POSTFIELDS, R"({"dept_id":"0","cursor":"0","size":50})"); const CURLcode result = curl_easy_perform(handle); curl_slist_free_all(headers); curl_easy_cleanup(handle); return result == CURLE_OK ? 0 : 1; }