Skip to content

接口名称

部门管理API(用户令牌)- IFeishuUserV3Departments

功能描述

飞书组织机构部门是指企业组织架构树上的某一个节点。当前接口使用用户令牌访问,适用于用户应用场景,主要提供部门信息的查询功能。在部门内部,可添加用户作为部门成员,也可添加新的部门作为子部门。用户令牌版本具有权限限制,只能查看有权限访问的部门信息。

参考文档

https://open.feishu.cn/document/server-docs/contact-v3/department/field-overview

函数列表

函数名称功能描述认证方式HTTP 方法
GetDepartmentInfoByIdAsync获取单个部门信息用户令牌GET
GetDepartmentsByIdsAsync批量获取部门信息用户令牌GET
GetDepartmentsByParentIdAsync获取子部门列表用户令牌GET
GetParentDepartmentsByIdAsync获取父部门信息用户令牌GET

函数详细内容

函数名称:获取单个部门信息

函数签名

csharp
Task<FeishuApiResult<GetDepartmentInfoResult>?> GetDepartmentInfoByIdAsync(
    [Path] string department_id,
    [Query("user_id_type")] string? user_id_type = "open_id",
    [Query("department_id_type")] string? department_id_type = "open_department_id",
    CancellationToken cancellationToken = default);

认证:用户令牌

参数

参数名类型必填说明
department_idstring✅ 必填部门ID
user_id_typestring⚪ 可选用户ID类型,默认为"open_id"
department_id_typestring⚪ 可选部门ID类型,默认为"open_department_id"

响应

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "department": {
      "department_id": "od-1234567890",
      "name": "技术部",
      "parent_department_id": "0",
      "leader_user_id": "ou_1234567890",
      "leaders": [
        {
          "user_id": "ou_1234567890",
          "leader_type": 1
        }
      ],
      "primary_member_count": 25,
      "status": {
        "is_deleted": false
      },
      "create_group_chat": true
    }
  }
}

说明

  • 获取单个部门的详细信息,包括部门名称、ID、父部门、负责人、状态以及成员个数等
  • 使用用户令牌只能获取有权限查看的部门信息
  • 敏感信息(如某些字段)可能因为权限限制而不可见

代码示例

javascript
// 获取部门详细信息
async function getDepartmentDetails(departmentId) {
  const result = await feishuUserV3Departments.getDepartmentInfoByIdAsync(
    departmentId,
    "open_id",
    "open_department_id"
  );

  if (result.code === 0) {
    const dept = result.data.department;
    
    console.log("=== 部门详细信息 ===");
    console.log(`部门ID: ${dept.department_id}`);
    console.log(`部门名称: ${dept.name}`);
    console.log(`父部门ID: ${dept.parent_department_id}`);
    console.log(`部门主管: ${dept.leader_user_id || '未设置'}`);
    console.log(`主要成员数量: ${dept.primary_member_count}`);
    console.log(`部门状态: ${dept.status.is_deleted ? '已删除' : '正常'}`);
    console.log(`是否创建群聊: ${dept.create_group_chat ? '是' : '否'}`);
    
    // 显示负责人信息
    if (dept.leaders && dept.leaders.length > 0) {
      console.log("\n负责人列表:");
      dept.leaders.forEach((leader, index) => {
        const leaderType = leader.leader_type === 1 ? "部门主管" : "部门分管";
        console.log(`${index + 1}. ${leader.user_id} (${leaderType})`);
      });
    }
    
    // 显示HRBP信息(如果有权限)
    if (dept.department_hrbps && dept.department_hrbps.length > 0) {
      console.log("\nHRBP列表:");
      dept.department_hrbps.forEach((hrbp, index) => {
        console.log(`${index + 1}. ${hrbp}`);
      });
    }
    
    return dept;
  } else {
    console.error("获取部门信息失败:", result.msg);
    
    // 权限相关的错误处理
    if (result.code === 403) {
      console.log("权限不足,无法查看该部门信息");
    } else if (result.code === 404) {
      console.log("部门不存在或已被删除");
    }
    
    return null;
  }
}

// 使用示例:获取并分析部门信息
async function analyzeDepartment(departmentId) {
  const dept = await getDepartmentDetails(departmentId);
  
  if (dept) {
    // 分析部门规模
    if (dept.primary_member_count > 0) {
      console.log(`\n=== 部门规模分析 ===`);
      if (dept.primary_member_count < 10) {
        console.log("小型部门(<10人)");
      } else if (dept.primary_member_count < 50) {
        console.log("中型部门(10-50人)");
      } else {
        console.log("大型部门(>50人)");
      }
    }
    
    // 分析组织结构
    if (dept.parent_department_id === "0") {
      console.log("该部门为根部门(顶级部门)");
    } else {
      console.log(`该部门隶属于父部门: ${dept.parent_department_id}`);
    }
  }
}

analyzeDepartment("tech_dept_001");

函数名称:批量获取部门信息

函数签名

csharp
Task<FeishuApiResult<BatchGetDepartmentRequest>?> GetDepartmentsByIdsAsync(
    [Query("department_ids")] string[] department_ids,
    [Query("user_id_type")] string? user_id_type = "open_id",
    [Query("department_id_type")] string? department_id_type = "open_department_id",
    CancellationToken cancellationToken = default);

认证:用户令牌

参数

参数名类型必填说明
department_idsstring[]✅ 必填部门ID数组
user_id_typestring⚪ 可选用户ID类型,默认为"open_id"
department_id_typestring⚪ 可选部门ID类型,默认为"open_department_id"

响应

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "departments": [
      {
        "department_id": "od-1234567890",
        "name": "技术部",
        "parent_department_id": "0",
        "primary_member_count": 25
      },
      {
        "department_id": "od-1234567891",
        "name": "产品部",
        "parent_department_id": "0",
        "primary_member_count": 15
      }
    ]
  }
}

说明

  • 批量获取多个部门的详细信息
  • 使用用户令牌只能获取有权限查看的部门
  • 最多支持50个部门ID
  • 无权限的部门将不会在结果中返回

代码示例

javascript
// 批量获取部门信息
async function getBatchDepartmentInfo(departmentIds) {
  if (!departmentIds || departmentIds.length === 0) {
    console.log("部门ID列表不能为空");
    return [];
  }

  const maxBatchSize = 50;
  const allDepartments = [];
  
  for (let i = 0; i < departmentIds.length; i += maxBatchSize) {
    const batch = departmentIds.slice(i, i + maxBatchSize);
    
    const result = await feishuUserV3Departments.getDepartmentsByIdsAsync(
      batch,
      "open_id",
      "open_department_id"
    );

    if (result.code === 0) {
      allDepartments.push(...result.data.departments);
      console.log(`批次 ${Math.floor(i / maxBatchSize) + 1}: 获取到 ${result.data.departments.length} 个部门`);
    } else {
      console.error(`批次查询失败:`, result.msg);
      if (result.code === 403) {
        console.log("部分部门权限不足,已过滤");
      }
    }
  }

  return allDepartments;
}

// 分析部门成员分布和权限情况
async function analyzeAccessibleDepartments(departmentIds) {
  console.log(`准备批量获取 ${departmentIds.length} 个部门信息...`);
  
  const departments = await getBatchDepartmentInfo(departmentIds);
  
  if (departments.length === 0) {
    console.log("未获取到任何有权限的部门信息");
    return;
  }

  const accessibleCount = departments.length;
  const totalCount = departmentIds.length;
  const accessRate = ((accessibleCount / totalCount) * 100).toFixed(1);
  
  console.log(`\n=== 部门访问权限分析 ===`);
  console.log(`总查询部门数: ${totalCount}`);
  console.log(`有权限访问: ${accessibleCount}`);
  console.log(`无权限访问: ${totalCount - accessibleCount}`);
  console.log(`访问权限比例: ${accessRate}%`);

  // 分析部门成员分布
  const totalMembers = departments.reduce((sum, dept) => sum + (dept.primary_member_count || 0), 0);
  const avgMembers = Math.round(totalMembers / departments.length);
  
  console.log(`\n=== 成员分布统计 ===`);
  console.log(`总成员数: ${totalMembers}`);
  console.log(`平均部门人数: ${avgMembers}`);
  
  // 按成员数量排序并显示
  departments.sort((a, b) => (b.primary_member_count || 0) - (a.primary_member_count || 0));
  
  console.log(`\n=== 部门详情(按人数排序) ===`);
  departments.forEach((dept, index) => {
    const memberCount = dept.primary_member_count || 0;
    const percentage = totalMembers > 0 ? ((memberCount / totalMembers) * 100).toFixed(1) : '0.0';
    const parentInfo = dept.parent_department_id === "0" ? "根部门" : `父部门: ${dept.parent_department_id}`;
    
    console.log(`${index + 1}. ${dept.name}`);
    console.log(`   人数: ${memberCount} (${percentage}%)`);
    console.log(`   ${parentInfo}`);
    console.log(`   ID: ${dept.department_id}`);
  });
  
  return departments;
}

// 使用示例:分析当前用户可访问的部门
analyzeAccessibleDepartments([
  "tech_dept_001", 
  "product_dept_001", 
  "sales_dept_001",
  "hr_dept_001",
  "finance_dept_001"
]);

函数名称:获取子部门列表

函数签名

csharp
Task<FeishuApiPageListResult<GetDepartmentInfo>?> GetDepartmentsByParentIdAsync(
    [Path] string department_id,
    [Query("fetch_child")] bool fetch_child = false,
    [Query("page_size")] int? page_size = 10,
    [Query("page_token")] string? page_token = null,
    [Query("user_id_type")] string? user_id_type = "open_id",
    [Query("department_id_type")] string? department_id_type = "open_department_id",
    CancellationToken cancellationToken = default);

认证:用户令牌

参数

参数名类型必填说明
department_idstring✅ 必填父部门ID
fetch_childbool⚪ 可选是否递归获取子部门,默认false
page_sizeint?⚪ 可选分页大小,默认10,最大50
page_tokenstring⚪ 可选分页标记,首次请求不填
user_id_typestring⚪ 可选用户ID类型,默认为"open_id"
department_id_typestring⚪ 可选部门ID类型,默认为"open_department_id"

响应

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "department_id": "od-1234567891",
        "name": "前端团队",
        "parent_department_id": "od-1234567890",
        "primary_member_count": 8,
        "leader_user_id": "ou_1234567891"
      }
    ],
    "page_token": "next_page_token",
    "has_more": true
  }
}

说明

  • 查询指定部门下的子部门列表
  • 使用用户令牌只能获取有权限查看的子部门
  • 支持递归查询获取所有层级的子部门
  • 支持分页查询,适合获取大量子部门

代码示例

javascript
// 获取部门的所有子部门(支持分页和递归)
async function getAllSubDepartments(parentDepartmentId, includeRecursive = false, maxDepth = 3) {
  let hasMore = true;
  let pageToken = null;
  const allDepartments = [];
  let pageCount = 0;

  while (hasMore) {
    pageCount++;
    console.log(`正在获取第 ${pageCount} 页子部门数据...`);
    
    const result = await feishuUserV3Departments.getDepartmentsByParentIdAsync(
      parentDepartmentId,
      false, // 手动控制递归
      50, // 每页获取更多数据
      pageToken,
      "open_id",
      "open_department_id"
    );

    if (result.code === 0) {
      const departments = result.data.items;
      allDepartments.push(...departments);
      hasMore = result.data.has_more;
      pageToken = result.data.page_token;
      
      console.log(`第 ${pageCount} 页获取到 ${departments.length} 个子部门`);
      
      // 如果需要递归且当前层级的子部门数量较少,获取下一级
      if (includeRecursive && pageCount === 1 && departments.length < 10) {
        for (const dept of departments) {
          const subDepts = await getAllSubDepartments(dept.department_id, true, maxDepth - 1);
          if (subDepts.length > 0) {
            dept.sub_departments = subDepts;
          }
        }
      }
    } else {
      console.error(`第 ${pageCount} 页获取失败:`, result.msg);
      
      if (result.code === 403) {
        console.log("权限不足,无法查看该部门的子部门");
      }
      break;
    }
  }

  return allDepartments;
}

// 构建部门层级树
function buildDepartmentTree(departments, parentDepartmentId) {
  const tree = [];
  const children = departments.filter(dept => dept.parent_department_id === parentDepartmentId);
  
  for (const child of children) {
    const childNode = { ...child };
    childNode.children = buildDepartmentTree(departments, child.department_id);
    tree.push(childNode);
  }
  
  return tree;
}

// 显示部门树结构
function printDepartmentTree(nodes, indent = 0) {
  const prefix = "  ".repeat(indent);
  
  nodes.forEach((node, index) => {
    const isLast = index === nodes.length - 1;
    const memberCount = node.primary_member_count || 0;
    const leaderInfo = node.leader_user_id ? ` (主管: ${node.leader_user_id})` : "";
    const connector = isLast ? "└─" : "├─";
    
    console.log(`${prefix}${connector} ${node.name} (${memberCount}人)${leaderInfo}`);
    
    if (node.children && node.children.length > 0) {
      printDepartmentTree(node.children, indent + 1);
    }
  });
}

// 分析部门层级结构
async function analyzeDepartmentStructure(parentDepartmentId) {
  console.log(`正在分析部门 ${parentDepartmentId} 的层级结构...`);
  
  // 获取所有相关部门
  const departments = await getAllSubDepartments(parentDepartmentId, true);
  
  if (departments.length === 0) {
    console.log("该部门下没有子部门或没有权限查看");
    return;
  }

  console.log(`\n=== 层级结构分析 ===`);
  console.log(`直接子部门数: ${departments.length}`);
  
  // 构建树结构
  const tree = buildDepartmentTree(departments, parentDepartmentId);
  
  console.log(`\n=== 部门树结构 ===`);
  printDepartmentTree(tree);
  
  // 统计信息
  const totalMembers = departments.reduce((sum, dept) => sum + (dept.primary_member_count || 0), 0);
  const avgMembers = Math.round(totalMembers / departments.length);
  
  console.log(`\n=== 统计信息 ===`);
  console.log(`子部门总数: ${departments.length}`);
  console.log(`子部门总人数: ${totalMembers}`);
  console.log(`平均每个子部门人数: ${avgMembers}`);
  
  // 找出最大和最小的子部门
  const sortedBySize = [...departments].sort((a, b) => (b.primary_member_count || 0) - (a.primary_member_count || 0));
  const largestDept = sortedBySize[0];
  const smallestDept = sortedBySize[sortedBySize.length - 1];
  
  if (largestDept && smallestDept) {
    console.log(`最大子部门: ${largestDept.name} (${largestDept.primary_member_count || 0}人)`);
    console.log(`最小子部门: ${smallestDept.name} (${smallestDept.primary_member_count || 0}人)`);
  }
}

// 使用示例:分析技术部门的组织结构
analyzeDepartmentStructure("tech_dept_001");

函数名称:获取父部门信息

函数签名

csharp
Task<FeishuApiPageListResult<GetDepartmentInfo>?> GetParentDepartmentsByIdAsync(
    [Query("department_id")] string department_id,
    [Query("page_size")] int? page_size = 10,
    [Query("page_token")] string? page_token = null,
    [Query("user_id_type")] string? user_id_type = "open_id",
    [Query("department_id_type")] string? department_id_type = "open_department_id",
    CancellationToken cancellationToken = default);

认证:用户令牌

参数

参数名类型必填说明
department_idstring✅ 必填部门ID
page_sizeint?⚪ 可选分页大小,默认10,最大50
page_tokenstring⚪ 可选分页标记,首次请求不填
user_id_typestring⚪ 可选用户ID类型,默认为"open_id"
department_id_typestring⚪ 可选部门ID类型,默认为"open_department_id"

响应

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "department_id": "od-1234567890",
        "name": "技术部",
        "parent_department_id": "0"
      },
      {
        "department_id": "od-1234567891",
        "name": "总公司",
        "parent_department_id": "0"
      }
    ],
    "page_token": "next_page_token",
    "has_more": false
  }
}

说明

  • 递归获取指定部门的父部门信息
  • 从直接父部门一直追溯到根部门
  • 使用用户令牌只能获取有权限查看的父部门信息
  • 返回结果按层级顺序排列,可能有权限限制的父部门不会显示

代码示例

javascript
// 获取部门完整路径(考虑权限限制)
async function getDepartmentPath(departmentId) {
  const result = await feishuUserV3Departments.getParentDepartmentsByIdAsync(
    departmentId,
    50, // 获取更多父部门
    null,
    "open_id",
    "open_department_id"
  );

  if (result.code !== 0) {
    console.error("获取部门路径失败:", result.msg);
    
    if (result.code === 403) {
      console.log("权限不足,无法查看该部门的上层组织结构");
    }
    return null;
  }

  // 获取当前部门信息
  const currentDeptResult = await feishuUserV3Departments.getDepartmentInfoByIdAsync(
    departmentId,
    "open_id",
    "open_department_id"
  );

  const parentDepartments = result.data.items || [];
  const currentDepartment = currentDeptResult.code === 0 ? currentDeptResult.data.department : null;
  
  // 构建完整路径
  const fullPath = [...parentDepartments.reverse(), currentDepartment]
    .filter(dept => dept) // 过滤空值
    .map(dept => ({
      id: dept.department_id,
      name: dept.name,
      memberCount: dept.primary_member_count || 0,
      hasAccess: true // 能够获取到的都是有权限的
    }));

  return fullPath;
}

// 显示部门路径和权限分析
async function displayDepartmentPathWithAnalysis(departmentId) {
  console.log(`正在获取部门 ${departmentId} 的完整路径...`);
  
  const path = await getDepartmentPath(departmentId);
  
  if (!path || path.length === 0) {
    console.log("未找到部门路径信息,可能没有访问权限");
    return;
  }

  console.log("\n=== 部门完整路径 ===");
  path.forEach((dept, index) => {
    const arrow = index === path.length - 1 ? "" : " → ";
    const memberInfo = dept.memberCount > 0 ? ` (${dept.memberCount}人)` : "";
    console.log(`${dept.name}${memberInfo}${arrow}`);
  });
  
  console.log(`\n路径分析:`);
  console.log(`- 路径层级: ${path.length} 层`);
  console.log(`- 权限状态: 完全可访问`);
  console.log(`- 是否为根部门: ${path.length === 1 ? '是' : '否'}`);
  
  // 分析组织深度
  if (path.length >= 5) {
    console.log(`- 组织深度: 深层级组织 (${path.length}层)`);
  } else if (path.length >= 3) {
    console.log(`- 组织深度: 中等层级 (${path.length}层)`);
  } else {
    console.log(`- 组织深度: 扁平化组织 (${path.length}层)`);
  }
  
  return path;
}

// 比较多个部门的组织层级
async function compareDepartmentHierarchy(departmentIds) {
  console.log("=== 部门层级对比分析 ===");
  
  const comparisonResults = [];
  
  for (const deptId of departmentIds) {
    const path = await getDepartmentPath(deptId);
    
    if (path) {
      comparisonResults.push({
        id: deptId,
        name: path[path.length - 1].name,
        level: path.length,
        totalMembers: path.reduce((sum, dept) => sum + dept.memberCount, 0)
      });
    }
  }
  
  // 按层级排序
  comparisonResults.sort((a, b) => b.level - a.level);
  
  console.log("\n=== 层级排名 ===");
  comparisonResults.forEach((result, index) => {
    console.log(`${index + 1}. ${result.name}: 第${result.level}层 (${result.totalMembers}总人数)`);
  });
  
  // 统计分析
  const avgLevel = Math.round(comparisonResults.reduce((sum, r) => sum + r.level, 0) / comparisonResults.length);
  const deepest = Math.max(...comparisonResults.map(r => r.level));
  const shallowest = Math.min(...comparisonResults.map(r => r.level));
  
  console.log(`\n=== 统计信息 ===`);
  console.log(`平均层级: ${avgLevel}`);
  console.log(`最深层级: ${deepest}`);
  console.log(`最浅层级: ${shallowest}`);
  console.log(`层级差异: ${deepest - shallowest}`);
}

// 使用示例
async function analyzeDepartmentHierarchyExamples() {
  // 显示单个部门的完整路径
  await displayDepartmentPathWithAnalysis("tech_frontend_dept_001");
  
  // 比较多个部门的层级
  await compareDepartmentHierarchy([
    "tech_frontend_dept_001",
    "product_design_dept_001", 
    "sales_beijing_dept_001",
    "hr_recruit_dept_001"
  ]);
}

analyzeDepartmentHierarchyExamples();