Skip to content

接口名称

职位序列管理API(租户令牌)- IFeishuTenantV3JobFamilies

功能描述

序列是用户属性之一,用来为不同的用户定义不同的工作类型,例如产品、研发、测试、运营。当前接口使用租户令牌访问,适用于租户应用场景。可以根据企业实际需要添加序列,后续在创建或更新用户时,为用户设置相匹配的序列。通过序列API,可以创建、更新、查询、删除序列信息。

参考文档

https://open.feishu.cn/document/contact-v3/job_family/job-family-resource-introduction

函数列表

函数名称功能描述认证方式HTTP 方法
CreateJobFamilyAsync创建职位序列租户令牌POST
UpdateJobFamilyAsync更新职位序列信息租户令牌PUT
GetJobFamilyByIdAsync获取指定职位序列信息租户令牌GET
GetJobFamilesListAsync获取职位序列列表租户令牌GET
DeleteJobFamilyByIdAsync删除指定职位序列租户令牌DELETE

函数详细内容

函数名称:创建职位序列

函数签名

csharp
Task<FeishuApiResult<JobFamilyResult>?> CreateJobFamilyAsync(
    [Body] JobFamilyCreateUpdateRequest familyCreateRequest,
    CancellationToken cancellationToken = default);

认证:租户令牌

参数

参数名类型必填说明
familyCreateRequestJobFamilyCreateUpdateRequest✅ 必填职位序列创建请求体

响应

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "job_family": {
      "job_family_id": "jf_1234567890",
      "name": "研发序列",
      "description": "负责产品研发和技术实现的职位序列",
      "parent_job_family_id": null,
      "status": true,
      "i18n_name": [
        {
          "locale": "zh_cn",
          "text": "研发序列"
        },
        {
          "locale": "en_us", 
          "text": "R&D Sequence"
        }
      ],
      "i18n_description": [
        {
          "locale": "zh_cn",
          "text": "负责产品研发和技术实现的职位序列"
        }
      ]
    }
  }
}

说明

  • 创建一个新的职位序列,用于分类不同工作类型的用户
  • 序列名称在租户内必须唯一
  • 支持创建父子序列结构,实现序列的层级化管理
  • 支持多语言配置,适应国际化需求
  • 序列创建后可应用于用户管理中

代码示例

javascript
// 创建研发序列
const createFamilyRequest = {
  name: "研发序列",
  description: "负责产品研发和技术实现的职位序列,包括前端、后端、测试等方向",
  status: true, // 启用序列
  i18n_name: [
    {
      locale: "zh_cn",
      text: "研发序列"
    },
    {
      locale: "en_us",
      text: "R&D Sequence"
    }
  ],
  i18n_description: [
    {
      locale: "zh_cn",
      text: "负责产品研发和技术实现的职位序列"
    },
    {
      locale: "en_us",
      text: "Position sequence responsible for product R&D and technical implementation"
    }
  ]
};

const result = await feishuTenantV3JobFamilies.createJobFamilyAsync(createFamilyRequest);

if (result.code === 0) {
  const jobFamily = result.data.job_family;
  console.log("职位序列创建成功:");
  console.log(`- 序列ID: ${jobFamily.job_family_id}`);
  console.log(`- 序列名称: ${jobFamily.name}`);
  console.log(`- 描述: ${jobFamily.description}`);
  console.log(`- 状态: ${jobFamily.status ? '启用' : '禁用'}`);
  
  // 显示多语言配置
  if (jobFamily.i18n_name && jobFamily.i18n_name.length > 0) {
    console.log("\n多语言名称:");
    jobFamily.i18n_name.forEach(item => {
      console.log(`  ${item.locale}: ${item.text}`);
    });
  }
} else {
  console.error("创建职位序列失败:", result.msg);
  
  // 错误处理
  switch (result.code) {
    case 400:
      console.log("请求参数错误,可能序列名称重复或格式不正确");
      break;
    case 403:
      console.log("权限不足,无法创建职位序列");
      break;
    default:
      console.log("创建失败,请稍后重试");
  }
}

函数名称:更新职位序列信息

函数签名

csharp
Task<FeishuApiResult<JobFamilyResult>?> UpdateJobFamilyAsync(
    [Path] string job_family_id,
    [Body] JobFamilyCreateUpdateRequest familyCreateRequest,
    CancellationToken cancellationToken = default);

认证:租户令牌

参数

参数名类型必填说明
job_family_idstring✅ 必填职位序列ID
familyCreateRequestJobFamilyCreateUpdateRequest✅ 必填职位序列更新请求体

响应

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "job_family": {
      "job_family_id": "jf_1234567890",
      "name": "技术研发序列",
      "description": "负责产品研发、技术实现和技术管理的综合职位序列",
      "parent_job_family_id": "jf_1234567891",
      "status": true,
      "i18n_name": [
        {
          "locale": "zh_cn",
          "text": "技术研发序列"
        }
      ]
    }
  }
}

说明

  • 更新指定序列的完整信息,需要提供所有必要的字段
  • 可用于修改序列名称、描述、父序列关系等
  • 更新后需要重新应用于相关用户
  • 支持调整序列的层级关系

代码示例

javascript
// 更新职位序列,将其设为另一个序列的子序列
const updateFamilyRequest = {
  name: "前端开发序列",
  description: "专注于前端界面开发和用户体验优化的职位序列",
  parent_job_family_id: "jf_1234567890", // 设为研发序列的子序列
  status: true,
  i18n_name: [
    {
      locale: "zh_cn",
      text: "前端开发序列"
    },
    {
      locale: "en_us",
      text: "Frontend Development Sequence"
    }
  ],
  i18n_description: [
    {
      locale: "zh_cn",
      text: "专注于前端界面开发和用户体验优化的职位序列"
    },
    {
      locale: "en_us",
      text: "Position sequence focusing on frontend interface development and UX optimization"
    }
  ]
};

const result = await feishuTenantV3JobFamilies.updateJobFamilyAsync(
  "jf_1234567892", // 要更新的序列ID
  updateFamilyRequest
);

if (result.code === 0) {
  const jobFamily = result.data.job_family;
  console.log("职位序列更新成功:");
  console.log(`- 序列ID: ${jobFamily.job_family_id}`);
  console.log(`- 新名称: ${jobFamily.name}`);
  console.log(`- 父序列: ${jobFamily.parent_job_family_id || '无'}`);
  console.log(`- 状态: ${jobFamily.status ? '启用' : '禁用'}`);
  
  // 验证更新结果
  if (jobFamily.parent_job_family_id) {
    console.log(`序列已成功设置父序列: ${jobFamily.parent_job_family_id}`);
  }
} else {
  console.error("更新职位序列失败:", result.msg);
  
  if (result.code === 404) {
    console.log("序列不存在或已被删除");
  } else if (result.code === 400) {
    console.log("参数错误,可能是父序列不存在或形成了循环引用");
  }
}

函数名称:获取指定职位序列信息

函数签名

csharp
Task<FeishuApiResult<JobFamilyResult>?> GetJobFamilyByIdAsync(
    [Path] string job_family_id,
    CancellationToken cancellationToken = default);

认证:租户令牌

参数

参数名类型必填说明
job_family_idstring✅ 必填职位序列ID

响应

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "job_family": {
      "job_family_id": "jf_1234567890",
      "name": "研发序列",
      "description": "负责产品研发和技术实现的职位序列",
      "parent_job_family_id": null,
      "status": true,
      "i18n_name": [
        {
          "locale": "zh_cn",
          "text": "研发序列"
        }
      ],
      "i18n_description": [
        {
          "locale": "zh_cn",
          "text": "负责产品研发和技术实现的职位序列"
        }
      ]
    }
  }
}

说明

  • 获取指定序列的详细信息
  • 返回序列的完整属性信息
  • 包含多语言配置和层级关系信息
  • 可用于验证序列状态和属性

代码示例

javascript
// 获取并分析职位序列详细信息
async function analyzeJobFamily(jobFamilyId) {
  console.log(`正在获取职位序列 ${jobFamilyId} 的详细信息...`);
  
  const result = await feishuTenantV3JobFamilies.getJobFamilyByIdAsync(jobFamilyId);
  
  if (result.code === 0) {
    const jobFamily = result.data.job_family;
    
    console.log("\n=== 职位序列详细信息 ===");
    console.log(`序列ID: ${jobFamily.job_family_id}`);
    console.log(`序列名称: ${jobFamily.name}`);
    console.log(`描述: ${jobFamily.description || '无描述'}`);
    console.log(`状态: ${jobFamily.status ? '启用' : '禁用'}`);
    console.log(`父序列: ${jobFamily.parent_job_family_id || '无(根序列)'}`);
    
    // 显示多语言配置
    if (jobFamily.i18n_name && jobFamily.i18n_name.length > 0) {
      console.log("\n多语言名称:");
      jobFamily.i18n_name.forEach(item => {
        console.log(`  ${item.locale}: ${item.text}`);
      });
    }
    
    if (jobFamily.i18n_description && jobFamily.i18n_description.length > 0) {
      console.log("\n多语言描述:");
      jobFamily.i18n_description.forEach(item => {
        console.log(`  ${item.locale}: ${item.text}`);
      });
    }
    
    // 分析序列层级
    console.log("\n=== 层级分析 ===");
    if (jobFamily.parent_job_family_id) {
      console.log("这是一个子序列");
      console.log(`父序列ID: ${jobFamily.parent_job_family_id}`);
      
      // 获取父序列信息
      const parentResult = await feishuTenantV3JobFamilies.getJobFamilyByIdAsync(jobFamily.parent_job_family_id);
      if (parentResult.code === 0) {
        console.log(`父序列名称: ${parentResult.data.job_family.name}`);
      }
    } else {
      console.log("这是一个根序列");
    }
    
    return jobFamily;
  } else {
    console.error("获取职位序列信息失败:", result.msg);
    
    if (result.code === 404) {
      console.log("序列不存在或已被删除");
    }
    
    return null;
  }
}

// 使用示例
analyzeJobFamily("jf_1234567890");

函数名称:获取职位序列列表

函数签名

csharp
Task<FeishuApiPageListResult<JobFamilyInfo>?> GetJobFamilesListAsync(
    [Query("name")] string name,
    [Query("page_size")] int? page_size = 10,
    [Query("page_token")] string? page_token = null,
    CancellationToken cancellationToken = default);

认证:租户令牌

参数

参数名类型必填说明
namestring✅ 必填序列名称,用于过滤查询
page_sizeint?⚪ 可选分页大小,默认10,最大50
page_tokenstring⚪ 可选分页标记,首次请求不填

响应

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "items": [
      {
        "job_family_id": "jf_1234567890",
        "name": "研发序列",
        "description": "负责产品研发和技术实现的职位序列",
        "parent_job_family_id": null,
        "status": true
      },
      {
        "job_family_id": "jf_1234567891",
        "name": "产品序列", 
        "description": "负责产品规划和管理",
        "parent_job_family_id": null,
        "status": true
      }
    ],
    "page_token": "next_page_token",
    "has_more": true
  }
}

说明

  • 获取当前租户下的职位序列列表
  • 支持按名称进行过滤查询
  • 支持分页查询,适合获取大量序列
  • 返回序列的基本信息,不包含多语言配置

代码示例

javascript
// 获取所有职位序列
async function getAllJobFamilies(filterName = "") {
  let hasMore = true;
  let pageToken = null;
  const allFamilies = [];
  let pageCount = 0;

  while (hasMore) {
    pageCount++;
    console.log(`正在获取第 ${pageCount} 页职位序列数据...`);
    
    const result = await feishuTenantV3JobFamilies.getJobFamilesListAsync(
      filterName,
      50, // 每页获取更多数据
      pageToken
    );

    if (result.code === 0) {
      const families = result.data.items;
      allFamilies.push(...families);
      hasMore = result.data.has_more;
      pageToken = result.data.page_token;
      
      console.log(`第 ${pageCount} 页获取到 ${families.length} 个序列`);
    } else {
      console.error(`第 ${pageCount} 页获取失败:`, result.msg);
      break;
    }
  }

  return allFamilies;
}

// 分析职位序列结构
async function analyzeJobFamilyStructure() {
  console.log("正在分析职位序列结构...");
  
  const families = await getAllJobFamilies();
  
  if (families.length === 0) {
    console.log("未找到任何职位序列");
    return;
  }

  console.log(`\n=== 职位序列概览 ===`);
  console.log(`总序列数: ${families.length}`);
  
  // 按状态分类统计
  const enabledFamilies = families.filter(f => f.status);
  const disabledFamilies = families.filter(f => !f.status);
  
  console.log(`启用序列: ${enabledFamilies.length}`);
  console.log(`禁用序列: ${disabledFamilies.length}`);
  
  // 按层级分类统计
  const rootFamilies = families.filter(f => !f.parent_job_family_id);
  const childFamilies = families.filter(f => f.parent_job_family_id);
  
  console.log(`根序列: ${rootFamilies.length}`);
  console.log(`子序列: ${childFamilies.length}`);
  
  // 显示所有序列
  console.log(`\n=== 序列列表 ===`);
  
  // 先显示根序列
  console.log("\n根序列:");
  rootFamilies.forEach(family => {
    const status = family.status ? '启用' : '禁用';
    const children = childFamilies.filter(child => child.parent_job_family_id === family.job_family_id);
    console.log(`├─ ${family.name} (${family.job_family_id}) [${status}]`);
    console.log(`   描述: ${family.description || '无描述'}`);
    
    // 显示子序列
    if (children.length > 0) {
      children.forEach(child => {
        const childStatus = child.status ? '启用' : '禁用';
        console.log(`│  └─ ${child.name} (${child.job_family_id}) [${childStatus}]`);
      });
    }
  });
  
  // 显示无父序列的孤儿序列(如果有)
  const orphanChildren = childFamilies.filter(child => 
    !rootFamilies.some(root => root.job_family_id === child.parent_job_family_id)
  );
  
  if (orphanChildren.length > 0) {
    console.log("\n孤儿子序列(父序列不存在):");
    orphanChildren.forEach(child => {
      const status = child.status ? '启用' : '禁用';
      console.log(`├─ ${child.name} (${child.job_family_id}) [${status}]`);
      console.log(`│  缺失父序列: ${child.parent_job_family_id}`);
    });
  }
  
  return families;
}

// 搜索特定名称的序列
async function searchJobFamilies(keyword) {
  console.log(`正在搜索名称包含 "${keyword}" 的职位序列...`);
  
  const families = await getAllJobFamilies(keyword);
  
  if (families.length === 0) {
    console.log(`未找到名称包含 "${keyword}" 的职位序列`);
    return [];
  }
  
  console.log(`\n找到 ${families.length} 个匹配的职位序列:`);
  families.forEach((family, index) => {
    const status = family.status ? '启用' : '禁用';
    const parentInfo = family.parent_job_family_id ? ` (父: ${family.parent_job_family_id})` : ' (根序列)';
    
    console.log(`${index + 1}. ${family.name}${parentInfo} [${status}]`);
    console.log(`   ID: ${family.job_family_id}`);
    console.log(`   描述: ${family.description || '无描述'}`);
  });
  
  return families;
}

// 使用示例
analyzeJobFamilyStructure();
searchJobFamilies("研发");

函数名称:删除指定职位序列

函数签名

csharp
Task<FeishuNullDataApiResult?> DeleteJobFamilyByIdAsync(
    [Path] string job_family_id,
    CancellationToken cancellationToken = default);

认证:租户令牌

参数

参数名类型必填说明
job_family_idstring✅ 必填职位序列ID

响应

json
{
  "code": 0,
  "msg": "success"
}

说明

  • 删除指定的职位序列
  • 仅支持删除没有子序列的序列
  • 如果序列内存在子序列,则不能直接删除
  • 删除操作不可恢复,请谨慎操作
  • 删除前请确保没有用户正在使用该序列

代码示例

javascript
// 安全删除序列(包含前置检查)
async function safeDeleteJobFamily(jobFamilyId) {
  console.log(`准备删除职位序列 ${jobFamilyId}...`);
  
  // 第一步:获取序列信息
  const familyResult = await feishuTenantV3JobFamilies.getJobFamilyByIdAsync(jobFamilyId);
  
  if (familyResult.code !== 0) {
    console.error("无法获取序列信息:", familyResult.msg);
    return false;
  }
  
  const family = familyResult.data.job_family;
  console.log(`序列名称: ${family.name}`);
  
  // 第二步:检查是否有子序列
  console.log("检查是否有子序列...");
  const allFamilies = await getAllJobFamilies(); // 获取所有序列
  const childFamilies = allFamilies.filter(f => f.parent_job_family_id === jobFamilyId);
  
  if (childFamilies.length > 0) {
    console.log("删除失败:该序列下还有子序列,无法直接删除");
    console.log("子序列列表:");
    childFamilies.forEach(child => {
      console.log(`  - ${child.name} (${child.job_family_id})`);
    });
    console.log("请先删除或转移所有子序列后再尝试删除此序列");
    return false;
  }
  
  // 第三步:确认删除
  console.log("确认信息:");
  console.log(`- 序列名称: ${family.name}`);
  console.log(`- 序列ID: ${family.job_family_id}`);
  console.log(`- 序列状态: ${family.status ? '启用' : '禁用'}`);
  console.log(`- 无子序列: ✓`);
  
  // 第四步:执行删除
  console.log("正在执行删除操作...");
  
  const deleteResult = await feishuTenantV3JobFamilies.deleteJobFamilyByIdAsync(jobFamilyId);
  
  if (deleteResult.code === 0) {
    console.log("✓ 职位序列删除成功");
    console.log(`已删除序列: ${family.name} (${jobFamilyId})`);
    
    // 验证删除结果
    const verifyResult = await feishuTenantV3JobFamilies.getJobFamilyByIdAsync(jobFamilyId);
    if (verifyResult.code === 404) {
      console.log("✓ 验证成功:序列已不存在");
    } else {
      console.log("⚠ 警告:删除成功但验证异常");
    }
    
    return true;
  } else {
    console.error("删除职位序列失败:", deleteResult.msg);
    
    // 错误处理
    switch (deleteResult.code) {
      case 400:
        console.log("请求参数错误,可能是序列ID不正确");
        break;
      case 403:
        console.log("权限不足,无法删除序列");
        break;
      case 404:
        console.log("序列不存在或已被删除");
        break;
      case 409:
        console.log("序列正在被使用或有依赖关系,无法删除");
        break;
      default:
        console.log("未知错误,请稍后重试");
    }
    
    return false;
  }
}

// 批量删除无用的子序列
async function cleanupUnusedChildFamilies() {
  console.log("开始清理无用的子序列...");
  
  const allFamilies = await getAllJobFamilies();
  
  // 找出所有子序列
  const childFamilies = allFamilies.filter(f => f.parent_job_family_id);
  const rootFamilies = allFamilies.filter(f => !f.parent_job_family_id);
  
  if (childFamilies.length === 0) {
    console.log("没有找到子序列");
    return;
  }
  
  console.log(`找到 ${childFamilies.length} 个子序列`);
  
  // 找出孤儿子序列(父序列不存在的)
  const orphanChildren = childFamilies.filter(child => 
    !rootFamilies.some(root => root.job_family_id === child.parent_job_family_id)
  );
  
  if (orphanChildren.length > 0) {
    console.log(`\n发现 ${orphanChildren.length} 个孤儿子序列(父序列不存在):`);
    orphanChildren.forEach(child => {
      console.log(`- ${child.name} (${child.job_family_id}) - 缺失父: ${child.parent_job_family_id}`);
    });
    
    // 询问是否删除孤儿子序列
    console.log("\n这些孤儿子序列可以安全删除");
    for (const orphan of orphanChildren) {
      console.log(`\n正在删除孤儿序列: ${orphan.name}`);
      await safeDeleteJobFamily(orphan.job_family_id);
    }
  } else {
    console.log("没有发现孤儿子序列");
  }
  
  console.log("\n清理完成");
}

// 使用示例
// safeDeleteJobFamily("jf_1234567892");
// cleanupUnusedChildFamilies();