接口名称
职位序列管理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);认证:租户令牌
参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| familyCreateRequest | JobFamilyCreateUpdateRequest | ✅ 必填 | 职位序列创建请求体 |
响应:
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_id | string | ✅ 必填 | 职位序列ID |
| familyCreateRequest | JobFamilyCreateUpdateRequest | ✅ 必填 | 职位序列更新请求体 |
响应:
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_id | string | ✅ 必填 | 职位序列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);认证:租户令牌
参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | ✅ 必填 | 序列名称,用于过滤查询 |
| page_size | int? | ⚪ 可选 | 分页大小,默认10,最大50 |
| page_token | string | ⚪ 可选 | 分页标记,首次请求不填 |
响应:
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_id | string | ✅ 必填 | 职位序列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();